From 7ffd40ea571cd358efc8c5e9665450fb05c7f5ff Mon Sep 17 00:00:00 2001 From: kunw Date: Wed, 26 Oct 2016 16:09:19 +0800 Subject: [PATCH 01/15] Updates for link of logs on dashboard. --- .../details/retrieve-projects.directive.js | 11 ++++++----- .../repository/list-repository.directive.js | 16 +++++++++++++--- .../components/user-log/user-log.directive.html | 2 +- .../js/components/user-log/user-log.directive.js | 6 +++--- .../js/services/i18n/locale_messages_en-US.js | 1 + .../js/services/i18n/locale_messages_zh-CN.js | 1 + src/ui/views/project.htm | 8 ++++---- 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/ui/static/resources/js/components/details/retrieve-projects.directive.js b/src/ui/static/resources/js/components/details/retrieve-projects.directive.js index 3533f2c42..4101898a6 100644 --- a/src/ui/static/resources/js/components/details/retrieve-projects.directive.js +++ b/src/ui/static/resources/js/components/details/retrieve-projects.directive.js @@ -88,7 +88,6 @@ function getProjectSuccess(response) { - var partialProjects = response.data || []; for(var i in partialProjects) { vm.projects.push(partialProjects[i]); @@ -114,11 +113,13 @@ } } - $location.search('project_id', vm.selectedProject.project_id); - vm.checkProjectMember(vm.selectedProject.project_id); - + if(vm.selectedProject) { + $location.search('project_id', vm.selectedProject.project_id); + vm.checkProjectMember(vm.selectedProject.project_id); + } + vm.resultCount = vm.projects.length; - + $scope.$watch('vm.filterInput', function(current, origin) { vm.resultCount = $filter('name')(vm.projects, vm.filterInput, 'name').length; }); diff --git a/src/ui/static/resources/js/components/repository/list-repository.directive.js b/src/ui/static/resources/js/components/repository/list-repository.directive.js index 0a5fd627b..38d4117fc 100644 --- a/src/ui/static/resources/js/components/repository/list-repository.directive.js +++ b/src/ui/static/resources/js/components/repository/list-repository.directive.js @@ -19,9 +19,9 @@ .module('harbor.repository') .directive('listRepository', listRepository); - ListRepositoryController.$inject = ['$scope', 'ListRepositoryService', 'DeleteRepositoryService', '$filter', 'trFilter', '$location', 'getParameterByName']; + ListRepositoryController.$inject = ['$scope', 'ListRepositoryService', 'DeleteRepositoryService', '$filter', 'trFilter', '$location', 'getParameterByName', '$window']; - function ListRepositoryController($scope, ListRepositoryService, DeleteRepositoryService, $filter, trFilter, $location, getParameterByName) { + function ListRepositoryController($scope, ListRepositoryService, DeleteRepositoryService, $filter, trFilter, $location, getParameterByName, $window) { $scope.subsTabPane = 30; @@ -104,7 +104,17 @@ } function getRepositoryFailed(response) { - console.log('Failed to list repositories:' + response); + $scope.$emit('modalTitle', $filter('tr')('error')); + $scope.$emit('modalMessage', $filter('tr')('project_does_not_exist')); + var emitInfo = { + 'confirmOnly': true, + 'contentType': 'text/html', + 'action' : function() { + $window.location.href = '/dashboard'; + } + }; + $scope.$emit('raiseInfo', emitInfo); + console.log('Failed to list repositories:' + response.data); } function searchRepo() { diff --git a/src/ui/static/resources/js/components/user-log/user-log.directive.html b/src/ui/static/resources/js/components/user-log/user-log.directive.html index 4fd762d5e..9764fc7af 100644 --- a/src/ui/static/resources/js/components/user-log/user-log.directive.html +++ b/src/ui/static/resources/js/components/user-log/user-log.directive.html @@ -32,7 +32,7 @@ //t.username// - //t.repo_name// + //t.repo_name// //t.repo_tag// //t.operation// //t.op_time | dateL : 'YYYY-MM-DD HH:mm:ss'// diff --git a/src/ui/static/resources/js/components/user-log/user-log.directive.js b/src/ui/static/resources/js/components/user-log/user-log.directive.js index ceb86a778..0a462c466 100644 --- a/src/ui/static/resources/js/components/user-log/user-log.directive.js +++ b/src/ui/static/resources/js/components/user-log/user-log.directive.js @@ -29,7 +29,7 @@ .success(listIntegratedLogSuccess) .error(listIntegratedLogFailed); - vm.gotoLog = gotoLog; + vm.gotoRepo = gotoRepo; function listIntegratedLogSuccess(data) { vm.integratedLogs = data || []; @@ -42,8 +42,8 @@ console.log('Failed to get user logs:' + data); } - function gotoLog(projectId, username) { - $window.location.href = '/repository#/logs?project_id=' + projectId + '#' + encodeURIComponent(username); + function gotoRepo(projectId, repoName) { + $window.location.href = '/repository#/repositories?project_id=' + projectId + '#' + encodeURIComponent(repoName); } } diff --git a/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js b/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js index 0ac5025c5..46635cf2f 100644 --- a/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js +++ b/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js @@ -263,6 +263,7 @@ var locale_messages = { 'failed_to_update_destination': 'Failed to update destination.', 'failed_to_toggle_publicity_insuffient_permissions': 'Failed to toggle project publicity, insuffient permissions.', 'failed_to_toggle_publicity': 'Failed to toggle project publicity.', + 'project_does_not_exist': 'Project does not exist.', 'project_admin': 'Project Admin', 'developer': 'Developer', 'guest': 'Guest', diff --git a/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js b/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js index a896ba848..07903b375 100644 --- a/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js +++ b/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js @@ -263,6 +263,7 @@ var locale_messages = { 'failed_to_update_destination': '修改目标失败。', 'failed_to_toggle_publicity_insuffient_permissions': '切换项目公开性失败,权限不足。', 'failed_to_toggle_publicity': '切换项目公开性失败。', + 'project_does_not_exist': '项目不存在。', 'project_admin': '项目管理员', 'developer': '开发人员', 'guest': '访客', diff --git a/src/ui/views/project.htm b/src/ui/views/project.htm index 4c0360068..7be0c4593 100644 --- a/src/ui/views/project.htm +++ b/src/ui/views/project.htm @@ -47,8 +47,8 @@ // 'repositories' | tr // // 'role' | tr // // 'creation_time' | tr // - // 'publicity' | tr // - // 'operation' | tr // + // 'publicity' | tr // + // 'operation' | tr // @@ -63,8 +63,8 @@ //p.repo_count// //vm.getProjectRole(p.current_user_role_id) | tr// //p.creation_time | dateL : 'YYYY-MM-DD HH:mm:ss'// - - + +    From 0689935da44d2458f191e69433ee693a8ea25ce5 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Wed, 26 Oct 2016 18:03:31 +0800 Subject: [PATCH 02/15] log rotate --- make/common/log/logrotate_docker.conf | 7 ------ make/common/log/rotate.sh | 26 ++++++++++++++++++++ make/photon/log/Dockerfile | 11 +++------ make/photon/log/logrotate.conf.photon | 35 --------------------------- make/ubuntu/log/Dockerfile | 11 ++++----- 5 files changed, 35 insertions(+), 55 deletions(-) delete mode 100644 make/common/log/logrotate_docker.conf create mode 100755 make/common/log/rotate.sh delete mode 100644 make/photon/log/logrotate.conf.photon diff --git a/make/common/log/logrotate_docker.conf b/make/common/log/logrotate_docker.conf deleted file mode 100644 index 6a953d4c3..000000000 --- a/make/common/log/logrotate_docker.conf +++ /dev/null @@ -1,7 +0,0 @@ -# Logrotate configuartion file for docker. - -/var/log/docker/*/*.log { - rotate 100 - size 10M - copytruncate -} diff --git a/make/common/log/rotate.sh b/make/common/log/rotate.sh new file mode 100755 index 000000000..3f96df9bc --- /dev/null +++ b/make/common/log/rotate.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -e +echo "Log rotate starting..." + +#The logs n days before will be compressed. +n=14 +path=/var/log/docker + +list="" +n_days_before=$(($(date +%s) - 3600*24*$n)) +for dir in $(ls $path | grep -v "tar.gz"); +do + if [ $(date --date=$dir +%s) -lt $n_days_before ] + then + echo "$dir will be compressed" + list="$list $dir" + fi +done + +if [ -n "$list" ] +then + cd $path + tar --remove-files -zcvf $(date -d @$n_days_before +%F)-.tar.gz $list +fi + +echo "Log rotate finished." diff --git a/make/photon/log/Dockerfile b/make/photon/log/Dockerfile index 8ae03e95c..ea0759427 100644 --- a/make/photon/log/Dockerfile +++ b/make/photon/log/Dockerfile @@ -1,8 +1,7 @@ FROM library/photon:latest # run logrotate hourly, disable imklog model, provides TCP/UDP syslog reception -RUN tdnf install -y cronie rsyslog logrotate shadow\ - && mv /etc/cron.daily/logrotate /etc/cron.hourly/ \ +RUN tdnf install -y cronie rsyslog shadow tar gzip \ && mkdir /etc/rsyslog.d/ \ && mkdir /var/spool/rsyslog \ && groupadd syslog \ @@ -10,15 +9,13 @@ RUN tdnf install -y cronie rsyslog logrotate shadow\ ADD make/common/log/rsyslog.conf /etc/rsyslog.conf -COPY make/photon/log/logrotate.conf.photon /etc/logrotate.conf - -# logrotate configuration file for docker -ADD make/common/log/logrotate_docker.conf /etc/logrotate.d/ +# rotate logs weekly +# notes: file name cannot contain dot, or the script will not run +ADD make/common/log/rotate.sh /etc/cron.weekly/rotate # rsyslog configuration file for docker ADD make/common/log/rsyslog_docker.conf /etc/rsyslog.d/ - VOLUME /var/log/docker/ EXPOSE 514 diff --git a/make/photon/log/logrotate.conf.photon b/make/photon/log/logrotate.conf.photon deleted file mode 100644 index c28d55b62..000000000 --- a/make/photon/log/logrotate.conf.photon +++ /dev/null @@ -1,35 +0,0 @@ -# see "man logrotate" for details -# rotate log files weekly -weekly - -# keep 4 weeks worth of backlogs -rotate 4 - -# create new (empty) log files after rotating old ones -create - -# use date as a suffix of the rotated file -dateext - -# uncomment this if you want your log files compressed -#compress - -# RPM packages drop log rotation information into this directory -include /etc/logrotate.d - -# no packages own wtmp and btmp -- we'll rotate them here -#/var/log/wtmp { -# monthly -# create 0664 root utmp -# minsize 1M -# rotate 1 -#} - -/var/log/btmp { - missingok - monthly - create 0600 root utmp - rotate 1 -} - -# system-specific logs may be also be configured here. diff --git a/make/ubuntu/log/Dockerfile b/make/ubuntu/log/Dockerfile index f91da3469..3e1c7520e 100644 --- a/make/ubuntu/log/Dockerfile +++ b/make/ubuntu/log/Dockerfile @@ -1,13 +1,12 @@ FROM library/ubuntu:14.04 -# run logrotate hourly, disable imklog model, provides TCP/UDP syslog reception -RUN mv /etc/cron.daily/logrotate /etc/cron.hourly/ \ - && rm /etc/rsyslog.d/* \ - && rm /etc/rsyslog.conf +RUN rm /etc/rsyslog.d/* && rm /etc/rsyslog.conf + ADD make/common/log/rsyslog.conf /etc/rsyslog.conf -# logrotate configuration file for docker -ADD make/common/log/logrotate_docker.conf /etc/logrotate.d/ +# rotate logs weekly +# notes: file name cannot contain dot, or the script will not run +ADD make/common/log/rotate.sh /etc/cron.weekly/rotate # rsyslog configuration file for docker ADD make/common/log/rsyslog_docker.conf /etc/rsyslog.d/ From 8af0bd6d3815cc0f0d25c1dcc7e062c3e8469317 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Tue, 25 Oct 2016 18:09:54 +0800 Subject: [PATCH 03/15] ova installation scripts --- .../ova/deps/docker-compose-1.7.1/install.sh | 7 ++ tools/ova/script/app_post_install.sh | 15 ++++ tools/ova/script/common.sh | 54 ++++++++++++ tools/ova/script/config.sh | 88 +++++++++++++++++++ tools/ova/script/firstboot.sh | 43 +++++++++ tools/ova/script/start_harbor.sh | 31 +++++++ tools/ova/script/subsequentboot.sh | 37 ++++++++ 7 files changed, 275 insertions(+) create mode 100755 tools/ova/deps/docker-compose-1.7.1/install.sh create mode 100755 tools/ova/script/app_post_install.sh create mode 100755 tools/ova/script/common.sh create mode 100755 tools/ova/script/config.sh create mode 100755 tools/ova/script/firstboot.sh create mode 100755 tools/ova/script/start_harbor.sh create mode 100755 tools/ova/script/subsequentboot.sh diff --git a/tools/ova/deps/docker-compose-1.7.1/install.sh b/tools/ova/deps/docker-compose-1.7.1/install.sh new file mode 100755 index 000000000..810b24630 --- /dev/null +++ b/tools/ova/deps/docker-compose-1.7.1/install.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +echo "docker-compose version 1.7.1" +cd "$( dirname "${BASH_SOURCE[0]}" )" +cp ./docker-compose-Linux-x86_64 /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose + diff --git a/tools/ova/script/app_post_install.sh b/tools/ova/script/app_post_install.sh new file mode 100755 index 000000000..aeda8239a --- /dev/null +++ b/tools/ova/script/app_post_install.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +tdnf install -y docker +systemctl enable docker.service + +mkdir -p /var/log/harbor + +echo "Downloading harbor..." +wget -O /ova.tar.gz http://10.117.5.62/ISV/appliancePackages/ova.tar.gz + +echo "Downloading notice file..." +wget -O /NOTICE_Harbor_0.4.1_Beta.txt http://10.117.5.62/ISV/appliancePackages/NOTICE_Harbor_0.4.1_Beta.txt + +echo "Downloading license file..." +wget -O /LICENSE_Harbor_0.4.1_Beta_100216.txt http://10.117.5.62/ISV/appliancePackages/LICENSE_Harbor_0.4.1_Beta_100216.txt \ No newline at end of file diff --git a/tools/ova/script/common.sh b/tools/ova/script/common.sh new file mode 100755 index 000000000..88b268a78 --- /dev/null +++ b/tools/ova/script/common.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +#Shut down Harbor +function down { + base_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + docker-compose -f $base_dir/../harbor/docker-compose*.yml down +} + +#Start Harbor +function up { + base_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + $base_dir/start_harbor.sh +} + +#Configure Harbor +function configure { + base_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + $base_dir/config.sh +} + +#Garbage collectoin +function gc { + echo "======================= $(date)=====================" + + #the registry image + image=$1 + + base_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + + docker run --name gc --rm --volume /data/registry:/storage \ + --volume $base_dir/../harbor/common/config/registry/:/etc/registry/ \ + $image garbage-collect /etc/registry/config.yml + + echo "====================================================" +} + +#Add rules to iptables +function addIptableRules { + iptables -A INPUT -p tcp --dport 5480 -j ACCEPT + iptables -A INPUT -p tcp --dport 5488 -j ACCEPT + iptables -A INPUT -p tcp --dport 5489 -j ACCEPT +} + +#Install docker-compose +function installDockerCompose { + base_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + $base_dir/../deps/docker-compose-1.7.1/install.sh +} + +#Load images +function load { + basedir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + docker load -i $basedir/../harbor/harbor*.tgz +} \ No newline at end of file diff --git a/tools/ova/script/config.sh b/tools/ova/script/config.sh new file mode 100755 index 000000000..43a238d59 --- /dev/null +++ b/tools/ova/script/config.sh @@ -0,0 +1,88 @@ +#!/bin/bash +set -e + +attrs=( + harbor_admin_password + auth_mode + ldap_url + ldap_searchdn + ldap_search_pwd + ldap_basedn + ldap_uid + email_server + email_server_port + email_username + email_password + email_from + email_ssl + db_password + verify_remote_cert + ) + +base_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" && pwd )" + +#The location of harbor.cfg +cfg=$base_dir/harbor/harbor.cfg + +#Format cert and key files +function format { + file=$1 + head=$(sed -rn 's/(-+[A-Za-z ]*-+)([^-]*)(-+[A-Za-z ]*-+)/\1/p' $file) + body=$(sed -rn 's/(-+[A-Za-z ]*-+)([^-]*)(-+[A-Za-z ]*-+)/\2/p' $file) + tail=$(sed -rn 's/(-+[A-Za-z ]*-+)([^-]*)(-+[A-Za-z ]*-+)/\3/p' $file) + echo $head > $file + echo $body | sed 's/\s\+/\n/g' >> $file + echo $tail >> $file +} + +#Modify hostname +ip=$(ip addr show eth0|grep "inet "|tr -s ' '|cut -d ' ' -f 3|cut -d '/' -f 1) +if [ -n "$ip" ] +then + echo "Read IP address: [ IP - $ip ]" + sed -i -r s/"hostname = .*"/"hostname = $ip"/ $cfg +else + echo "Failed to get the IP address" + exit 1 +fi + +#Handle http/https +protocal=http +echo "Read attribute using ovfenv: [ ssl_cert ]" +ssl_cert=$(ovfenv -k ssl_cert) +echo "Read attribute using ovfenv: [ ssl_cert_key ]" +ssl_cert_key=$(ovfenv -k ssl_cert_key) +if [ -n "$ssl_cert" ] && [ -n "$ssl_cert_key" ] +then + echo "ssl_cert and ssl_cert_key are set, using HTTPS protocal" + protocal=https + sed -i -r s%"#?ui_url_protocol = .*"%"ui_url_protocol = $protocal"% $cfg + mkdir -p /path/to + echo $ssl_cert > /path/to/server.crt + format /path/to/server.crt + echo $ssl_cert_key > /path/to/server.key + format /path/to/server.key +else + echo "ssl_cert and ssl_cert_key are not set, using HTTP protocal" +fi + +for attr in "${attrs[@]}" +do + echo "Read attribute using ovfenv: [ $attr ]" + value=$(ovfenv -k $attr) + + #ldap search password and email password can be null + if [ -n "$value" ] || [ "$attr" = "ldap_search_pwd" ] \ + || [ "$attr" = "email_password" ] + then + if [ "$attr" = ldap_search_pwd ] \ + || [ "$attr" = email_password ] \ + || [ "$attr" = db_password ] \ + || [ "$attr" = harbor_admin_password ] + then + bs=$(echo $value | base64) + #value={base64}$bs + fi + sed -i -r s%"#?$attr = .*"%"$attr = $value"% $cfg + fi +done \ No newline at end of file diff --git a/tools/ova/script/firstboot.sh b/tools/ova/script/firstboot.sh new file mode 100755 index 000000000..dde6da80e --- /dev/null +++ b/tools/ova/script/firstboot.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -e + +echo "======================= $(date)=====================" + +export PATH=$PATH:/usr/local/bin + +base_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source $base_dir/common.sh + +#Reset root password +value=$(ovfenv -k root_pwd) +if [ -n "$value" ] +then + echo "Resetting root password..." + printf "$value\n$value\n" | passwd root +fi + +#echo "Adding rules to iptables..." +#addIptableRules + +echo "Installing docker compose..." +installDockerCompose + +echo "Starting docker service..." +systemctl start docker + +echo "Uncompress Harbor offline instaler tar..." +tar -zxvf $base_dir/../harbor-offline-installer*.tgz -C $base_dir/../ + +echo "Loading images..." +load + +#Configure Harbor +echo "Configuring Harbor..." +chmod 600 $base_dir/../harbor/harbor.cfg +configure + +#Start Harbor +echo "Starting Harbor..." +up + +echo "====================================================" \ No newline at end of file diff --git a/tools/ova/script/start_harbor.sh b/tools/ova/script/start_harbor.sh new file mode 100755 index 000000000..9dc967ede --- /dev/null +++ b/tools/ova/script/start_harbor.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e + +workdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $workdir/../harbor + +echo "[Step 1]: preparing environment ..." +./prepare + +echo "[Step 2]: starting Harbor ..." +docker-compose -f docker-compose*.yml up -d + +protocol=http +hostname=reg.mydomain.com + +if [[ $(cat ./harbor.cfg) =~ ui_url_protocol[[:blank:]]*=[[:blank:]]*(https?) ]] +then +protocol=${BASH_REMATCH[1]} +fi + +if [[ $(grep 'hostname[[:blank:]]*=' ./harbor.cfg) =~ hostname[[:blank:]]*=[[:blank:]]*(.*) ]] +then +hostname=${BASH_REMATCH[1]} +fi + +echo $" +----Harbor has been installed and started successfully.---- + +Now you should be able to visit the admin portal at ${protocol}://${hostname}. +For more details, please visit https://github.com/vmware/harbor . +" diff --git a/tools/ova/script/subsequentboot.sh b/tools/ova/script/subsequentboot.sh new file mode 100755 index 000000000..ad09d8743 --- /dev/null +++ b/tools/ova/script/subsequentboot.sh @@ -0,0 +1,37 @@ +#!/bin/bash +set -e +echo "======================= $(date)=====================" + +export PATH=$PATH:/usr/local/bin + +base_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source $base_dir/common.sh + +#echo "Adding rules to iptables..." +#addIptableRules + +#Stop Harbor +echo "Shutting down Harbor..." +down + +#Garbage collection +value=$(ovfenv -k gc_enabled) +if [ "$value" = "true" ] +then + echo "GC enabled, starting garbage collection..." + #If the registry contains no images, the gc will fail. + #So append a true to avoid failure. + gc registry:2.5.0 2>&1 >> /var/log/harbor/gc.log || true +else + echo "GC disabled, skip garbage collection" +fi + +#Configure Harbor +echo "Configuring Harbor..." +configure + +#Start Harbor +echo "Starting Harbor..." +up + +echo "====================================================" \ No newline at end of file From ebc569fb93f24b94120f64a9cc276ccbb3588cba Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Thu, 27 Oct 2016 14:24:10 +0800 Subject: [PATCH 04/15] fix #883 --- src/ui/api/project.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ui/api/project.go b/src/ui/api/project.go index e8828e0e3..9905630ec 100644 --- a/src/ui/api/project.go +++ b/src/ui/api/project.go @@ -20,10 +20,10 @@ import ( "net/http" "regexp" + "github.com/vmware/harbor/src/common/api" "github.com/vmware/harbor/src/common/dao" "github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/utils/log" - "github.com/vmware/harbor/src/common/api" "strconv" "time" @@ -192,7 +192,8 @@ func (p *ProjectAPI) Delete() { if err := dao.AddAccessLog(models.AccessLog{ UserID: userID, ProjectID: p.projectID, - RepoName: p.projectName, + RepoName: p.projectName + "/", + RepoTag: "N/A", Operation: "delete", }); err != nil { log.Errorf("failed to add access log: %v", err) From 231690281b563c6cb0187d5126b1e47ec63515e7 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Thu, 27 Oct 2016 14:58:33 +0800 Subject: [PATCH 05/15] fix #826 --- docs/user_guide.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/user_guide.md b/docs/user_guide.md index 084da17c3..9ab2e45f5 100644 --- a/docs/user_guide.md +++ b/docs/user_guide.md @@ -67,6 +67,9 @@ You can update or remove a member by clicking the icon on the right. ##Replicating images If you are a system administrator, you can replicate images to a remote registry, which is called destination in Harbor. Only Harbor instance is supported as a destination for now. + +**Note:** The replication feature is incompatible between Harbor instance before version 0.3.5(included) and after version 0.3.5. + Click "Add New Policy" on the "Replication" tab, fill the necessary fields and click "OK", a policy for this project will be created. If "Enable" is chosen, the project will be replicated to the remote immediately, and when a new repository is pushed to this project or an existing repository is deleted from this project, the same operation will also be replicated to the destination. ![browse project](img/new_create_policy.png) From a7c84cc2c8fb16b9d14e4ed472a609bb1e18e866 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Thu, 27 Oct 2016 14:16:23 +0800 Subject: [PATCH 06/15] fix #895. --- src/ui/api/member.go | 8 +++++++- src/ui/api/member_test.go | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/ui/api/member.go b/src/ui/api/member.go index 63cdc7cde..b528872c5 100644 --- a/src/ui/api/member.go +++ b/src/ui/api/member.go @@ -16,13 +16,14 @@ package api import ( + "fmt" "net/http" "strconv" + "github.com/vmware/harbor/src/common/api" "github.com/vmware/harbor/src/common/dao" "github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/utils/log" - "github.com/vmware/harbor/src/common/api" ) // ProjectMemberAPI handles request to /api/projects/{}/members/{} @@ -98,6 +99,11 @@ func (pma *ProjectMemberAPI) Get() { log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err) pma.CustomAbort(http.StatusInternalServerError, "Internal error.") } + + if len(roleList) == 0 { + pma.CustomAbort(http.StatusNotFound, fmt.Sprintf("user %d is not a member of the project", pma.memberID)) + } + //return empty role list to indicate if a user is not a member result := make(map[string]interface{}) user, err := dao.GetUser(models.User{UserID: pma.memberID}) diff --git a/src/ui/api/member_test.go b/src/ui/api/member_test.go index 4b6618e9b..8dbeae8fe 100644 --- a/src/ui/api/member_test.go +++ b/src/ui/api/member_test.go @@ -4,9 +4,10 @@ import ( "fmt" "testing" + "strconv" + "github.com/stretchr/testify/assert" "github.com/vmware/harbor/tests/apitests/apilib" - "strconv" ) func TestMemGet(t *testing.T) { @@ -51,8 +52,19 @@ func TestMemGet(t *testing.T) { assert.Equal(int(404), httpStatusCode, "Case 3: Project creation status should be 404") } - fmt.Printf("\n") + //------------case 4: Response Code=404, member does not exist-----------// + fmt.Println("case 4: Response Code=404, member does not exist") + projectID = "1" + memberID := "10000" + httpStatusCode, err = apiTest.GetMemByPIDUID(*admin, projectID, memberID) + if err != nil { + t.Fatalf("failed to get member %s of project %s: %v", memberID, projectID, err) + } + assert.Equal(int(404), httpStatusCode, + fmt.Sprintf("response status code should be 404 other than %d", httpStatusCode)) + + fmt.Printf("\n") } /** From f87e609aebfec5d91ec2563e4ff84ce00af4e462 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Fri, 28 Oct 2016 12:22:27 +0800 Subject: [PATCH 07/15] fix #964 --- docs/user_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_guide.md b/docs/user_guide.md index 084da17c3..20751a359 100644 --- a/docs/user_guide.md +++ b/docs/user_guide.md @@ -169,4 +169,4 @@ $ docker-compose start Option "--dry-run" will print the progress without removing any data. -About the details of GC, please see [GC](https://github.com/docker/distribution/blob/master/docs/garbage-collection.md). \ No newline at end of file +About the details of GC, please see [GC](https://github.com/docker/docker.github.io/blob/master/registry/garbage-collection.md). \ No newline at end of file From 9d3d7e6502be4f7790fbb0c99c68fa0bfdaf40a2 Mon Sep 17 00:00:00 2001 From: wemeya Date: Fri, 28 Oct 2016 13:44:30 +0800 Subject: [PATCH 08/15] modify log_test.go --- src/ui/api/log_test.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ui/api/log_test.go b/src/ui/api/log_test.go index a7b027a75..bda4d9279 100644 --- a/src/ui/api/log_test.go +++ b/src/ui/api/log_test.go @@ -21,7 +21,7 @@ func TestLogGet(t *testing.T) { project.ProjectName = "my_project" project.Public = 1 now := fmt.Sprintf("%v", time.Now().Unix()) - statusCode, result, err := apiTest.LogGet(*admin, "0", now, "") + statusCode, result, err := apiTest.LogGet(*admin, "0", now, "1000") if err != nil { t.Error("Error while get log information", err.Error()) t.Log(err) @@ -41,6 +41,7 @@ func TestLogGet(t *testing.T) { assert.Equal(int(201), reply, "Case 2: Project creation status should be 201") } //case 1: right parameters, expect the right output + now = fmt.Sprintf("%v", time.Now().Unix()) statusCode, result, err = apiTest.LogGet(*admin, "0", now, "1000") if err != nil { t.Error("Error while get log information", err.Error()) @@ -58,7 +59,6 @@ func TestLogGet(t *testing.T) { } fmt.Println("log ", result) //case 2: wrong format of start_time parameter, expect the wrong output - now = fmt.Sprintf("%v", time.Now().Unix()) statusCode, result, err = apiTest.LogGet(*admin, "ss", now, "3") if err != nil { t.Error("Error occured while get log information since the format of start_time parameter is not right.", err.Error()) @@ -77,7 +77,6 @@ func TestLogGet(t *testing.T) { } //case 4: wrong format of lines parameter, expect the wrong output - now = fmt.Sprintf("%v", time.Now().Unix()) statusCode, result, err = apiTest.LogGet(*admin, "0", now, "s") if err != nil { t.Error("Error occured while get log information since the format of lines parameter is not right.", err.Error()) @@ -87,7 +86,6 @@ func TestLogGet(t *testing.T) { } //case 5: wrong format of lines parameter, expect the wrong output - now = fmt.Sprintf("%v", time.Now().Unix()) statusCode, result, err = apiTest.LogGet(*admin, "0", now, "-5") if err != nil { t.Error("Error occured while get log information since the format of lines parameter is not right.", err.Error()) @@ -143,7 +141,6 @@ func TestLogGet(t *testing.T) { } fmt.Printf("\n") - } func getLog(result []apilib.AccessLog) (int, int) { From 509c68a78198b3e3faa95eba4be5b327727baf9b Mon Sep 17 00:00:00 2001 From: kunw Date: Fri, 28 Oct 2016 13:53:47 +0800 Subject: [PATCH 09/15] Updates for issues of account settings in LDAP. --- src/ui/controllers/accountsetting.go | 10 ++++++++-- src/ui/controllers/base.go | 2 +- src/ui/controllers/changepassword.go | 14 ++++++++++---- src/ui/controllers/optionalmenu.go | 8 +++++++- .../js/components/user/list-user.directive.html | 4 ++-- .../js/components/user/list-user.directive.js | 3 +++ src/ui/views/admin-options.htm | 2 +- 7 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/ui/controllers/accountsetting.go b/src/ui/controllers/accountsetting.go index 516547b98..f6587bfe1 100644 --- a/src/ui/controllers/accountsetting.go +++ b/src/ui/controllers/accountsetting.go @@ -11,8 +11,14 @@ type AccountSettingController struct { // Get renders the account settings page func (asc *AccountSettingController) Get() { - if asc.AuthMode != "db_auth" { + var isAdminForLdap bool + sessionUserID, ok := asc.GetSession("userId").(int) + if ok && sessionUserID == 1 { + isAdminForLdap = true + } + if asc.AuthMode == "db_auth" || isAdminForLdap { + asc.Forward("page_title_account_setting", "account-settings.htm") + } else { asc.CustomAbort(http.StatusForbidden, "") } - asc.Forward("page_title_account_setting", "account-settings.htm") } diff --git a/src/ui/controllers/base.go b/src/ui/controllers/base.go index 5bbba0557..c8d2c7a39 100644 --- a/src/ui/controllers/base.go +++ b/src/ui/controllers/base.go @@ -8,10 +8,10 @@ import ( "github.com/astaxie/beego" "github.com/beego/i18n" - "github.com/vmware/harbor/src/ui/auth" "github.com/vmware/harbor/src/common/dao" "github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/utils/log" + "github.com/vmware/harbor/src/ui/auth" ) // BaseController wraps common methods such as i18n support, forward, which can be leveraged by other UI render controllers. diff --git a/src/ui/controllers/changepassword.go b/src/ui/controllers/changepassword.go index 842cbe2f2..cbd1b11b0 100644 --- a/src/ui/controllers/changepassword.go +++ b/src/ui/controllers/changepassword.go @@ -10,9 +10,15 @@ type ChangePasswordController struct { } // Get renders the change password page -func (asc *ChangePasswordController) Get() { - if asc.AuthMode != "db_auth" { - asc.CustomAbort(http.StatusForbidden, "") +func (cpc *ChangePasswordController) Get() { + var isAdminForLdap bool + sessionUserID, ok := cpc.GetSession("userId").(int) + if ok && sessionUserID == 1 { + isAdminForLdap = true + } + if cpc.AuthMode == "db_auth" || isAdminForLdap { + cpc.Forward("page_title_change_password", "change-password.htm") + } else { + cpc.CustomAbort(http.StatusForbidden, "") } - asc.Forward("page_title_change_password", "change-password.htm") } diff --git a/src/ui/controllers/optionalmenu.go b/src/ui/controllers/optionalmenu.go index 96efcac68..fe0bb2b78 100644 --- a/src/ui/controllers/optionalmenu.go +++ b/src/ui/controllers/optionalmenu.go @@ -19,6 +19,8 @@ func (omc *OptionalMenuController) Get() { var hasLoggedIn bool var allowAddNew bool + + var isAdminForLdap bool var allowSettingAccount bool if sessionUserID != nil { @@ -35,7 +37,11 @@ func (omc *OptionalMenuController) Get() { } omc.Data["Username"] = u.Username - if omc.AuthMode == "db_auth" { + if userID == 1 { + isAdminForLdap = true + } + + if omc.AuthMode == "db_auth" || isAdminForLdap { allowSettingAccount = true } diff --git a/src/ui/static/resources/js/components/user/list-user.directive.html b/src/ui/static/resources/js/components/user/list-user.directive.html index 31e540295..10147219e 100644 --- a/src/ui/static/resources/js/components/user/list-user.directive.html +++ b/src/ui/static/resources/js/components/user/list-user.directive.html @@ -31,7 +31,7 @@ // 'email' | tr // // 'registration_time' | tr // // 'administrator' | tr // - // 'operation' | tr // + // 'operation' | tr // @@ -46,7 +46,7 @@ - +    diff --git a/src/ui/static/resources/js/components/user/list-user.directive.js b/src/ui/static/resources/js/components/user/list-user.directive.js index 18cd60a2c..77b1903db 100644 --- a/src/ui/static/resources/js/components/user/list-user.directive.js +++ b/src/ui/static/resources/js/components/user/list-user.directive.js @@ -98,6 +98,9 @@ 'restrict': 'E', 'templateUrl': '/static/resources/js/components/user/list-user.directive.html', 'link': link, + 'scope': { + 'authMode': '@' + }, 'controller': ListUserController, 'controllerAs': 'vm', 'bindToController': true diff --git a/src/ui/views/admin-options.htm b/src/ui/views/admin-options.htm index 68c225e0b..8e57a8ff0 100644 --- a/src/ui/views/admin-options.htm +++ b/src/ui/views/admin-options.htm @@ -24,7 +24,7 @@ // 'system_management' | tr // // 'system_management' | tr // - + From 5cefe5c91f8c6f7688814b967f1222b7eaa7cfb5 Mon Sep 17 00:00:00 2001 From: kunw Date: Fri, 28 Oct 2016 14:07:33 +0800 Subject: [PATCH 10/15] Updates for handling errors of UI. --- .../js/components/repository/list-repository.directive.js | 8 +++++++- .../resources/js/services/i18n/locale_messages_en-US.js | 1 + .../resources/js/services/i18n/locale_messages_zh-CN.js | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ui/static/resources/js/components/repository/list-repository.directive.js b/src/ui/static/resources/js/components/repository/list-repository.directive.js index 38d4117fc..918f80eac 100644 --- a/src/ui/static/resources/js/components/repository/list-repository.directive.js +++ b/src/ui/static/resources/js/components/repository/list-repository.directive.js @@ -104,8 +104,14 @@ } function getRepositoryFailed(response) { + var errorMessage = ''; + if(response.status === 404) { + errorMessage = $filter('tr')('project_does_not_exist'); + }else{ + errorMessage = $filter('tr')('failed_to_get_project'); + } $scope.$emit('modalTitle', $filter('tr')('error')); - $scope.$emit('modalMessage', $filter('tr')('project_does_not_exist')); + $scope.$emit('modalMessage', errorMessage); var emitInfo = { 'confirmOnly': true, 'contentType': 'text/html', diff --git a/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js b/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js index 46635cf2f..39de11118 100644 --- a/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js +++ b/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js @@ -233,6 +233,7 @@ var locale_messages = { 'failed_to_get_project_member': 'Failed to get current project member.', 'failed_to_delete_repo': 'Failed to delete repository. ', 'failed_to_delete_repo_insuffient_permissions': 'Failed to delete repository, insuffient permissions.', + 'failed_to_get_repo': 'Failed to get repositories.', 'failed_to_get_tag': 'Failed to get tag.', 'failed_to_get_log': 'Failed to get logs.', 'failed_to_get_project': 'Failed to get projects.', diff --git a/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js b/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js index 07903b375..b57d3c42a 100644 --- a/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js +++ b/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js @@ -233,6 +233,7 @@ var locale_messages = { 'failed_to_get_project_member': '无法获取当前项目成员。', 'failed_to_delete_repo': '无法删除镜像仓库。', 'failed_to_delete_repo_insuffient_permissions': '无法删除镜像仓库,权限不足。', + 'failed_to_get_repo': '获取镜像仓库数据失败。', 'failed_to_get_tag': '获取标签数据失败。', 'failed_to_get_log': '获取日志数据失败。', 'failed_to_get_project': '获取项目数据失败。', From 9252dbe7a0d4526cdf9713aed229d6ac3d5d42f1 Mon Sep 17 00:00:00 2001 From: zgdxiaoxiao Date: Fri, 28 Oct 2016 14:30:19 +0800 Subject: [PATCH 11/15] add test case of search api --- src/ui/api/harborapi_test.go | 21 +++++++++++++++++---- src/ui/api/search_test.go | 28 +++++++++++++++++++--------- src/ui/api/statistic_test.go | 4 ---- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/ui/api/harborapi_test.go b/src/ui/api/harborapi_test.go index 5bfb200fb..3169a6ed9 100644 --- a/src/ui/api/harborapi_test.go +++ b/src/ui/api/harborapi_test.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "log" "net/http/httptest" "path/filepath" "runtime" @@ -90,6 +91,11 @@ func init() { _ = updateInitPassword(1, "Harbor12345") + //syncRegistry + if err := SyncRegistry(); err != nil { + log.Fatalf("failed to sync repositories from registry: %v", err) + } + //Init user Info admin = &usrInfo{adminName, adminPwd} unknownUsr = &usrInfo{"unknown", "unknown"} @@ -119,8 +125,10 @@ func request(_sling *sling.Sling, acceptHeader string, authInfo ...usrInfo) (int //The response includes the project and repository list in a proper display order. //@param q Search parameter for project and repository name. //@return []Search -//func (a testapi) SearchGet (q string) (apilib.Search, error) { -func (a testapi) SearchGet(q string) (apilib.Search, error) { +func (a testapi) SearchGet(q string, authInfo ...usrInfo) (int, apilib.Search, error) { + var httpCode int + var body []byte + var err error _sling := sling.New().Get(a.basePath) @@ -134,10 +142,15 @@ func (a testapi) SearchGet(q string) (apilib.Search, error) { _sling = _sling.QueryStruct(&QueryParams{Query: q}) - _, body, err := request(_sling, jsonAcceptHeader) + if len(authInfo) > 0 { + httpCode, body, err = request(_sling, jsonAcceptHeader, authInfo[0]) + } else { + httpCode, body, err = request(_sling, jsonAcceptHeader) + } + var successPayload = new(apilib.Search) err = json.Unmarshal(body, &successPayload) - return *successPayload, err + return httpCode, *successPayload, err } //Create a new project. diff --git a/src/ui/api/search_test.go b/src/ui/api/search_test.go index 1eecd1009..ac05f74f2 100644 --- a/src/ui/api/search_test.go +++ b/src/ui/api/search_test.go @@ -14,19 +14,29 @@ func TestSearch(t *testing.T) { apiTest := newHarborAPI() var result apilib.Search - result, err := apiTest.SearchGet("library") - //fmt.Printf("%+v\n", result) + + //-------------case 1 : Response Code = 200, Not sysAdmin --------------// + httpStatusCode, result, err := apiTest.SearchGet("library") if err != nil { t.Error("Error while search project or repository", err.Error()) t.Log(err) } else { - assert.Equal(result.Projects[0].Id, int64(1), "Project id should be equal") - assert.Equal(result.Projects[0].Name, "library", "Project name should be library") - assert.Equal(result.Projects[0].Public, int32(1), "Project public status should be 1 (true)") - //t.Log(result) + assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200") + assert.Equal(int64(1), result.Projects[0].Id, "Project id should be equal") + assert.Equal("library", result.Projects[0].Name, "Project name should be library") + assert.Equal(int32(1), result.Projects[0].Public, "Project public status should be 1 (true)") + } + + //--------case 2 : Response Code = 200, sysAdmin and search repo--------// + httpStatusCode, result, err = apiTest.SearchGet("docker", *admin) + if err != nil { + t.Error("Error while search project or repository", err.Error()) + t.Log(err) + } else { + assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200") + assert.Equal("library", result.Repositories[0].ProjectName, "Project name should be library") + assert.Equal("library/docker", result.Repositories[0].RepositoryName, "Repository name should be library/docker") + assert.Equal(int32(1), result.Repositories[0].ProjectPublic, "Project public status should be 1 (true)") } - //if result.Response.StatusCode != 200 { - // t.Log(result.Response) - //} } diff --git a/src/ui/api/statistic_test.go b/src/ui/api/statistic_test.go index 17e2b9f5a..37400bea4 100644 --- a/src/ui/api/statistic_test.go +++ b/src/ui/api/statistic_test.go @@ -10,10 +10,6 @@ import ( ) func TestStatisticGet(t *testing.T) { - if err := SyncRegistry(); err != nil { - t.Fatalf("failed to sync repositories from registry: %v", err) - } - fmt.Println("Testing Statistic API") assert := assert.New(t) From 54696b11125f6458f546f28381336d9c263133a7 Mon Sep 17 00:00:00 2001 From: kunw Date: Fri, 28 Oct 2016 16:12:51 +0800 Subject: [PATCH 12/15] Updates for redirections when user is not an admin. --- src/ui/controllers/accountsetting.go | 6 +----- src/ui/controllers/adminoption.go | 18 +++++++++++++++++- src/ui/controllers/changepassword.go | 6 +----- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/ui/controllers/accountsetting.go b/src/ui/controllers/accountsetting.go index f6587bfe1..612015455 100644 --- a/src/ui/controllers/accountsetting.go +++ b/src/ui/controllers/accountsetting.go @@ -1,9 +1,5 @@ package controllers -import ( - "net/http" -) - // AccountSettingController handles request to /account_setting type AccountSettingController struct { BaseController @@ -19,6 +15,6 @@ func (asc *AccountSettingController) Get() { if asc.AuthMode == "db_auth" || isAdminForLdap { asc.Forward("page_title_account_setting", "account-settings.htm") } else { - asc.CustomAbort(http.StatusForbidden, "") + asc.Redirect("/dashboard", 302) } } diff --git a/src/ui/controllers/adminoption.go b/src/ui/controllers/adminoption.go index d0a10c1fa..69cc48828 100644 --- a/src/ui/controllers/adminoption.go +++ b/src/ui/controllers/adminoption.go @@ -1,5 +1,10 @@ package controllers +import ( + "github.com/vmware/harbor/src/common/dao" + "github.com/vmware/harbor/src/common/utils/log" +) + // AdminOptionController handles requests to /admin_option type AdminOptionController struct { BaseController @@ -7,5 +12,16 @@ type AdminOptionController struct { // Get renders the admin options page func (aoc *AdminOptionController) Get() { - aoc.Forward("page_title_admin_option", "admin-options.htm") + sessionUserID, ok := aoc.GetSession("userId").(int) + if ok { + isAdmin, err := dao.IsAdminRole(sessionUserID) + if err != nil { + log.Errorf("Error occurred in IsAdminRole: %v", err) + } + if isAdmin { + aoc.Forward("page_title_admin_option", "admin-options.htm") + return + } + } + aoc.Redirect("/dashboard", 302) } diff --git a/src/ui/controllers/changepassword.go b/src/ui/controllers/changepassword.go index cbd1b11b0..0873db73b 100644 --- a/src/ui/controllers/changepassword.go +++ b/src/ui/controllers/changepassword.go @@ -1,9 +1,5 @@ package controllers -import ( - "net/http" -) - // ChangePasswordController handles request to /change_password type ChangePasswordController struct { BaseController @@ -19,6 +15,6 @@ func (cpc *ChangePasswordController) Get() { if cpc.AuthMode == "db_auth" || isAdminForLdap { cpc.Forward("page_title_change_password", "change-password.htm") } else { - cpc.CustomAbort(http.StatusForbidden, "") + cpc.Redirect("/dashboard", 302) } } From 08b4851fc8daf9ea7515aeb9fbf7f95e3060985c Mon Sep 17 00:00:00 2001 From: kunw Date: Fri, 28 Oct 2016 16:50:40 +0800 Subject: [PATCH 13/15] Updates for controller test cases. --- src/ui/controllers/controllers_test.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/ui/controllers/controllers_test.go b/src/ui/controllers/controllers_test.go index b4cb4fe2c..c80377417 100644 --- a/src/ui/controllers/controllers_test.go +++ b/src/ui/controllers/controllers_test.go @@ -112,20 +112,17 @@ func TestMain(t *testing.T) { r, _ = http.NewRequest("GET", "/account_setting", nil) w = httptest.NewRecorder() beego.BeeApp.Handlers.ServeHTTP(w, r) - assert.Equal(int(200), w.Code, "'/account_setting' httpStatusCode should be 200") - assert.Equal(true, strings.Contains(fmt.Sprintf("%s", w.Body), "page_title_account_setting"), "http respond should have 'page_title_account_setting'") + assert.Equal(int(302), w.Code, "'/account_setting' httpStatusCode should be 302") r, _ = http.NewRequest("GET", "/change_password", nil) w = httptest.NewRecorder() beego.BeeApp.Handlers.ServeHTTP(w, r) - assert.Equal(int(200), w.Code, "'/change_password' httpStatusCode should be 200") - assert.Equal(true, strings.Contains(fmt.Sprintf("%s", w.Body), "page_title_change_password"), "http respond should have 'page_title_change_password'") + assert.Equal(int(302), w.Code, "'/change_password' httpStatusCode should be 302") r, _ = http.NewRequest("GET", "/admin_option", nil) w = httptest.NewRecorder() beego.BeeApp.Handlers.ServeHTTP(w, r) - assert.Equal(int(200), w.Code, "'/admin_option' httpStatusCode should be 200") - assert.Equal(true, strings.Contains(fmt.Sprintf("%s", w.Body), "page_title_admin_option"), "http respond should have 'page_title_admin_option'") + assert.Equal(int(302), w.Code, "'/admin_option' httpStatusCode should be 302") r, _ = http.NewRequest("GET", "/forgot_password", nil) w = httptest.NewRecorder() From 8c9435324dbe1b674ed3e2c149e1bfc096c9abe0 Mon Sep 17 00:00:00 2001 From: kunw Date: Fri, 28 Oct 2016 17:14:09 +0800 Subject: [PATCH 14/15] Updates for controller tests. --- src/ui/controllers/controllers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/controllers/controllers_test.go b/src/ui/controllers/controllers_test.go index c80377417..a6724ca25 100644 --- a/src/ui/controllers/controllers_test.go +++ b/src/ui/controllers/controllers_test.go @@ -117,7 +117,7 @@ func TestMain(t *testing.T) { r, _ = http.NewRequest("GET", "/change_password", nil) w = httptest.NewRecorder() beego.BeeApp.Handlers.ServeHTTP(w, r) - assert.Equal(int(302), w.Code, "'/change_password' httpStatusCode should be 302") + assert.Equal(int(200), w.Code, "'/change_password' httpStatusCode should be 200") r, _ = http.NewRequest("GET", "/admin_option", nil) w = httptest.NewRecorder() From 1d18f5d1540a6c34b48bb01e03ad33eb74cdf2fa Mon Sep 17 00:00:00 2001 From: kunw Date: Fri, 28 Oct 2016 17:30:00 +0800 Subject: [PATCH 15/15] Updates for controller tests. --- src/ui/controllers/controllers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/controllers/controllers_test.go b/src/ui/controllers/controllers_test.go index a6724ca25..46e239be6 100644 --- a/src/ui/controllers/controllers_test.go +++ b/src/ui/controllers/controllers_test.go @@ -112,7 +112,7 @@ func TestMain(t *testing.T) { r, _ = http.NewRequest("GET", "/account_setting", nil) w = httptest.NewRecorder() beego.BeeApp.Handlers.ServeHTTP(w, r) - assert.Equal(int(302), w.Code, "'/account_setting' httpStatusCode should be 302") + assert.Equal(int(200), w.Code, "'/account_setting' httpStatusCode should be 200") r, _ = http.NewRequest("GET", "/change_password", nil) w = httptest.NewRecorder()