diff --git a/.travis.yml b/.travis.yml index 6e536c507..aff9e1f81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,14 @@ language: go go: - - 1.5.3 + - 1.6.2 go_import_path: github.com/vmware/harbor service: - mysql -env: GO15VENDOREXPERIMENT=1 DB_HOST=127.0.0.1 DB_PORT=3306 DB_USR=root DB_PWD= +env: DB_HOST=127.0.0.1 DB_PORT=3306 DB_USR=root DB_PWD= install: - sudo apt-get update && sudo apt-get install -y libldap2-dev diff --git a/Deploy/templates/ui/env b/Deploy/templates/ui/env index fe91f5965..d21e8fafc 100644 --- a/Deploy/templates/ui/env +++ b/Deploy/templates/ui/env @@ -12,4 +12,4 @@ LDAP_URL=$ldap_url LDAP_BASE_DN=$ldap_basedn SELF_REGISTRATION=$self_registration LOG_LEVEL=debug -GODEBUG=netdns=cgo \ No newline at end of file +GODEBUG=netdns=cgo diff --git a/Dockerfile.ui b/Dockerfile.ui index 459158279..c5b087bd3 100644 --- a/Dockerfile.ui +++ b/Dockerfile.ui @@ -1,4 +1,4 @@ -FROM golang:1.5.1 +FROM golang:1.6.2 MAINTAINER jiangd@vmware.com @@ -11,7 +11,6 @@ COPY . /go/src/github.com/vmware/harbor COPY ./vendor/golang.org /go/src/golang.org WORKDIR /go/src/github.com/vmware/harbor/ui -ENV GO15VENDOREXPERIMENT 1 RUN go get -d github.com/docker/distribution \ && go get -d github.com/docker/libtrust \ && go get -d github.com/go-sql-driver/mysql \ diff --git a/dao/accesslog.go b/dao/accesslog.go index dbf447353..908fb9280 100644 --- a/dao/accesslog.go +++ b/dao/accesslog.go @@ -62,6 +62,14 @@ func GetAccessLogs(accessLog models.AccessLog) ([]models.AccessLog, error) { sql += ` and u.username like ? ` queryParam = append(queryParam, accessLog.Username) } + if accessLog.RepoName != "" { + sql += ` and a.repo_name = ? ` + queryParam = append(queryParam, accessLog.RepoName) + } + if accessLog.RepoTag != "" { + sql += ` and a.repo_tag = ? ` + queryParam = append(queryParam, accessLog.RepoTag) + } if accessLog.Keywords != "" { sql += ` and a.operation in ( ` keywordList := strings.Split(accessLog.Keywords, "/") diff --git a/dao/dao_test.go b/dao/dao_test.go index da0ad6993..99ece3348 100644 --- a/dao/dao_test.go +++ b/dao/dao_test.go @@ -102,6 +102,8 @@ func clearUp(username string) { const username string = "Tester01" const projectName string = "test_project" +const repoTag string = "test1.1" +const repoTag2 string = "test1.2" const SysAdmin int = 1 const projectAdmin int = 2 const developer int = 3 @@ -419,6 +421,66 @@ func TestGetAccessLog(t *testing.T) { } } +func TestAddAccessLog(t *testing.T) { + var err error + var accessLogList []models.AccessLog + accessLog := models.AccessLog{ + UserID: currentUser.UserID, + ProjectID: currentProject.ProjectID, + RepoName: currentProject.Name + "/", + RepoTag: repoTag, + GUID: "N/A", + Operation: "create", + OpTime: time.Now(), + } + err = AddAccessLog(accessLog) + if err != nil { + t.Errorf("Error occurred in AddAccessLog: %v", err) + } + accessLogList, err = GetAccessLogs(accessLog) + if err != nil { + t.Errorf("Error occurred in GetAccessLog: %v", err) + } + if len(accessLogList) != 1 { + t.Errorf("The length of accesslog list should be 1, actual: %d", len(accessLogList)) + } + if accessLogList[0].RepoName != projectName+"/" { + t.Errorf("The project name does not match, expected: %s, actual: %s", projectName+"/", accessLogList[0].RepoName) + } + if accessLogList[0].RepoTag != repoTag { + t.Errorf("The repo tag does not match, expected: %s, actual: %s", repoTag, accessLogList[0].RepoTag) + } +} + +func TestAccessLog(t *testing.T) { + var err error + var accessLogList []models.AccessLog + accessLog := models.AccessLog{ + UserID: currentUser.UserID, + ProjectID: currentProject.ProjectID, + RepoName: currentProject.Name + "/", + RepoTag: repoTag2, + Operation: "create", + } + err = AccessLog(currentUser.Username, currentProject.Name, currentProject.Name+"/", repoTag2, "create") + if err != nil { + t.Errorf("Error occurred in AccessLog: %v", err) + } + accessLogList, err = GetAccessLogs(accessLog) + if err != nil { + t.Errorf("Error occurred in GetAccessLog: %v", err) + } + if len(accessLogList) != 1 { + t.Errorf("The length of accesslog list should be 1, actual: %d", len(accessLogList)) + } + if accessLogList[0].RepoName != projectName+"/" { + t.Errorf("The project name does not match, expected: %s, actual: %s", projectName+"/", accessLogList[0].RepoName) + } + if accessLogList[0].RepoTag != repoTag2 { + t.Errorf("The repo tag does not match, expected: %s, actual: %s", repoTag2, accessLogList[0].RepoTag) + } +} + func TestProjectExists(t *testing.T) { var exists bool var err error diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 404a0b431..20307cc49 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -109,7 +109,7 @@ paths: tags: - Products responses: - 200: + 201: description: Project created successfully. 400: description: Unsatisfied with constraints of the project creation. @@ -383,6 +383,28 @@ paths: description: User does not have permission of admin role. 500: description: Unexpected internal errors. + post: + summary: Creates a new user account. + description: | + This endpoint is to create a user if the user does not already exist. + parameters: + - name: user + in: body + description: New created user. + required: true + schema: + $ref: '#/definitions/User' + tags: + - Products + responses: + 201: + description: User created successfully. + 400: + description: Unsatisfied with constraints of the user creation. + 403: + description: User registration can only be used by admin role user when self-registration is off. + 500: + description: Unexpected internal errors. /users/{user_id}: put: summary: Update a registered user to change to be an administrator of Harbor. @@ -438,6 +460,37 @@ paths: description: User ID does not exist. 500: description: Unexpected internal errors. + /users/{user_id}/password: + put: + summary: Change the password on a user that already exists. + description: | + This endpoint is for user to update password. Users with the admin role can change any user's password. Guest users can change only their own password. + parameters: + - name: user_id + in: path + type: integer + format: int32 + required: true + description: Registered user ID. + - name: password + in: body + description: Password to be updated. + required: true + schema: + $ref: '#/definitions/Password' + tags: + - Products + responses: + 200: + description: Updated password successfully. + 400: + description: Invalid user ID; Old password is blank; New password is blank. + 401: + description: Old password is not correct. + 403: + description: Guests can only change their own account. + 500: + description: Unexpected internal errors. /repositories: get: summary: Get repositories accompany with relevant project and repo name. @@ -640,6 +693,15 @@ definitions: deleted: type: integer format: int32 + Password: + type: object + properties: + old_password: + type: string + description: The user's existing password. + new_password: + type: string + description: New password for marking as to be updated. AccessLog: type: object properties: