mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-03 01:00:08 +01:00
Merge remote-tracking branch 'hupstream/dev' into dev
This commit is contained in:
commit
4653f48a8f
21
.gitignore
vendored
21
.gitignore
vendored
@ -1,13 +1,14 @@
|
||||
harbor
|
||||
Deploy/config/registry/config.yml
|
||||
Deploy/config/ui/env
|
||||
Deploy/config/ui/app.conf
|
||||
Deploy/config/db/env
|
||||
Deploy/config/jobservice/env
|
||||
Deploy/config/nginx/nginx.conf
|
||||
Deploy/config/nginx/cert/*
|
||||
Deploy/ui/harbor_ui
|
||||
Deploy/jobservice/harbor_jobservice
|
||||
ui/ui
|
||||
make/common/config/registry/config.yml
|
||||
make/common/config/ui/env
|
||||
make/common/config/ui/app.conf
|
||||
make/common/config/db/env
|
||||
make/common/config/jobservice/env
|
||||
make/common/config/nginx/nginx.conf
|
||||
make/common/config/nginx/cert/*
|
||||
make/dev/ui/harbor_ui
|
||||
make/dev//jobservice/harbor_jobservice
|
||||
src/ui/ui
|
||||
src/jobservice/jobservice
|
||||
*.pyc
|
||||
jobservice/test
|
||||
|
70
Makefile
70
Makefile
@ -28,7 +28,6 @@
|
||||
# for example: make package_online -e \
|
||||
# REGISTRYSERVER=reg-bj.eng.vmware.com \
|
||||
# REGISTRYPROJECTNAME=harborrelease
|
||||
# note**: DONT add "/" on end of REGISTRYSERVER.
|
||||
#
|
||||
# package_offline:
|
||||
# prepare offline install package
|
||||
@ -62,6 +61,9 @@
|
||||
# note**: If commit new code to github, the git commit TAG will \
|
||||
# change. Better use this commond clean previous images and \
|
||||
# files with specific TAG.
|
||||
# By default DEVFLAG=true, if you want to release new version of Harbor, \
|
||||
# should setting the flag to false.
|
||||
# make XXXX -e DEVFLAG=flase
|
||||
|
||||
SHELL := /bin/bash
|
||||
BUILDPATH=$(CURDIR)
|
||||
@ -75,6 +77,7 @@ BASEIMAGE=photon
|
||||
COMPILETAG=compile_normal
|
||||
REGISTRYSERVER=
|
||||
REGISTRYPROJECTNAME=vmware
|
||||
DEVFLAG=true
|
||||
|
||||
# docker parameters
|
||||
DOCKERCMD=$(shell which docker)
|
||||
@ -96,11 +99,13 @@ GODEP=$(GOTEST) -i
|
||||
GOFMT=gofmt -w
|
||||
GOBUILDIMAGE=reg.mydomain.com/library/harborgo[:tag]
|
||||
GOBUILDPATH=$(GOBASEPATH)/harbor
|
||||
GOBUILDPATH_UI=$(GOBUILDPATH)/ui
|
||||
GOBUILDPATH_JOBSERVICE=$(GOBUILDPATH)/jobservice
|
||||
GOIMAGEBUILDCMD=/usr/local/go/bin/go
|
||||
GOIMAGEBUILD=$(GOIMAGEBUILDCMD) build
|
||||
GOBUILDPATH_UI=$(GOBUILDPATH)/src/ui
|
||||
GOBUILDPATH_JOBSERVICE=$(GOBUILDPATH)/src/jobservice
|
||||
GOBUILDMAKEPATH=$(GOBUILDPATH)/make
|
||||
GOBUILDMAKEPATH_UI=$(GOBUILDMAKEPATH)/ui
|
||||
GOBUILDMAKEPATH_JOBSERVICE=$(GOBUILDMAKEPATH)/jobservice
|
||||
GOBUILDMAKEPATH_UI=$(GOBUILDMAKEPATH)/dev/ui
|
||||
GOBUILDMAKEPATH_JOBSERVICE=$(GOBUILDMAKEPATH)/dev/jobservice
|
||||
|
||||
# binary
|
||||
UISOURCECODE=$(SRCPATH)/ui
|
||||
@ -128,10 +133,10 @@ DOCKERFILEPATH_DB=$(DOCKERFILEPATH_COMMON)/db
|
||||
DOCKERFILENAME_DB=Dockerfile
|
||||
|
||||
# docker image name
|
||||
DOCKERIMAGENAME_UI=$(REGISTRYPROJECTNAME)/harbor-ui
|
||||
DOCKERIMAGENAME_JOBSERVICE=$(REGISTRYPROJECTNAME)/harbor-jobservice
|
||||
DOCKERIMAGENAME_LOG=$(REGISTRYPROJECTNAME)/harbor-log
|
||||
DOCKERIMAGENAME_DB=$(REGISTRYPROJECTNAME)/harbor-db
|
||||
DOCKERIMAGENAME_UI=vmware/harbor-ui
|
||||
DOCKERIMAGENAME_JOBSERVICE=vmware/harbor-jobservice
|
||||
DOCKERIMAGENAME_LOG=vmware/harbor-log
|
||||
DOCKERIMAGENAME_DB=vmware/harbor-db
|
||||
|
||||
|
||||
# docker-compose files
|
||||
@ -143,7 +148,12 @@ VERSIONFILEPATH=$(SRCPATH)/ui/views/sections
|
||||
VERSIONFILENAME=header-content.htm
|
||||
GITCMD=$(shell which git)
|
||||
GITTAG=$(GITCMD) describe --tags
|
||||
VERSIONTAG=$(shell $(GITTAG))
|
||||
ifeq ($(DEVFLAG), true)
|
||||
VERSIONTAG=dev
|
||||
else
|
||||
VERSIONTAG=$(shell $(GITTAG))
|
||||
endif
|
||||
|
||||
SEDCMD=$(shell which sed)
|
||||
|
||||
# package
|
||||
@ -186,11 +196,11 @@ compile_golangimage:
|
||||
@echo "compiling binary for ui (golang image)..."
|
||||
@echo $(GOBASEPATH)
|
||||
@echo $(GOBUILDPATH)
|
||||
$(DOCKERCMD) run --rm -v $(BUILDPATH):$(GOBUILDPATH) -w $(GOBUILDPATH_UI) $(GOBUILDIMAGE) $(GOBUILD) -v -o $(GOBUILDMAKEPATH_UI)/$(UIBINARYNAME)
|
||||
$(DOCKERCMD) run --rm -v $(BUILDPATH):$(GOBUILDPATH) -w $(GOBUILDPATH_UI) $(GOBUILDIMAGE) $(GOIMAGEBUILD) -v -o $(GOBUILDMAKEPATH_UI)/$(UIBINARYNAME)
|
||||
@echo "Done."
|
||||
|
||||
@echo "compiling binary for jobservice (golang image)..."
|
||||
$(DOCKERCMD) run --rm -v $(BUILDPATH):$(GOBUILDPATH) -w $(GOBUILDPATH_JOBSERVICE) $(GOBUILDIMAGE) $(GOBUILD) -v -o $(GOBUILDMAKEPATH_JOBSERVICE)/$(JOBSERVICEBINARYNAME)
|
||||
$(DOCKERCMD) run --rm -v $(BUILDPATH):$(GOBUILDPATH) -w $(GOBUILDPATH_JOBSERVICE) $(GOBUILDIMAGE) $(GOIMAGEBUILD) -v -o $(GOBUILDMAKEPATH_JOBSERVICE)/$(JOBSERVICEBINARYNAME)
|
||||
@echo "Done."
|
||||
|
||||
compile:check_environment $(COMPILETAG)
|
||||
@ -209,10 +219,10 @@ build_common: prepare version
|
||||
$(DOCKERPULL) nginx:1.9
|
||||
|
||||
build_photon: build_common
|
||||
make -f $(MAKEFILEPATH_PHOTON)/Makefile build
|
||||
make -f $(MAKEFILEPATH_PHOTON)/Makefile build -e DEVFLAG=$(DEVFLAG)
|
||||
|
||||
build_ubuntu: build_common
|
||||
make -f $(MAKEFILEPATH_UBUNTU)/Makefile build
|
||||
make -f $(MAKEFILEPATH_UBUNTU)/Makefile build -e DEVFLAG=$(DEVFLAG)
|
||||
|
||||
build: build_$(BASEIMAGE)
|
||||
|
||||
@ -230,8 +240,10 @@ install: compile build modify_composefile
|
||||
package_online: modify_composefile
|
||||
@echo "packing online package ..."
|
||||
@cp -r make $(HARBORPKG)
|
||||
@$(SEDCMD) -i 's/image\: vmware/image\: $(REGISTRYSERVER)\/$(REGISTRYPROJECTNAME)/' $(HARBORPKG)/docker-compose.$(VERSIONTAG).yml
|
||||
|
||||
@if [ -n "$(REGISTRYSERVER)" ] ; then \
|
||||
$(SEDCMD) -i 's/image\: vmware/image\: $(REGISTRYSERVER)\/$(REGISTRYPROJECTNAME)/' \
|
||||
$(HARBORPKG)/docker-compose.$(VERSIONTAG).yml ; \
|
||||
fi
|
||||
@cp LICENSE $(HARBORPKG)/LICENSE
|
||||
@cp NOTICE $(HARBORPKG)/NOTICE
|
||||
@$(TARCMD) -zcvf harbor-online-installer-$(VERSIONTAG).tgz \
|
||||
@ -258,7 +270,7 @@ package_offline: compile build modify_composefile
|
||||
$(DOCKERIMAGENAME_LOG):$(VERSIONTAG) \
|
||||
$(DOCKERIMAGENAME_DB):$(VERSIONTAG) \
|
||||
$(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG) \
|
||||
nginx:1.9.0 registry:2.5.0
|
||||
nginx:1.9 registry:2.5.0
|
||||
|
||||
@$(TARCMD) -zcvf harbor-offline-installer-$(VERSIONTAG).tgz \
|
||||
--exclude=$(HARBORPKG)/common/db --exclude=$(HARBORPKG)/ubuntu \
|
||||
@ -274,10 +286,10 @@ package_offline: compile build modify_composefile
|
||||
|
||||
pushimage:
|
||||
@echo "pushing harbor images ..."
|
||||
@$(DOCKERTAG) $(DOCKERIMAGENAME_UI):$(VERSIONTAG) $(REGISTRYSERVER)$(DOCKERIMAGENAME_UI):$(VERSIONTAG)
|
||||
@$(PUSHSCRIPTPATH)/$(PUSHSCRIPTNAME) $(REGISTRYSERVER)$(DOCKERIMAGENAME_UI):$(VERSIONTAG) \
|
||||
$(DOCKERTAG) $(DOCKERIMAGENAME_UI):$(VERSIONTAG) $(REGISTRYSERVER)$(DOCKERIMAGENAME_UI):$(VERSIONTAG)
|
||||
$(PUSHSCRIPTPATH)/$(PUSHSCRIPTNAME) $(REGISTRYSERVER)$(DOCKERIMAGENAME_UI):$(VERSIONTAG) \
|
||||
$(REGISTRYUSER) $(REGISTRYPASSWORD) $(REGISTRYSERVER)
|
||||
@$(DOCKERRMIMAGE) $(REGISTRYSERVER)$(DOCKERIMAGENAME_UI):$(VERSIONTAG)
|
||||
$(DOCKERRMIMAGE) $(REGISTRYSERVER)$(DOCKERIMAGENAME_UI):$(VERSIONTAG)
|
||||
|
||||
@$(DOCKERTAG) $(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG) $(REGISTRYSERVER)$(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG)
|
||||
@$(PUSHSCRIPTPATH)/$(PUSHSCRIPTNAME) $(REGISTRYSERVER)$(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG) \
|
||||
@ -315,8 +327,8 @@ cleanimage:
|
||||
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_DB):$(VERSIONTAG)
|
||||
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG)
|
||||
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_LOG):$(VERSIONTAG)
|
||||
- $(DOCKERRMIMAGE) -f registry:2.5.0
|
||||
- $(DOCKERRMIMAGE) -f nginx:1.9
|
||||
#- $(DOCKERRMIMAGE) -f registry:2.5.0
|
||||
#- $(DOCKERRMIMAGE) -f nginx:1.9
|
||||
|
||||
cleandockercomposefile:
|
||||
@echo "cleaning $(DOCKERCOMPOSEFILEPATH)/docker-compose.$(VERSIONTAG).yml"
|
||||
@ -334,8 +346,16 @@ cleanpackage:
|
||||
@if [ -f $(BUILDPATH)/harbor-offline-installer-$(VERSIONTAG).tgz ] ; \
|
||||
then rm $(BUILDPATH)/harbor-offline-installer-$(VERSIONTAG).tgz ; fi
|
||||
|
||||
.PHONY: clean
|
||||
clean: cleanbinary cleanimage cleandockercomposefile cleanversiontag cleanpackage
|
||||
.PHONY: cleanall
|
||||
cleanall: cleanbinary cleanimage cleandockercomposefile cleanversiontag cleanpackage
|
||||
|
||||
clean:
|
||||
@echo " make cleanall: remove binary, Harbor images, specific version docker-compose"
|
||||
@echo " file, specific version tag, online and offline install package"
|
||||
@echo " make cleanbinary: remove ui and jobservice binary"
|
||||
@echo " make cleanimage: remove Harbor images"
|
||||
@echo " make cleandockercomposefile: remove specific version docker-compose"
|
||||
@echo " make cleanversiontag: cleanpackageremove specific version tag"
|
||||
@echo " make cleanpackage: remove online and offline install package"
|
||||
|
||||
all: install
|
||||
|
||||
|
@ -69,7 +69,7 @@ function check_golang {
|
||||
fi
|
||||
|
||||
# docker has been installed and check its version
|
||||
if [[ $(go version) =~ (([0-9]+).([0-9]+).([0-9]+)) ]]
|
||||
if [[ $(go version) =~ (([0-9]+)\.([0-9]+)([\.0-9]*)) ]]
|
||||
then
|
||||
golang_version=${BASH_REMATCH[1]}
|
||||
golang_version_part1=${BASH_REMATCH[2]}
|
||||
@ -97,7 +97,7 @@ function check_docker {
|
||||
fi
|
||||
|
||||
# docker has been installed and check its version
|
||||
if [[ $(docker --version) =~ (([0-9]+).([0-9]+).([0-9]+)) ]]
|
||||
if [[ $(docker --version) =~ (([0-9]+)\.([0-9]+)([\.0-9]*)) ]]
|
||||
then
|
||||
docker_version=${BASH_REMATCH[1]}
|
||||
docker_version_part1=${BASH_REMATCH[2]}
|
||||
@ -125,7 +125,7 @@ function check_dockercompose {
|
||||
fi
|
||||
|
||||
# docker-compose has been installed, check its version
|
||||
if [[ $(docker-compose --version) =~ (([0-9]+).([0-9]+).([0-9]+)) ]]
|
||||
if [[ $(docker-compose --version) =~ (([0-9]+)\.([0-9]+)([\.0-9]*)) ]]
|
||||
then
|
||||
docker_compose_version=${BASH_REMATCH[1]}
|
||||
docker_compose_version_part1=${BASH_REMATCH[2]}
|
||||
|
Binary file not shown.
Binary file not shown.
@ -2,17 +2,18 @@
|
||||
#
|
||||
# Targets:
|
||||
#
|
||||
# build: build harbor photon images
|
||||
# build: build harbor ubuntu images
|
||||
# clean: clean ui and jobservice harbor images
|
||||
|
||||
# common
|
||||
SHELL := /bin/bash
|
||||
BUILDPATH=$(CURDIR)
|
||||
DEPLOYPATH=$(BUILDPATH)/make
|
||||
DEPLOYDEVPATH=$(DEPLOYPATH)/dev
|
||||
MAKEPATH=$(BUILDPATH)/make
|
||||
MAKEDEVPATH=$(MAKEPATH)/dev
|
||||
SRCPATH=./src
|
||||
TOOLSPATH=$(BUILDPATH)/tools
|
||||
CHECKENVCMD=checkenv.sh
|
||||
DEVFLAG=true
|
||||
|
||||
# docker parameters
|
||||
DOCKERCMD=$(shell which docker)
|
||||
@ -22,14 +23,14 @@ DOCKERIMASES=$(DOCKERCMD) images
|
||||
|
||||
# binary
|
||||
UISOURCECODE=$(SRCPATH)/ui
|
||||
UIBINARYPATH=$(DEPLOYDEVPATH)/ui
|
||||
UIBINARYPATH=$(MAKEDEVPATH)/ui
|
||||
UIBINARYNAME=harbor_ui
|
||||
JOBSERVICESOURCECODE=$(SRCPATH)/jobservice
|
||||
JOBSERVICEBINARYPATH=$(DEPLOYDEVPATH)/jobservice
|
||||
JOBSERVICEBINARYPATH=$(MAKEDEVPATH)/jobservice
|
||||
JOBSERVICEBINARYNAME=harbor_jobservice
|
||||
|
||||
# photon dockerfile
|
||||
DOCKERFILEPATH=$(DEPLOYPATH)/photon
|
||||
# ubuntu dockerfile
|
||||
DOCKERFILEPATH=$(MAKEPATH)/ubuntu
|
||||
DOCKERFILEPATH_UI=$(DOCKERFILEPATH)/ui
|
||||
DOCKERFILENAME_UI=Dockerfile
|
||||
DOCKERIMAGENAME_UI=vmware/harbor-ui
|
||||
@ -45,26 +46,30 @@ VERSIONFILEPATH=$(SRCPATH)/views/sections
|
||||
VERSIONFILENAME=header-content.htm
|
||||
GITCMD=$(shell which git)
|
||||
GITTAG=$(GITCMD) describe --tags
|
||||
VERSIONTAG=$(shell $(GITTAG))
|
||||
ifeq ($(DEVFLAG), true)
|
||||
VERSIONTAG=dev
|
||||
else
|
||||
VERSIONTAG=$(shell $(GITTAG))
|
||||
endif
|
||||
|
||||
check_environment:
|
||||
@$(TOOLSPATH)/$(CHECKENVCMD)
|
||||
@$(MAKEPATH)/$(CHECKENVCMD)
|
||||
|
||||
build:
|
||||
@echo "building ui container for photon..."
|
||||
@echo "building ui container for ubuntu..."
|
||||
$(DOCKERBUILD) -f $(DOCKERFILEPATH_UI)/$(DOCKERFILENAME_UI) -t $(DOCKERIMAGENAME_UI):$(VERSIONTAG) .
|
||||
@echo "Done."
|
||||
|
||||
@echo "building jobservice container for photon..."
|
||||
@echo "building jobservice container for ubuntu..."
|
||||
$(DOCKERBUILD) -f $(DOCKERFILEPATH_JOBSERVICE)/$(DOCKERFILENAME_JOBSERVICE) -t $(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG) .
|
||||
@echo "Done."
|
||||
|
||||
@echo "building log container for photon..."
|
||||
@echo "building log container for ubuntu..."
|
||||
$(DOCKERBUILD) -f $(DOCKERFILEPATH_LOG)/$(DOCKERFILENAME_LOG) -t $(DOCKERIMAGENAME_LOG):$(VERSIONTAG) .
|
||||
@echo "Done."
|
||||
|
||||
cleanimage:
|
||||
@echo "cleaning image for photon..."
|
||||
@echo "cleaning image for ubuntu..."
|
||||
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_UI):$(VERSIONTAG)
|
||||
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG)
|
||||
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_LOG):$(VERSIONTAG)
|
||||
|
@ -8,11 +8,12 @@
|
||||
# common
|
||||
SHELL := /bin/bash
|
||||
BUILDPATH=$(CURDIR)
|
||||
DEPLOYPATH=$(BUILDPATH)/make
|
||||
DEPLOYDEVPATH=$(DEPLOYPATH)/dev
|
||||
MAKEPATH=$(BUILDPATH)/make
|
||||
MAKEDEVPATH=$(MAKEPATH)/dev
|
||||
SRCPATH=./src
|
||||
TOOLSPATH=$(BUILDPATH)/tools
|
||||
CHECKENVCMD=checkenv.sh
|
||||
DEVFLAG=true
|
||||
|
||||
# docker parameters
|
||||
DOCKERCMD=$(shell which docker)
|
||||
@ -22,14 +23,14 @@ DOCKERIMASES=$(DOCKERCMD) images
|
||||
|
||||
# binary
|
||||
UISOURCECODE=$(SRCPATH)/ui
|
||||
UIBINARYPATH=$(DEPLOYDEVPATH)/ui
|
||||
UIBINARYPATH=$(MAKEDEVPATH)/ui
|
||||
UIBINARYNAME=harbor_ui
|
||||
JOBSERVICESOURCECODE=$(SRCPATH)/jobservice
|
||||
JOBSERVICEBINARYPATH=$(DEPLOYDEVPATH)/jobservice
|
||||
JOBSERVICEBINARYPATH=$(MAKEDEVPATH)/jobservice
|
||||
JOBSERVICEBINARYNAME=harbor_jobservice
|
||||
|
||||
# ubuntu dockerfile
|
||||
DOCKERFILEPATH=$(DEPLOYPATH)/ubuntu
|
||||
DOCKERFILEPATH=$(MAKEPATH)/ubuntu
|
||||
DOCKERFILEPATH_UI=$(DOCKERFILEPATH)/ui
|
||||
DOCKERFILENAME_UI=Dockerfile
|
||||
DOCKERIMAGENAME_UI=vmware/harbor-ui
|
||||
@ -45,10 +46,14 @@ VERSIONFILEPATH=$(SRCPATH)/views/sections
|
||||
VERSIONFILENAME=header-content.htm
|
||||
GITCMD=$(shell which git)
|
||||
GITTAG=$(GITCMD) describe --tags
|
||||
VERSIONTAG=$(shell $(GITTAG))
|
||||
ifeq ($(DEVFLAG), true)
|
||||
VERSIONTAG=dev
|
||||
else
|
||||
VERSIONTAG=$(shell $(GITTAG))
|
||||
endif
|
||||
|
||||
check_environment:
|
||||
@$(TOOLSPATH)/$(CHECKENVCMD)
|
||||
@$(MAKEPATH)/$(CHECKENVCMD)
|
||||
|
||||
build:
|
||||
@echo "building ui container for ubuntu..."
|
||||
|
@ -428,7 +428,13 @@ func TestResetUserPassword(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestChangeUserPassword(t *testing.T) {
|
||||
err := ChangeUserPassword(models.User{UserID: currentUser.UserID, Password: "NewHarborTester12345", Salt: currentUser.Salt})
|
||||
user := models.User{UserID: currentUser.UserID}
|
||||
query, err := GetUser(user)
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred when get user salt")
|
||||
}
|
||||
currentUser.Salt = query.Salt
|
||||
err = ChangeUserPassword(models.User{UserID: currentUser.UserID, Password: "NewHarborTester12345", Salt: currentUser.Salt})
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred in ChangeUserPassword: %v", err)
|
||||
}
|
||||
@ -444,7 +450,14 @@ func TestChangeUserPassword(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestChangeUserPasswordWithOldPassword(t *testing.T) {
|
||||
err := ChangeUserPassword(models.User{UserID: currentUser.UserID, Password: "NewerHarborTester12345", Salt: currentUser.Salt}, "NewHarborTester12345")
|
||||
user := models.User{UserID: currentUser.UserID}
|
||||
query, err := GetUser(user)
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred when get user salt")
|
||||
}
|
||||
currentUser.Salt = query.Salt
|
||||
|
||||
err = ChangeUserPassword(models.User{UserID: currentUser.UserID, Password: "NewerHarborTester12345", Salt: currentUser.Salt}, "NewHarborTester12345")
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred in ChangeUserPassword: %v", err)
|
||||
}
|
||||
|
@ -137,11 +137,12 @@ func ChangeUserPassword(u models.User, oldPassword ...string) (err error) {
|
||||
o := GetOrmer()
|
||||
|
||||
var r sql.Result
|
||||
salt := utils.GenerateRandomString()
|
||||
if len(oldPassword) == 0 {
|
||||
//In some cases, it may no need to check old password, just as Linux change password policies.
|
||||
r, err = o.Raw(`update user set password=?, salt=? where user_id=?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserID).Exec()
|
||||
r, err = o.Raw(`update user set password=?, salt=? where user_id=?`, utils.Encrypt(u.Password, salt), salt, u.UserID).Exec()
|
||||
} else {
|
||||
r, err = o.Raw(`update user set password=?, salt=? where user_id=? and password = ?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserID, utils.Encrypt(oldPassword[0], u.Salt)).Exec()
|
||||
r, err = o.Raw(`update user set password=?, salt=? where user_id=? and password = ?`, utils.Encrypt(u.Password, salt), salt, u.UserID, utils.Encrypt(oldPassword[0], u.Salt)).Exec()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -35,7 +35,7 @@ type User struct {
|
||||
// RoleList []Role `json:"role_list"`
|
||||
HasAdminRole int `orm:"column(sysadmin_flag)" json:"has_admin_role"`
|
||||
ResetUUID string `orm:"column(reset_uuid)" json:"reset_uuid"`
|
||||
Salt string `orm:"column(salt)"`
|
||||
Salt string `orm:"column(salt)" json:"-"`
|
||||
CreationTime time.Time `orm:"creation_time" json:"creation_time"`
|
||||
UpdateTime time.Time `orm:"update_time" json:"update_time"`
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ func CommonAddUser() {
|
||||
|
||||
commonUser := models.User{
|
||||
Username: TestUserName,
|
||||
Email: TestUserPwd,
|
||||
Password: TestUserEmail,
|
||||
Password: TestUserPwd,
|
||||
Email: TestUserEmail,
|
||||
}
|
||||
|
||||
_, _ = dao.Register(commonUser)
|
||||
|
@ -12,8 +12,8 @@ import (
|
||||
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/tests/apitests/apilib"
|
||||
"github.com/vmware/harbor/src/common/utils"
|
||||
"github.com/vmware/harbor/tests/apitests/apilib"
|
||||
// "strconv"
|
||||
// "strings"
|
||||
|
||||
@ -285,7 +285,7 @@ func (a testapi) ProjectsGetByPID(projectID string) (int, apilib.Project, error)
|
||||
}
|
||||
|
||||
//Search projects by projectName and isPublic
|
||||
func (a testapi) ProjectsGet(projectName string, isPublic int32) (int, []apilib.Project, error) {
|
||||
func (a testapi) ProjectsGet(projectName string, isPublic int32, authInfo ...usrInfo) (int, []apilib.Project, error) {
|
||||
_sling := sling.New().Get(a.basePath)
|
||||
|
||||
//create api path
|
||||
@ -299,7 +299,15 @@ func (a testapi) ProjectsGet(projectName string, isPublic int32) (int, []apilib.
|
||||
|
||||
var successPayload []apilib.Project
|
||||
|
||||
httpStatusCode, body, err := request(_sling, jsonAcceptHeader)
|
||||
var httpStatusCode int
|
||||
var err error
|
||||
var body []byte
|
||||
if len(authInfo) > 0 {
|
||||
httpStatusCode, body, err = request(_sling, jsonAcceptHeader, authInfo[0])
|
||||
} else {
|
||||
httpStatusCode, body, err = request(_sling, jsonAcceptHeader)
|
||||
}
|
||||
|
||||
if err == nil && httpStatusCode == 200 {
|
||||
err = json.Unmarshal(body, &successPayload)
|
||||
}
|
||||
|
@ -30,8 +30,7 @@ func TestLogGet(t *testing.T) {
|
||||
|
||||
}
|
||||
logNum := len(result)
|
||||
logID := result[0].LogId
|
||||
fmt.Println(result)
|
||||
fmt.Println("result", result)
|
||||
//add the project first.
|
||||
fmt.Println("add the project first.")
|
||||
reply, err := apiTest.ProjectsPost(*admin, project)
|
||||
@ -48,12 +47,16 @@ func TestLogGet(t *testing.T) {
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(logNum+1, len(result), "lines of logs should be equal")
|
||||
assert.Equal(int32(logID+1), result[0].LogId, "LogId should be equal")
|
||||
assert.Equal("my_project/", result[0].RepoName, "RepoName should be equal")
|
||||
assert.Equal("N/A", result[0].RepoTag, "RepoTag should be equal")
|
||||
assert.Equal("create", result[0].Operation, "Operation should be equal")
|
||||
num, index := getLog(result)
|
||||
if num != 1 {
|
||||
assert.Equal(1, num, "add my_project log number should be 1")
|
||||
} else {
|
||||
assert.Equal("my_project/", result[index].RepoName, "RepoName should be equal")
|
||||
assert.Equal("N/A", result[index].RepoTag, "RepoTag should be equal")
|
||||
assert.Equal("create", result[index].Operation, "Operation should be equal")
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
@ -103,13 +106,17 @@ func TestLogGet(t *testing.T) {
|
||||
if logNum+1 >= 10 {
|
||||
logNum = 10
|
||||
} else {
|
||||
logNum += 1
|
||||
logNum++
|
||||
}
|
||||
assert.Equal(logNum, len(result), "lines of logs should be equal")
|
||||
assert.Equal(int32(logID+1), result[0].LogId, "LogId should be equal")
|
||||
assert.Equal("my_project/", result[0].RepoName, "RepoName should be equal")
|
||||
assert.Equal("N/A", result[0].RepoTag, "RepoTag should be equal")
|
||||
assert.Equal("create", result[0].Operation, "Operation should be equal")
|
||||
num, index := getLog(result)
|
||||
if num != 1 {
|
||||
assert.Equal(1, num, "add my_project log number should be 1")
|
||||
} else {
|
||||
assert.Equal("my_project/", result[index].RepoName, "RepoName should be equal")
|
||||
assert.Equal("N/A", result[index].RepoTag, "RepoTag should be equal")
|
||||
assert.Equal("create", result[index].Operation, "Operation should be equal")
|
||||
}
|
||||
}
|
||||
|
||||
//get the project
|
||||
@ -138,3 +145,14 @@ func TestLogGet(t *testing.T) {
|
||||
fmt.Printf("\n")
|
||||
|
||||
}
|
||||
|
||||
func getLog(result []apilib.AccessLog) (int, int) {
|
||||
var num, index int
|
||||
for i := 0; i < len(result); i++ {
|
||||
if result[i].RepoName == "my_project/" {
|
||||
num++
|
||||
index = i
|
||||
}
|
||||
}
|
||||
return num, index
|
||||
}
|
||||
|
@ -286,6 +286,13 @@ func (p *ProjectAPI) List() {
|
||||
if public != 1 {
|
||||
if isAdmin {
|
||||
projectList[i].Role = models.PROJECTADMIN
|
||||
} else {
|
||||
roles, err := dao.GetUserProjectRoles(p.userID, projectList[i].ProjectID)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get user's project role: %v", err)
|
||||
p.CustomAbort(http.StatusInternalServerError, "")
|
||||
}
|
||||
projectList[i].Role = roles[0].RoleID
|
||||
}
|
||||
if projectList[i].Role == models.PROJECTADMIN {
|
||||
projectList[i].Togglable = true
|
||||
|
@ -13,7 +13,7 @@ var addProject *apilib.ProjectReq
|
||||
var addPID int
|
||||
|
||||
func InitAddPro() {
|
||||
addProject = &apilib.ProjectReq{"test_project", 1}
|
||||
addProject = &apilib.ProjectReq{"add_project", 1}
|
||||
}
|
||||
|
||||
func TestAddProject(t *testing.T) {
|
||||
@ -106,7 +106,49 @@ func TestProGetByName(t *testing.T) {
|
||||
} else {
|
||||
assert.Equal(int(401), httpStatusCode, "httpStatusCode should be 200")
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
|
||||
//-------------------case 3 : check admin project role------------------------//
|
||||
httpStatusCode, result, err = apiTest.ProjectsGet(addProject.ProjectName, 0, *admin)
|
||||
if err != nil {
|
||||
t.Error("Error while search project by proName and isPublic", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
|
||||
assert.Equal(addProject.ProjectName, result[0].ProjectName, "Project name is wrong")
|
||||
assert.Equal(int32(1), result[0].Public, "Public is wrong")
|
||||
assert.Equal(int32(1), result[0].CurrentUserRoleId, "User project role is wrong")
|
||||
}
|
||||
|
||||
//-------------------case 4 : add project member and check his role ------------------------//
|
||||
CommonAddUser()
|
||||
roles := &apilib.RoleParam{[]int32{2}, TestUserName}
|
||||
projectID := strconv.Itoa(addPID)
|
||||
httpStatusCode, err = apiTest.AddProjectMember(*admin, projectID, *roles)
|
||||
if err != nil {
|
||||
t.Error("Error whihle add project role member", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
|
||||
}
|
||||
httpStatusCode, result, err = apiTest.ProjectsGet(addProject.ProjectName, 0, *testUser)
|
||||
if err != nil {
|
||||
t.Error("Error while search project by proName and isPublic", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
|
||||
assert.Equal(addProject.ProjectName, result[0].ProjectName, "Project name is wrong")
|
||||
assert.Equal(int32(1), result[0].Public, "Public is wrong")
|
||||
assert.Equal(int32(2), result[0].CurrentUserRoleId, "User project role is wrong")
|
||||
}
|
||||
id := strconv.Itoa(CommonGetUserID())
|
||||
httpStatusCode, err = apiTest.DeleteProjectMember(*admin, projectID, id)
|
||||
if err != nil {
|
||||
t.Error("Error whihle add project role member", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
|
||||
}
|
||||
CommonDelUser()
|
||||
}
|
||||
|
||||
//Get project by proID
|
||||
|
@ -23,10 +23,10 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// UserAPI handles request to /api/users/{}
|
||||
@ -152,7 +152,7 @@ func (ua *UserAPI) Put() {
|
||||
ua.DecodeJSONReq(&user)
|
||||
err := commonValidate(user)
|
||||
if err != nil {
|
||||
log.Warning("Bad request in change user profile: %v", err)
|
||||
log.Warningf("Bad request in change user profile: %v", err)
|
||||
ua.RenderError(http.StatusBadRequest, "change user profile error:"+err.Error())
|
||||
return
|
||||
}
|
||||
@ -200,7 +200,7 @@ func (ua *UserAPI) Post() {
|
||||
ua.DecodeJSONReq(&user)
|
||||
err := validate(user)
|
||||
if err != nil {
|
||||
log.Warning("Bad request in Register: %v", err)
|
||||
log.Warningf("Bad request in Register: %v", err)
|
||||
ua.RenderError(http.StatusBadRequest, "register error:"+err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -354,6 +354,16 @@ func TestUsersUpdatePassword(t *testing.T) {
|
||||
assert.Equal(200, code, "Get users status should be 200")
|
||||
testUser0002.Password = password.NewPassword
|
||||
testUser0002Auth.Passwd = password.NewPassword
|
||||
//TODO: verify the new password takes effect
|
||||
}
|
||||
//case 6: update user2 password setting the new password same as the old
|
||||
password.OldPassword = password.NewPassword
|
||||
code, err = apiTest.UsersUpdatePassword(testUser0002ID, password, *admin)
|
||||
if err != nil {
|
||||
t.Error("Error occured while change user profile", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(200, code, "When new password is same as old, update user password status should be 200")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,35 +26,26 @@
|
||||
var vm = this;
|
||||
|
||||
vm.isAdmin = (vm.hasAdminRole === 1);
|
||||
vm.enabled = vm.isAdmin ? 0 : 1;
|
||||
vm.toggle = toggle;
|
||||
vm.editable = (vm.currentUser.user_id !== Number(vm.userId));
|
||||
|
||||
function toggle() {
|
||||
ToggleAdminService(vm.userId, vm.enabled)
|
||||
ToggleAdminService(vm.userId, vm.isAdmin ? 0 : 1)
|
||||
.success(toggleAdminSuccess)
|
||||
.error(toggleAdminFailed);
|
||||
}
|
||||
|
||||
function toggleAdminSuccess(data, status) {
|
||||
if(vm.isAdmin) {
|
||||
vm.isAdmin = false;
|
||||
}else{
|
||||
vm.isAdmin = true;
|
||||
}
|
||||
console.log('Toggled userId:' + vm.userId + ' to admin:' + vm.isAdmin);
|
||||
vm.isAdmin = !vm.isAdmin;
|
||||
}
|
||||
|
||||
function toggleAdminFailed(data, status) {
|
||||
console.log('Failed to toggle admin:' + data);
|
||||
vm.isAdmin = !vm.isAdmin;
|
||||
$scope.$emit('modalTitle', $filter('tr')('error'));
|
||||
$scope.$emit('modalMessage', $filter('tr')('failed_to_toggle_admin'));
|
||||
$scope.$emit('raiseError', true);
|
||||
if(vm.isAdmin) {
|
||||
vm.isAdmin = false;
|
||||
}else{
|
||||
vm.isAdmin = true;
|
||||
}
|
||||
console.log('Failed to toggle admin:' + data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('harbor.validator')
|
||||
.directive('email', email);
|
||||
|
||||
email.$inject = ['EMAIL_REGEXP'];
|
||||
|
||||
function email(EMAIL_REGEXP) {
|
||||
var directive = {
|
||||
'require' : 'ngModel',
|
||||
'link': link
|
||||
};
|
||||
return directive;
|
||||
|
||||
function link (scope, element, attrs, ctrl) {
|
||||
|
||||
ctrl.$validators.email = validator;
|
||||
|
||||
function validator(modelValue, viewValue) {
|
||||
|
||||
return EMAIL_REGEXP.test(modelValue);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -20,5 +20,7 @@
|
||||
.module('harbor.validator')
|
||||
.constant('INVALID_CHARS', [",","~","#", "$", "%"])
|
||||
.constant('PASSWORD_REGEXP', /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{8,20}$/)
|
||||
.constant('PROJECT_REGEXP', /^[a-z0-9](?:-*[a-z0-9])*(?:[._][a-z0-9](?:-*[a-z0-9])*)*$/);
|
||||
.constant('PROJECT_REGEXP', /^[a-z0-9](?:-*[a-z0-9])*(?:[._][a-z0-9](?:-*[a-z0-9])*)*$/)
|
||||
.constant('EMAIL_REGEXP', /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
|
||||
|
||||
})();
|
@ -20,9 +20,9 @@
|
||||
.module('harbor.session')
|
||||
.controller('CurrentUserController', CurrentUserController);
|
||||
|
||||
CurrentUserController.$inject = ['$scope', 'CurrentUserService', 'currentUser', '$window', '$document'];
|
||||
CurrentUserController.$inject = ['$scope', 'CurrentUserService', 'currentUser', '$window', '$document', 'LogOutService'];
|
||||
|
||||
function CurrentUserController($scope, CurrentUserService, currentUser, $window, $document) {
|
||||
function CurrentUserController($scope, CurrentUserService, currentUser, $window, $document, LogOutService) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
@ -40,7 +40,18 @@
|
||||
}
|
||||
|
||||
function getCurrentUserFailed(e){
|
||||
console.log('No session of current user.');
|
||||
console.log('Failed to get current user:' + e);
|
||||
LogOutService()
|
||||
.success(logOutSuccess)
|
||||
.error(logOutFailed);
|
||||
}
|
||||
|
||||
function logOutSuccess(data, status) {
|
||||
currentUser.unset();
|
||||
}
|
||||
|
||||
function logOutFailed(data, status) {
|
||||
console.log('Failed to log out:' + data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
<div class="form-group">
|
||||
<label for="email" class="col-sm-3 control-label">// 'email' | tr //:</label>
|
||||
<div class="col-sm-7">
|
||||
<input type="email" class="form-control" id="email" ng-model="user.email" name="uEmail" required>
|
||||
<input type="text" class="form-control" id="email" ng-model="user.email" name="uEmail" required email>
|
||||
<div class="error-message" ng-messages="form.uEmail.$touched && form.uEmail.$error">
|
||||
<span ng-message="required">// 'email_is_required' | tr //</span>
|
||||
<span ng-message="email">// 'email_content_illegal' | tr //</span>
|
||||
|
@ -24,7 +24,7 @@
|
||||
<div class="form-group">
|
||||
<label for="email" class="col-sm-3 control-label">// 'email' | tr //:</label>
|
||||
<div class="col-sm-7">
|
||||
<input type="email" class="form-control" id="email" ng-model="user.email" ng-model-options="{ debounce: 500 }" ng-change="vm.reset()" name="uEmail" required data-target="email">
|
||||
<input type="text" class="form-control" id="email" ng-model="user.email" ng-model-options="{ debounce: 500 }" ng-change="vm.reset()" name="uEmail" required data-target="email" email>
|
||||
<div class="error-message">
|
||||
<div ng-messages="(form.$submitted || form.uEmail.$touched) && form.uEmail.$error">
|
||||
<span ng-message="required">// 'email_is_required' | tr //</span>
|
||||
|
@ -127,6 +127,7 @@
|
||||
<script src="/static/resources/js/components/validator/user-exist.validator.js"></script>
|
||||
<script src="/static/resources/js/components/validator/invalid-chars.validator.js"></script>
|
||||
<script src="/static/resources/js/components/validator/project-name.validator.js"></script>
|
||||
<script src="/static/resources/js/components/validator/email.validator.js"></script>
|
||||
|
||||
<script src="/static/resources/js/components/search/search.module.js"></script>
|
||||
<script src="/static/resources/js/components/search/search.directive.js"></script>
|
||||
|
@ -45,12 +45,11 @@
|
||||
<div class="form-group">
|
||||
<label for="email" class="col-sm-3 control-label">// 'email' | tr //:</label>
|
||||
<div class="col-sm-7">
|
||||
<input type="email" class="form-control" id="email" ng-model="user.email" name="uEmail" ng-model-options="{ updateOn: 'blur' }" required user-exists data-target="email" maxlength="50">
|
||||
<div class="error-message" ng-messages="(form.$submitted || form.uEmail.$touched) &&form.uEmail.$error">
|
||||
<input type="text" class="form-control" id="email" ng-model="user.email" name="uEmail" ng-model-options="{ updateOn: 'blur' }" required user-exists data-target="email" email>
|
||||
<div class="error-message" ng-messages="(form.$submitted || form.uEmail.$touched) && form.uEmail.$error">
|
||||
<span ng-message="required">// 'email_is_required' | tr //</span>
|
||||
<span ng-message="email">// 'email_content_illegal' | tr //</span>
|
||||
<span ng-message="userExists">// 'email_has_been_taken' | tr //</span>
|
||||
<span ng-message="maxlength">// 'email_is_too_long' | tr //</span>
|
||||
</div>
|
||||
<p class="help-block small-size-fonts">// 'email_desc' | tr //</p>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user