diff --git a/docs/swagger.yaml b/docs/swagger.yaml index b7e6e4a62..7a52174ea 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -448,186 +448,7 @@ paths: description: Project or metadata does not exist. '500': description: Internal server errors. - '/projects/{project_id}/members/': - get: - summary: Return a project's relevant role members. - description: > - This endpoint is for user to search a specified project's relevant role - members. - parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID. - tags: - - Products - responses: - '200': - description: Get project's relevant role members successfully. - schema: - type: array - items: - $ref: '#/definitions/User' - '400': - description: Illegal format of provided ID value. - '401': - description: User need to log in first. - '403': - description: User in session does not have permission to the project. - '404': - description: Project ID does not exist. - '500': - description: Unexpected internal errors. - post: - summary: Add project role member accompany with relevant project and user. - description: > - This endpoint is for user to add project role member accompany with - relevant project and user. - parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID. - - name: roles - in: body - description: >- - Role members for adding to relevant project. Only one role is - supported in the role list. - schema: - $ref: '#/definitions/RoleParam' - tags: - - Products - responses: - '200': - description: Role members added to relevant project successfully. - '400': - description: Illegal format of provided ID value. - '401': - description: User need to log in first. - '403': - description: User in session does not have permission to the project. - '404': - description: Project ID or username does not exist. - '409': - description: User has already added as a project role member. - '415': - $ref: '#/responses/UnsupportedMediaType' - '500': - description: Unexpected internal errors. - '/projects/{project_id}/members/{user_id}': - get: - summary: Return role members accompany with relevant project and user. - description: > - This endpoint is for user to get role members accompany with relevant - project and user. - parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID - - name: user_id - in: path - type: integer - format: int - required: true - description: Relevant user ID - tags: - - Products - responses: - '200': - description: Get project role members successfully. - schema: - type: array - items: - $ref: '#/definitions/Role' - '400': - description: Illegal format of provided ID value. - '401': - description: User need to log in first. - '403': - description: User in session does not have permission to the project. - '404': - description: Project ID does not exist. - '500': - description: Unexpected internal errors. - put: - summary: Update project role members accompany with relevant project and user. - description: > - This endpoint is for user to update current project role members - accompany with relevant project and user. - parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID. - - name: user_id - in: path - type: integer - format: int - required: true - description: Relevant user ID. - - name: roles - in: body - schema: - $ref: '#/definitions/RoleParam' - description: Updates for roles and username. - tags: - - Products - responses: - '200': - description: Project role members updated successfully. - '400': - description: Illegal format of provided ID value. - '401': - description: User need to log in first. - '403': - description: User in session does not have permission to the project. - '404': - description: Project ID does not exist. - '500': - description: Unexpected internal errors. - delete: - summary: Delete project role members accompany with relevant project and user. - description: > - This endpoint is aimed to remove project role members already added to - the relevant project and user. - parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID. - - name: user_id - in: path - type: integer - format: int - required: true - description: Relevant user ID. - tags: - - Products - responses: - '200': - description: Project role members deleted successfully. - '400': - description: Illegal format of provided ID value. - '401': - description: User need to log in first. - '403': - description: User in session does not have permission to the project. - '404': - description: Project ID does not exist. - '500': - description: Unexpected internal errors. - '/projects/{project_id}/projectmembers': + '/projects/{project_id}/members': get: summary: Get all project member information description: Get all project member information @@ -691,7 +512,7 @@ paths: description: Project does not exist. '500': description: Unexpected internal errors. - '/projects/{project_id}/projectmembers/{mid}': + '/projects/{project_id}/members/{mid}': get: summary: Get the project member information description: Get the project member information @@ -2492,6 +2313,71 @@ paths: $ref: '#/definitions/UserGroup' '500': description: Unexpected internal errors. + /ldap/users/search: + get: + summary: Search available ldap users. + description: > + This endpoint searches the available ldap users based on related + configuration parameters. Support searched by input ladp configuration, + load configuration from the system and specific filter. + parameters: + - name: username + in: query + type: string + required: false + description: Registered user ID + tags: + - Products + responses: + '200': + description: Search ldap users successfully. + schema: + type: array + items: + $ref: '#/definitions/LdapUsers' + '401': + description: User need to login first. + '403': + description: Only admin has this authority. + '500': + description: Unexpected internal errors. + /ldap/users/import: + post: + summary: Import selected available ldap users. + description: > + This endpoint adds the selected available ldap users to harbor based on + related configuration parameters from the system. System will try to + guess the user email address and realname, add to harbor user + information. + + If have errors when import user, will return the list of importing + failed uid and the failed reason. + parameters: + - name: uid_list + in: body + description: >- + The uid listed for importing. This list will check users validity of + ldap service based on configuration from the system. + required: true + schema: + $ref: '#/definitions/LdapImportUsers' + tags: + - Products + responses: + '200': + description: Add ldap users successfully. + '401': + description: User need to login first. + '403': + description: Only admin has this authority. + '415': + $ref: '#/responses/UnsupportedMediaType' + '404': + description: Failed import some users. + schema: + type: array + items: + $ref: '#/definitions/LdapFailedImportUsers' /usergroups: get: summary: Get all user groups information @@ -2613,71 +2499,7 @@ paths: description: Only admin has this authority. '500': description: Unexpected internal errors. - /ldap/users/search: - get: - summary: Search available ldap users. - description: > - This endpoint searches the available ldap users based on related - configuration parameters. Support searched by input ladp configuration, - load configuration from the system and specific filter. - parameters: - - name: username - in: query - type: string - required: false - description: Registered user ID - tags: - - Products - responses: - '200': - description: Search ldap users successfully. - schema: - type: array - items: - $ref: '#/definitions/LdapUsers' - '401': - description: User need to login first. - '403': - description: Only admin has this authority. - '500': - description: Unexpected internal errors. - /ldap/users/import: - post: - summary: Import selected available ldap users. - description: > - This endpoint adds the selected available ldap users to harbor based on - related configuration parameters from the system. System will try to - guess the user email address and realname, add to harbor user - information. - If have errors when import user, will return the list of importing - failed uid and the failed reason. - parameters: - - name: uid_list - in: body - description: >- - The uid listed for importing. This list will check users validity of - ldap service based on configuration from the system. - required: true - schema: - $ref: '#/definitions/LdapImportUsers' - tags: - - Products - responses: - '200': - description: Add ldap users successfully. - '401': - description: User need to login first. - '403': - description: Only admin has this authority. - '415': - $ref: '#/responses/UnsupportedMediaType' - '404': - description: Failed import some users. - schema: - type: array - items: - $ref: '#/definitions/LdapFailedImportUsers' /configurations: get: summary: Get system configurations. @@ -3799,4 +3621,3 @@ definitions: description: The DN of the LDAP group if group type is 1 (LDAP group). - diff --git a/src/common/dao/dao_test.go b/src/common/dao/dao_test.go index c65900f1b..5b1928e29 100644 --- a/src/common/dao/dao_test.go +++ b/src/common/dao/dao_test.go @@ -635,31 +635,6 @@ func TestGetProjectById(t *testing.T) { } } -func TestGetUserByProject(t *testing.T) { - pid := currentProject.ProjectID - u1 := models.User{ - Username: "Tester", - } - u2 := models.User{ - Username: "nononono", - } - users, err := GetUserByProject(pid, u1) - if err != nil { - t.Errorf("Error happened in GetUserByProject: %v, project Id: %d, user: %+v", err, pid, u1) - } - if len(users) != 1 { - t.Errorf("unexpected length of user list, expected: 1, the users list: %+v", users) - } - users, err = GetUserByProject(pid, u2) - if err != nil { - t.Errorf("Error happened in GetUserByProject: %v, project Id: %d, user: %+v", err, pid, u2) - } - if len(users) != 0 { - t.Errorf("unexpected length of user list, expected: 0, the users list: %+v", users) - } - -} - func TestGetUserProjectRoles(t *testing.T) { r, err := GetUserProjectRoles(currentUser.UserID, currentProject.ProjectID, common.UserMember) if err != nil { @@ -700,68 +675,6 @@ func TestGetProjects(t *testing.T) { } } -func TestAddProjectMember(t *testing.T) { - pmid, err := AddProjectMember(currentProject.ProjectID, 1, models.DEVELOPER, common.UserMember) - if err != nil { - t.Errorf("Error occurred in AddProjectMember: %v", err) - } - if pmid == 0 { - t.Errorf("Error add project member, pmid=0") - } - pmid, err = AddProjectMember(currentProject.ProjectID, 1, models.DEVELOPER, "randomstring") - if err == nil { - t.Errorf("Should failed on adding project member when adding duplicated items") - } - - roles, err := GetUserProjectRoles(1, currentProject.ProjectID, common.UserMember) - if err != nil { - t.Errorf("Error occurred in GetUserProjectRoles: %v", err) - } - - flag := false - for _, role := range roles { - if role.Name == "developer" { - flag = true - break - } - } - - if !flag { - t.Errorf("the user which ID is 1 does not have developer privileges") - } -} - -func TestUpdateProjectMember(t *testing.T) { - err := UpdateProjectMember(currentProject.ProjectID, 1, models.GUEST, "randomstring") - if err != nil { - t.Errorf("Error occurred in UpdateProjectMember: %v", err) - } - roles, err := GetUserProjectRoles(1, currentProject.ProjectID, common.UserMember) - if err != nil { - t.Errorf("Error occurred in GetUserProjectRoles: %v", err) - } - if roles[0].Name != "guest" { - t.Errorf("The user with ID 1 is not guest role after update, the acutal role: %s", roles[0].Name) - } - -} - -func TestDeleteProjectMember(t *testing.T) { - err := DeleteProjectMember(currentProject.ProjectID, 1, "randomstring") - if err != nil { - t.Errorf("Error occurred in DeleteProjectMember: %v", err) - } - - roles, err := GetUserProjectRoles(1, currentProject.ProjectID, common.UserMember) - if err != nil { - t.Errorf("Error occurred in GetUserProjectRoles: %v", err) - } - - if len(roles) != 0 { - t.Errorf("delete record failed from table project_member") - } -} - func TestGetRoleByID(t *testing.T) { r, err := GetRoleByID(models.PROJECTADMIN) if err != nil { diff --git a/src/common/dao/project.go b/src/common/dao/project.go index 9ec0b0361..27307a0e7 100644 --- a/src/common/dao/project.go +++ b/src/common/dao/project.go @@ -17,14 +17,12 @@ package dao import ( "github.com/vmware/harbor/src/common" "github.com/vmware/harbor/src/common/models" + "github.com/vmware/harbor/src/common/utils/log" "fmt" "time" - //"github.com/vmware/harbor/src/common/utils/log" ) -//TODO:transaction, return err - // AddProject adds a project to the database along with project roles information and access log records. func AddProject(project models.Project) (int64, error) { @@ -45,13 +43,47 @@ func AddProject(project models.Project) (int64, error) { return 0, err } - pmID, err := AddProjectMember(projectID, project.OwnerID, models.PROJECTADMIN, common.UserMember) + pmID, err := addProjectMember(models.Member{ + ProjectID: projectID, + EntityID: project.OwnerID, + Role: models.PROJECTADMIN, + EntityType: common.UserMember, + }) + if err != nil { + return 0, err + } if pmID == 0 { return projectID, fmt.Errorf("Failed to add project member, pmid=0") } return projectID, err } +func addProjectMember(member models.Member) (int, error) { + + log.Debugf("Adding project member %+v", member) + + o := GetOrmer() + + if member.EntityID <= 0 { + return 0, fmt.Errorf("Invalid entity_id, member: %+v", member) + } + + if member.ProjectID <= 0 { + return 0, fmt.Errorf("Invalid project_id, member: %+v", member) + } + + sql := "insert into project_member (project_id, entity_id , role, entity_type) values (?, ?, ?, ?)" + r, err := o.Raw(sql, member.ProjectID, member.EntityID, member.Role, member.EntityType).Exec() + if err != nil { + return 0, err + } + pmid, err := r.LastInsertId() + if err != nil { + return 0, err + } + return int(pmid), err +} + // GetProjectByID ... func GetProjectByID(id int64) (*models.Project, error) { o := GetOrmer() diff --git a/src/common/dao/project/projectmember.go b/src/common/dao/project/projectmember.go index ba59a0cfd..91facea00 100644 --- a/src/common/dao/project/projectmember.go +++ b/src/common/dao/project/projectmember.go @@ -74,7 +74,6 @@ func GetProjectMember(queryMember models.Member) ([]*models.Member, error) { func AddProjectMember(member models.Member) (int, error) { log.Debugf("Adding project member %+v", member) - o := dao.GetOrmer() if member.EntityID <= 0 { @@ -85,6 +84,11 @@ func AddProjectMember(member models.Member) (int, error) { return 0, fmt.Errorf("Invalid project_id, member: %+v", member) } + delSQL := "delete from project_member where project_id = ? and entity_id = ? and entity_type = ? " + _, err := o.Raw(delSQL, member.ProjectID, member.EntityID, member.EntityType).Exec() + if err != nil { + return 0, err + } sql := "insert into project_member (project_id, entity_id , role, entity_type) values (?, ?, ?, ?)" r, err := o.Raw(sql, member.ProjectID, member.EntityID, member.Role, member.EntityType).Exec() if err != nil { @@ -99,7 +103,6 @@ func AddProjectMember(member models.Member) (int, error) { // UpdateProjectMemberRole updates the record in table project_member, only role can be changed func UpdateProjectMemberRole(pmID int, role int) error { - o := dao.GetOrmer() sql := "update project_member set role = ? where id = ? " _, err := o.Raw(sql, role, pmID).Exec() diff --git a/src/common/dao/projectmember.go b/src/common/dao/projectmember.go deleted file mode 100644 index 1a8397156..000000000 --- a/src/common/dao/projectmember.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2017 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. - -package dao - -import ( - "github.com/vmware/harbor/src/common" - "github.com/vmware/harbor/src/common/models" -) - -// AddProjectMember inserts a record to table project_member -func AddProjectMember(projectID int64, userID int, role int, entityType string) (int, error) { - o := GetOrmer() - if !(entityType == common.UserMember || entityType == common.GroupMember) { - entityType = common.UserMember - } - sql := `insert into project_member (project_id, entity_id , role, entity_type) values (?, ?, ?, ?)` - _, err := o.Raw(sql, projectID, userID, role, entityType).Exec() - if err != nil { - return 0, err - } - var pmid int - querySQL := `select id from project_member where project_id = ? and entity_id = ? and entity_type = ? limit 1` - - err = o.Raw(querySQL, projectID, userID, entityType).QueryRow(&pmid) - if err != nil { - return 0, err - } - return pmid, err -} - -// UpdateProjectMember updates the record in table project_member -func UpdateProjectMember(projectID int64, userID int, role int, entityType string) error { - o := GetOrmer() - if !(entityType == common.UserMember || entityType == common.GroupMember) { - entityType = common.UserMember - } - - sql := `update project_member set role = ? where project_id = ? and entity_id = ?` - - _, err := o.Raw(sql, role, projectID, userID).Exec() - - return err -} - -// DeleteProjectMember delete the record from table project_member -func DeleteProjectMember(projectID int64, userID int, entityType string) error { - o := GetOrmer() - - if !(entityType == common.UserMember || entityType == common.GroupMember) { - entityType = common.UserMember - } - - sql := `delete from project_member where project_id = ? and entity_id = ? and entity_type = ?` - - if _, err := o.Raw(sql, projectID, userID, entityType).Exec(); err != nil { - return err - } - - return nil -} - -// GetUserByProject gets all members of the project. -func GetUserByProject(projectID int64, queryUser models.User) ([]*models.UserMember, error) { - o := GetOrmer() - sql := `select pm.id as id, u.user_id, u.username, u.creation_time, u.update_time, r.name as rolename, - r.role_id as role, pm.entity_type as entity_type from user u join project_member pm - on pm.project_id = ? and u.user_id = pm.entity_id - join role r on pm.role = r.role_id where u.deleted = 0 and pm.entity_type = 'u' ` - - queryParam := make([]interface{}, 1) - queryParam = append(queryParam, projectID) - - if len(queryUser.Username) != 0 { - sql += ` and u.username like ? ` - queryParam = append(queryParam, `%`+Escape(queryUser.Username)+`%`) - } - sql += ` order by u.username ` - - members := []*models.UserMember{} - _, err := o.Raw(sql, queryParam).QueryRows(&members) - - return members, err -} diff --git a/src/common/security/local/context_test.go b/src/common/security/local/context_test.go index 00f8e1517..d33982e56 100644 --- a/src/common/security/local/context_test.go +++ b/src/common/security/local/context_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" "github.com/vmware/harbor/src/common" "github.com/vmware/harbor/src/common/dao" + "github.com/vmware/harbor/src/common/dao/project" "github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/utils/log" "github.com/vmware/harbor/src/ui/promgr" @@ -122,25 +123,39 @@ func TestMain(m *testing.M) { private.ProjectID = id defer dao.DeleteProject(id) + var projectAdminPMID, developerUserPMID, guestUserPMID int // add project members - _, err = dao.AddProjectMember(private.ProjectID, projectAdminUser.UserID, common.RoleProjectAdmin, common.UserMember) + projectAdminPMID, err = project.AddProjectMember(models.Member{ + ProjectID: private.ProjectID, + EntityID: projectAdminUser.UserID, + EntityType: common.UserMember, + Role: common.RoleProjectAdmin, + }) if err != nil { log.Fatalf("failed to add member: %v", err) } - defer dao.DeleteProjectMember(private.ProjectID, projectAdminUser.UserID, common.UserMember) + defer project.DeleteProjectMemberByID(projectAdminPMID) - _, err = dao.AddProjectMember(private.ProjectID, developerUser.UserID, common.RoleDeveloper, common.UserMember) + developerUserPMID, err = project.AddProjectMember(models.Member{ + ProjectID: private.ProjectID, + EntityID: developerUser.UserID, + EntityType: common.UserMember, + Role: common.RoleDeveloper, + }) if err != nil { log.Fatalf("failed to add member: %v", err) } - defer dao.DeleteProjectMember(private.ProjectID, developerUser.UserID, common.UserMember) - - _, err = dao.AddProjectMember(private.ProjectID, guestUser.UserID, common.RoleGuest, common.UserMember) + defer project.DeleteProjectMemberByID(developerUserPMID) + guestUserPMID, err = project.AddProjectMember(models.Member{ + ProjectID: private.ProjectID, + EntityID: guestUser.UserID, + EntityType: common.UserMember, + Role: common.RoleGuest, + }) if err != nil { log.Fatalf("failed to add member: %v", err) } - defer dao.DeleteProjectMember(private.ProjectID, guestUser.UserID, common.UserMember) - + defer project.DeleteProjectMemberByID(guestUserPMID) os.Exit(m.Run()) } diff --git a/src/ui/api/api_test.go b/src/ui/api/api_test.go index 0dbec6f4e..697a5df37 100644 --- a/src/ui/api/api_test.go +++ b/src/ui/api/api_test.go @@ -31,13 +31,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/vmware/harbor/src/common/dao" + "github.com/vmware/harbor/src/common/dao/project" common_http "github.com/vmware/harbor/src/common/http" "github.com/vmware/harbor/src/common/models" ) var ( - nonSysAdminID, projAdminID, projDeveloperID, projGuestID int - + nonSysAdminID, projAdminID, projDeveloperID, projGuestID int64 + projAdminPMID, projDeveloperPMID, projGuestPMID int // The following users/credentials are registered and assigned roles at the beginning of // running testing and cleaned up at the end. // Do not try to change the system and project roles that the users have during @@ -206,7 +207,8 @@ func TestMain(m *testing.M) { func prepare() error { // register nonSysAdmin - id, err := dao.Register(models.User{ + var err error + nonSysAdminID, err = dao.Register(models.User{ Username: nonSysAdmin.Name, Password: nonSysAdmin.Passwd, Email: nonSysAdmin.Name + "@test.com", @@ -214,10 +216,9 @@ func prepare() error { if err != nil { return err } - nonSysAdminID = int(id) // register projAdmin and assign project admin role - id, err = dao.Register(models.User{ + projAdminID, err = dao.Register(models.User{ Username: projAdmin.Name, Password: projAdmin.Passwd, Email: projAdmin.Name + "@test.com", @@ -225,14 +226,18 @@ func prepare() error { if err != nil { return err } - projAdminID = int(id) - if _, err = dao.AddProjectMember(1, projAdminID, models.PROJECTADMIN, common.UserMember); err != nil { + if projAdminPMID, err = project.AddProjectMember(models.Member{ + ProjectID: 1, + Role: models.PROJECTADMIN, + EntityID: int(projAdminID), + EntityType: common.UserMember, + }); err != nil { return err } // register projDeveloper and assign project developer role - id, err = dao.Register(models.User{ + projDeveloperID, err = dao.Register(models.User{ Username: projDeveloper.Name, Password: projDeveloper.Passwd, Email: projDeveloper.Name + "@test.com", @@ -240,14 +245,18 @@ func prepare() error { if err != nil { return err } - projDeveloperID = int(id) - if _, err = dao.AddProjectMember(1, projDeveloperID, models.DEVELOPER, common.UserMember); err != nil { + if projDeveloperPMID, err = project.AddProjectMember(models.Member{ + ProjectID: 1, + Role: models.DEVELOPER, + EntityID: int(projDeveloperID), + EntityType: common.UserMember, + }); err != nil { return err } // register projGuest and assign project guest role - id, err = dao.Register(models.User{ + projGuestID, err = dao.Register(models.User{ Username: projGuest.Name, Password: projGuest.Passwd, Email: projGuest.Name + "@test.com", @@ -255,23 +264,29 @@ func prepare() error { if err != nil { return err } - projGuestID = int(id) - _, err = dao.AddProjectMember(1, projGuestID, models.GUEST, common.UserMember) + if projGuestPMID, err = project.AddProjectMember(models.Member{ + ProjectID: 1, + Role: models.GUEST, + EntityID: int(projGuestID), + EntityType: common.UserMember, + }); err != nil { + return err + } return err } func clean() { - ids := []int{projAdminID, projDeveloperID, projGuestID} - for _, id := range ids { - if err := dao.DeleteProjectMember(1, id, common.UserMember); err != nil { + pmids := []int{projAdminPMID, projDeveloperPMID, projGuestPMID} + + for _, id := range pmids { + if err := project.DeleteProjectMemberByID(id); err != nil { fmt.Printf("failed to clean up member %d from project library: %v", id, err) } } - - ids = append(ids, nonSysAdminID) - for _, id := range ids { - if err := dao.DeleteUser(id); err != nil { + userids := []int64{nonSysAdminID, projAdminID, projDeveloperID, projGuestID} + for _, id := range userids { + if err := dao.DeleteUser(int(id)); err != nil { fmt.Printf("failed to clean up user %d: %v \n", id, err) } } diff --git a/src/ui/api/harborapi_test.go b/src/ui/api/harborapi_test.go index b22614185..18d806a84 100644 --- a/src/ui/api/harborapi_test.go +++ b/src/ui/api/harborapi_test.go @@ -104,11 +104,10 @@ func init() { beego.Router("/api/users/:id/sysadmin", &UserAPI{}, "put:ToggleUserAdminRole") beego.Router("/api/projects/:id([0-9]+)/logs", &ProjectAPI{}, "get:Logs") beego.Router("/api/projects/:id([0-9]+)/_deletable", &ProjectAPI{}, "get:Deletable") - beego.Router("/api/projects/:pid([0-9]+)/members/?:mid", &ProjectUserMemberAPI{}, "get:Get;post:Post;delete:Delete;put:Put") beego.Router("/api/projects/:id([0-9]+)/metadatas/?:name", &MetadataAPI{}, "get:Get") beego.Router("/api/projects/:id([0-9]+)/metadatas/", &MetadataAPI{}, "post:Post") beego.Router("/api/projects/:id([0-9]+)/metadatas/:name", &MetadataAPI{}, "put:Put;delete:Delete") - beego.Router("/api/projects/:pid([0-9]+)/projectmembers/?:pmid([0-9]+)", &ProjectMemberAPI{}) + beego.Router("/api/projects/:pid([0-9]+)/members/?:pmid([0-9]+)", &ProjectMemberAPI{}) beego.Router("/api/repositories", &RepositoryAPI{}) beego.Router("/api/statistics", &StatisticAPI{}) beego.Router("/api/users/?:id", &UserAPI{}) @@ -440,12 +439,13 @@ func (a testapi) GetProjectMembersByProID(prjUsr usrInfo, projectID string) (int } //Add project role member accompany with projectID -func (a testapi) AddProjectMember(prjUsr usrInfo, projectID string, roles apilib.RoleParam) (int, error) { +//func (a testapi) AddProjectMember(prjUsr usrInfo, projectID string, roles apilib.RoleParam) (int, error) { +func (a testapi) AddProjectMember(prjUsr usrInfo, projectID string, member *models.MemberReq) (int, error) { _sling := sling.New().Post(a.basePath) path := "/api/projects/" + projectID + "/members/" _sling = _sling.Path(path) - _sling = _sling.BodyJSON(roles) + _sling = _sling.BodyJSON(member) httpStatusCode, _, err := request(_sling, jsonAcceptHeader, prjUsr) return httpStatusCode, err diff --git a/src/ui/api/member.go b/src/ui/api/member.go deleted file mode 100644 index e4855f72f..000000000 --- a/src/ui/api/member.go +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright (c) 2017 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. - -package api - -import ( - "fmt" - "net/http" - "strings" - - "github.com/vmware/harbor/src/common" - - "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" -) - -// ProjectUserMemberAPI handles request to /api/projects/{}/members/{} -type ProjectUserMemberAPI struct { - BaseController - memberID int - currentUserID int - project *models.Project -} - -type memberReq struct { - Username string `json:"username"` - UserID int `json:"user_id"` - Roles []int `json:"roles"` -} - -// Prepare validates the URL and parms -func (pma *ProjectUserMemberAPI) Prepare() { - pma.BaseController.Prepare() - - if !pma.SecurityCtx.IsAuthenticated() { - pma.HandleUnauthorized() - return - } - user, err := dao.GetUser(models.User{ - Username: pma.SecurityCtx.GetUsername(), - }) - if err != nil { - pma.HandleInternalServerError( - fmt.Sprintf("failed to get user %s: %v", - pma.SecurityCtx.GetUsername(), err)) - return - } - pma.currentUserID = user.UserID - - pid, err := pma.GetInt64FromPath(":pid") - if err != nil || pid <= 0 { - text := "invalid project ID: " - if err != nil { - text += err.Error() - } else { - text += fmt.Sprintf("%d", pid) - } - pma.HandleBadRequest(text) - return - } - project, err := pma.ProjectMgr.Get(pid) - if err != nil { - pma.ParseAndHandleError(fmt.Sprintf("failed to get project %d", pid), err) - return - } - if project == nil { - pma.HandleNotFound(fmt.Sprintf("project %d not found", pid)) - return - } - pma.project = project - - if !(pma.Ctx.Input.IsGet() && pma.SecurityCtx.HasReadPerm(pid) || - pma.SecurityCtx.HasAllPerm(pid)) { - pma.HandleForbidden(pma.SecurityCtx.GetUsername()) - return - } - - if len(pma.GetStringFromPath(":mid")) != 0 { - mid, err := pma.GetInt64FromPath(":mid") - if err != nil || mid <= 0 { - text := "invalid member ID: " - if err != nil { - text += err.Error() - } else { - text += fmt.Sprintf("%d", mid) - } - pma.HandleBadRequest(text) - return - } - - member, err := dao.GetUser(models.User{ - UserID: int(mid), - }) - if err != nil { - pma.HandleInternalServerError(fmt.Sprintf("failed to get user %d: %v", mid, err)) - return - } - if member == nil { - pma.HandleNotFound(fmt.Sprintf("member %d not found", mid)) - return - } - - pma.memberID = member.UserID - } -} - -// Get ... -func (pma *ProjectUserMemberAPI) Get() { - pid := pma.project.ProjectID - if pma.memberID == 0 { //member id not set return list of the members - username := pma.GetString("username") - queryUser := models.User{Username: username} - userList, err := dao.GetUserByProject(pid, queryUser) - if err != nil { - log.Errorf("Failed to query database for member list, error: %v", err) - pma.RenderError(http.StatusInternalServerError, "Internal Server Error") - return - } - pma.Data["json"] = userList - } else { //return detail of a member - roleList, err := listRoles(pma.memberID, pid, common.UserMember) - if err != nil { - 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}) - if err != nil { - log.Errorf("Error occurred in GetUser, error: %v", err) - pma.CustomAbort(http.StatusInternalServerError, "Internal error.") - } - result["username"] = user.Username - result["user_id"] = pma.memberID - result["roles"] = roleList - pma.Data["json"] = result - } - pma.ServeJSON() -} - -// Post ... -func (pma *ProjectUserMemberAPI) Post() { - projectID := pma.project.ProjectID - - var req memberReq - pma.DecodeJSONReq(&req) - username := strings.TrimSpace(req.Username) - userID := checkUserExists(username) - if userID <= 0 { - - user, err := auth.SearchUser(username) - - if err != nil { - log.Errorf("Failed the search user, error: %v", err) - pma.RenderError(http.StatusInternalServerError, "Failed to search user") - return - } - - if user == nil { - log.Errorf("Current user doesn't exist: %v", username) - pma.RenderError(http.StatusNotFound, "Failed to search user: "+username) - return - } - - err = auth.OnBoardUser(user) - - if err != nil { - log.Errorf("Failed the onboard user, error: %s", err) - pma.RenderError(http.StatusInternalServerError, "Failed to onboard user") - return - } - if user.UserID <= 0 { - log.Error("Failed the onboard user, UserId <=0") - pma.RenderError(http.StatusInternalServerError, "Failed to onboard user") - return - } - userID = user.UserID - - } - rolelist, err := dao.GetUserProjectRoles(userID, projectID, common.UserMember) - if err != nil { - log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err) - pma.CustomAbort(http.StatusInternalServerError, "Internal error.") - } - if len(rolelist) > 0 { - log.Warningf("user is already added to project, user id: %d, project id: %d", userID, projectID) - pma.RenderError(http.StatusConflict, "user is ready in project") - return - } - - if len(req.Roles) <= 0 || len(req.Roles) > 1 { - pma.CustomAbort(http.StatusBadRequest, "only one role is supported") - } - - rid := req.Roles[0] - if !(rid == models.PROJECTADMIN || - rid == models.DEVELOPER || - rid == models.GUEST) { - pma.CustomAbort(http.StatusBadRequest, "invalid role") - } - - _, err = dao.AddProjectMember(projectID, userID, rid, common.UserMember) - if err != nil { - log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", projectID, userID, rid) - pma.RenderError(http.StatusInternalServerError, "Failed to update data in database") - return - } -} - -// Put ... -func (pma *ProjectUserMemberAPI) Put() { - pid := pma.project.ProjectID - mid := pma.memberID - - var req memberReq - pma.DecodeJSONReq(&req) - roleList, err := dao.GetUserProjectRoles(mid, pid, common.UserMember) - if len(roleList) == 0 { - log.Warningf("User is not in project, user id: %d, project id: %d", mid, pid) - pma.RenderError(http.StatusNotFound, "user not exist in project") - return - } - //TODO: delete and insert should in one transaction - //delete user project role record for the given user - err = dao.DeleteProjectMember(pid, mid, common.UserMember) - if err != nil { - log.Errorf("Failed to delete project roles for user, user id: %d, project id: %d, error: %v", mid, pid, err) - pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB") - return - } - //insert roles in request - for _, rid := range req.Roles { - _, err = dao.AddProjectMember(pid, mid, int(rid), common.UserMember) - if err != nil { - log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", pid, mid, rid) - pma.RenderError(http.StatusInternalServerError, "Failed to update data in database") - return - } - } -} - -// Delete ... -func (pma *ProjectUserMemberAPI) Delete() { - pid := pma.project.ProjectID - mid := pma.memberID - - err := dao.DeleteProjectMember(pid, mid, common.UserMember) - if err != nil { - log.Errorf("Failed to delete project roles for user, user id: %d, project id: %d, error: %v", mid, pid, err) - pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB") - return - } -} diff --git a/src/ui/api/member_test.go b/src/ui/api/member_test.go deleted file mode 100644 index 82e6bd000..000000000 --- a/src/ui/api/member_test.go +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2017 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. -package api - -import ( - "fmt" - "testing" - - "strconv" - - "github.com/stretchr/testify/assert" - "github.com/vmware/harbor/tests/apitests/apilib" -) - -func TestMemGet(t *testing.T) { - var result []apilib.User - var httpStatusCode int - var err error - - assert := assert.New(t) - apiTest := newHarborAPI() - projectID := "1" - - fmt.Println("Testing Member Get API") - //-------------------case 1 : response code = 200------------------------// - httpStatusCode, result, err = apiTest.GetProjectMembersByProID(*admin, projectID) - if err != nil { - t.Error("Error whihle get members by projectID", err.Error()) - t.Log(err) - } else { - assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200") - assert.Equal("proj_admin", result[0].Username, "User name should be proj_admin") - } - - //---------case 2: Response Code=401,User need to log in first.----------// - fmt.Println("case 2: Response Code=401,User need to log in first.") - httpStatusCode, result, err = apiTest.GetProjectMembersByProID(*unknownUsr, projectID) - if err != nil { - t.Error("Error while get members by projectID", err.Error()) - t.Log(err) - } else { - assert.Equal(int(401), httpStatusCode, "Case 2: Project creation status should be 401") - } - - //------------case 3: Response Code=404,Project does not exist-----------// - fmt.Println("case 3: Response Code=404,Project does not exist") - projectID = "11" - httpStatusCode, result, err = apiTest.GetProjectMembersByProID(*admin, projectID) - if err != nil { - t.Error("Error while get members by projectID", err.Error()) - t.Log(err) - } else { - assert.Equal(int(404), httpStatusCode, "Case 3: Project creation status should be 404") - } - - //------------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") -} - -/** - * Add project role member accompany with projectID - * role_id = 1 : ProjectAdmin - * role_id = 2 : Developer - * role_id = 3 : Guest - */ - -func TestMemPost(t *testing.T) { - var httpStatusCode int - var err error - - assert := assert.New(t) - apiTest := newHarborAPI() - projectID := "1" - CommonAddUser() - roles := &apilib.RoleParam{[]int32{1}, TestUserName} - fmt.Printf("Add User \"%s\" successfully!\n", TestUserName) - - fmt.Println("Testing Member Post API") - //-------------------case 1 : response code = 200------------------------// - fmt.Println("case 1: response code = 200") - 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") - } - - //---------case 2: Response Code=409,User is ready in project.----------// - fmt.Println("case 2: Response Code=409,User is ready in project.") - httpStatusCode, err = apiTest.AddProjectMember(*admin, projectID, *roles) - if err != nil { - t.Error("Error while add project role member", err.Error()) - t.Log(err) - } else { - assert.Equal(int(409), httpStatusCode, "Case 2: httpStatusCode should be 409") - } - - //---------case 3: Response Code=404,User does not exist.----------// - fmt.Println("case 3: Response Code=404,User does not exist.") - - errorRoles := &apilib.RoleParam{[]int32{1}, "T"} - httpStatusCode, err = apiTest.AddProjectMember(*admin, projectID, *errorRoles) - if err != nil { - t.Error("Error while add project role member", err.Error()) - t.Log(err) - } else { - assert.Equal(int(404), httpStatusCode, "Case 3: httpStatusCode status should be 404") - } - /* - //---------case 4: Response Code=403,User in session does not have permission to the project..----------// - fmt.Println("case 4:User in session does not have permission to the project.") - - httpStatusCode, err = apiTest.AddProjectMember(*testUser, projectID, *roles) - if err != nil { - t.Error("Error while add project role member", err.Error()) - t.Log(err) - } else { - assert.Equal(int(403), httpStatusCode, "Case 3: httpStatusCode status should be 403") - } - - */ -} - -func TestGetMemByPIDUID(t *testing.T) { - var httpStatusCode int - var err error - - assert := assert.New(t) - apiTest := newHarborAPI() - projectID := "1" - userID := strconv.Itoa(CommonGetUserID()) - fmt.Println("Testing Member Get API by PID and UID") - //-------------------case 1 : response code = 200------------------------// - fmt.Println("case 1: response code = 200") - httpStatusCode, err = apiTest.GetMemByPIDUID(*admin, projectID, userID) - if err != nil { - t.Error("Error whihle get project role member", err.Error()) - t.Log(err) - } else { - assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200") - } - -} - -func TestPutMem(t *testing.T) { - var httpStatusCode int - var err error - - assert := assert.New(t) - apiTest := newHarborAPI() - projectID := "1" - userID := strconv.Itoa(CommonGetUserID()) - - roles := &apilib.RoleParam{[]int32{3}, TestUserName} - fmt.Println("Testing Member Put API") - //-------------------case 1 : response code = 200------------------------// - fmt.Println("case 1: response code = 200") - httpStatusCode, err = apiTest.PutProjectMember(*admin, projectID, userID, *roles) - if err != nil { - t.Error("Error whihle put project role member", err.Error()) - t.Log(err) - } else { - assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200") - } - -} - -func TestDeleteMemUser(t *testing.T) { - var httpStatusCode int - var err error - - assert := assert.New(t) - apiTest := newHarborAPI() - projectID := "1" - - fmt.Println("Testing Member Delete API") - //-------------------case 1 : response code = 200------------------------// - fmt.Println("case 1: response code = 200") - - 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() -} diff --git a/src/ui/api/project_test.go b/src/ui/api/project_test.go index 49f3e0d87..f2ef7a7d5 100644 --- a/src/ui/api/project_test.go +++ b/src/ui/api/project_test.go @@ -136,14 +136,19 @@ func TestListProjects(t *testing.T) { //-------------------case 4 : add project member and check his role ------------------------// CommonAddUser() - roles := &apilib.RoleParam{[]int32{2}, TestUserName} + member := &models.MemberReq{ + Role: 2, + MemberUser: models.User{ + Username: TestUserName, + }, + } projectID := strconv.Itoa(addPID) - httpStatusCode, err = apiTest.AddProjectMember(*admin, projectID, *roles) + httpStatusCode, err = apiTest.AddProjectMember(*admin, projectID, member) 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") + assert.Equal(int(201), httpStatusCode, "httpStatusCode should be 201") } httpStatusCode, result, err = apiTest.ProjectsGet( &apilib.ProjectQuery{ diff --git a/src/ui/api/projectmember_test.go b/src/ui/api/projectmember_test.go index 3b72d5a24..6f912b413 100644 --- a/src/ui/api/projectmember_test.go +++ b/src/ui/api/projectmember_test.go @@ -30,7 +30,7 @@ func TestProjectMemberAPI_Get(t *testing.T) { &codeCheckingCase{ request: &testingRequest{ method: http.MethodGet, - url: "/api/projects/1/projectmembers", + url: "/api/projects/1/members", }, code: http.StatusUnauthorized, }, @@ -38,7 +38,7 @@ func TestProjectMemberAPI_Get(t *testing.T) { &codeCheckingCase{ request: &testingRequest{ method: http.MethodGet, - url: "/api/projects/1/projectmembers", + url: "/api/projects/1/members", credential: admin, }, code: http.StatusOK, @@ -47,7 +47,7 @@ func TestProjectMemberAPI_Get(t *testing.T) { &codeCheckingCase{ request: &testingRequest{ method: http.MethodGet, - url: "/api/projects/0/projectmembers", + url: "/api/projects/0/members", credential: admin, }, code: http.StatusBadRequest, @@ -56,7 +56,7 @@ func TestProjectMemberAPI_Get(t *testing.T) { &codeCheckingCase{ request: &testingRequest{ method: http.MethodGet, - url: "/api/projects/1/projectmembers/121", + url: "/api/projects/1/members/121", credential: admin, }, code: http.StatusNotFound, @@ -81,7 +81,7 @@ func TestProjectMemberAPI_Post(t *testing.T) { &codeCheckingCase{ request: &testingRequest{ method: http.MethodPost, - url: "/api/projects/1/projectmembers", + url: "/api/projects/1/members", bodyJSON: &models.MemberReq{ Role: 1, MemberUser: models.User{ @@ -94,7 +94,7 @@ func TestProjectMemberAPI_Post(t *testing.T) { &codeCheckingCase{ request: &testingRequest{ method: http.MethodPost, - url: "/api/projects/1/projectmembers", + url: "/api/projects/1/members", bodyJSON: &models.MemberReq{ Role: 1, MemberUser: models.User{ @@ -108,7 +108,7 @@ func TestProjectMemberAPI_Post(t *testing.T) { &codeCheckingCase{ request: &testingRequest{ method: http.MethodPost, - url: "/api/projects/1/projectmembers", + url: "/api/projects/1/members", bodyJSON: &models.MemberReq{ Role: 1, MemberUser: models.User{ @@ -144,8 +144,8 @@ func TestProjectMemberAPI_PutAndDelete(t *testing.T) { if err != nil { t.Errorf("Error occurred when add project member: %v", err) } - URL := fmt.Sprintf("/api/projects/1/projectmembers/%v", ID) - badURL := fmt.Sprintf("/api/projects/1/projectmembers/%v", 0) + URL := fmt.Sprintf("/api/projects/1/members/%v", ID) + badURL := fmt.Sprintf("/api/projects/1/members/%v", 0) cases := []*codeCheckingCase{ // 401 &codeCheckingCase{ diff --git a/src/ui/api/replication_policy_test.go b/src/ui/api/replication_policy_test.go index 74dd73069..ab3bf3d98 100644 --- a/src/ui/api/replication_policy_test.go +++ b/src/ui/api/replication_policy_test.go @@ -19,6 +19,8 @@ import ( "net/http/httptest" "testing" + "github.com/vmware/harbor/src/common/dao/project" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/vmware/harbor/src/common" @@ -314,17 +316,21 @@ func TestRepPolicyAPIList(t *testing.T) { Password: "ProjectDev", Email: "project_dev@test.com", } - + var proAdminPMID, proDevPMID int proAdminID, err := dao.Register(projectAdmin) if err != nil { panic(err) } defer dao.DeleteUser(int(proAdminID)) - - if _, err = dao.AddProjectMember(1, int(proAdminID), models.PROJECTADMIN, common.UserMember); err != nil { + if proAdminPMID, err = project.AddProjectMember(models.Member{ + ProjectID: 1, + Role: models.PROJECTADMIN, + EntityID: int(proAdminID), + EntityType: common.UserMember, + }); err != nil { panic(err) } - defer dao.DeleteProjectMember(1, int(proAdminID), common.UserMember) + defer project.DeleteProjectMemberByID(proAdminPMID) proDevID, err := dao.Register(projectDev) if err != nil { @@ -332,10 +338,15 @@ func TestRepPolicyAPIList(t *testing.T) { } defer dao.DeleteUser(int(proDevID)) - if _, err = dao.AddProjectMember(1, int(proDevID), models.DEVELOPER, common.UserMember); err != nil { + if proDevPMID, err = project.AddProjectMember(models.Member{ + ProjectID: 1, + Role: models.DEVELOPER, + EntityID: int(proDevID), + EntityType: common.UserMember, + }); err != nil { panic(err) } - defer dao.DeleteProjectMember(1, int(proDevID), common.UserMember) + defer project.DeleteProjectMemberByID(proDevPMID) // 400: invalid project ID runCodeCheckingCases(t, &codeCheckingCase{ diff --git a/src/ui/api/repository_test.go b/src/ui/api/repository_test.go index c0efc2c6c..292a8f21b 100644 --- a/src/ui/api/repository_test.go +++ b/src/ui/api/repository_test.go @@ -20,6 +20,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/vmware/harbor/src/common/dao" + "github.com/vmware/harbor/src/common/dao/project" + "github.com/vmware/harbor/src/common/models" ) func TestGetRepos(t *testing.T) { @@ -226,6 +229,24 @@ func TestPopulateAuthor(t *testing.T) { } func TestPutOfRepository(t *testing.T) { + u, err := dao.GetUser(models.User{ + Username: projAdmin.Name, + }) + if err != nil { + t.Errorf("Error occurred when Register user: %v", err) + } + pmid, err := project.AddProjectMember( + models.Member{ + ProjectID: 1, + Role: 1, + EntityID: int(u.UserID), + EntityType: "u"}, + ) + if err != nil { + t.Errorf("Error occurred when add project member: %v", err) + } + defer project.DeleteProjectMemberByID(pmid) + base := "/api/repositories/" desc := struct { Description string `json:"description"` @@ -307,7 +328,7 @@ func TestPutOfRepository(t *testing.T) { // verify that the description is changed repositories := []*repoResp{} - err := handleAndParse(&testingRequest{ + err = handleAndParse(&testingRequest{ method: http.MethodGet, url: base, queryStruct: struct { diff --git a/src/ui/api/utils.go b/src/ui/api/utils.go index 26cae3564..94b1a54a3 100644 --- a/src/ui/api/utils.go +++ b/src/ui/api/utils.go @@ -35,45 +35,6 @@ import ( uiutils "github.com/vmware/harbor/src/ui/utils" ) -//sysadmin has all privileges to all projects -func listRoles(userID int, projectID int64, entityType string) ([]models.Role, error) { - roles := make([]models.Role, 0, 1) - isSysAdmin, err := dao.IsAdminRole(userID) - if err != nil { - log.Errorf("failed to determine whether the user %d is system admin: %v", userID, err) - return roles, err - } - if isSysAdmin { - role, err := dao.GetRoleByID(models.PROJECTADMIN) - if err != nil { - log.Errorf("failed to get role %d: %v", models.PROJECTADMIN, err) - return roles, err - } - roles = append(roles, *role) - return roles, nil - } - - rs, err := dao.GetUserProjectRoles(userID, projectID, entityType) - if err != nil { - log.Errorf("failed to get user %d 's roles for project %d: %v", userID, projectID, err) - return roles, err - } - roles = append(roles, rs...) - return roles, nil -} - -func checkUserExists(name string) int { - u, err := dao.GetUser(models.User{Username: name}) - if err != nil { - log.Errorf("Error occurred in GetUser, error: %v", err) - return 0 - } - if u != nil { - return u.UserID - } - return 0 -} - // SyncRegistry syncs the repositories of registry with database. func SyncRegistry(pm promgr.ProjectManager) error { diff --git a/src/ui/auth/db/db.go b/src/ui/auth/db/db.go index a4cd0be55..8000cb8be 100644 --- a/src/ui/auth/db/db.go +++ b/src/ui/auth/db/db.go @@ -46,6 +46,11 @@ func (d *Auth) SearchUser(username string) (*models.User, error) { return dao.GetUser(queryCondition) } +// OnBoardUser - +func (d *Auth) OnBoardUser(u *models.User) error { + return nil +} + func init() { auth.Register("db_auth", &Auth{}) } diff --git a/src/ui/router.go b/src/ui/router.go index 5f9be6ed3..9b297b553 100644 --- a/src/ui/router.go +++ b/src/ui/router.go @@ -46,8 +46,7 @@ func initRouters() { beego.Router("/sendEmail", &controllers.CommonController{}, "get:SendResetEmail") //API: - beego.Router("/api/projects/:pid([0-9]+)/members/?:mid", &api.ProjectUserMemberAPI{}) - beego.Router("/api/projects/:pid([0-9]+)/projectmembers/?:pmid([0-9]+)", &api.ProjectMemberAPI{}) + beego.Router("/api/projects/:pid([0-9]+)/members/?:pmid([0-9]+)", &api.ProjectMemberAPI{}) beego.Router("/api/projects/", &api.ProjectAPI{}, "head:Head") beego.Router("/api/projects/:id([0-9]+)", &api.ProjectAPI{}) diff --git a/src/ui_ng/lib/src/confirmation-dialog/confirmation-dialog.component.ts b/src/ui_ng/lib/src/confirmation-dialog/confirmation-dialog.component.ts index 21d9571c9..6f03044f1 100644 --- a/src/ui_ng/lib/src/confirmation-dialog/confirmation-dialog.component.ts +++ b/src/ui_ng/lib/src/confirmation-dialog/confirmation-dialog.component.ts @@ -99,7 +99,7 @@ export class ConfirmationDialogComponent { } operate(): void { - if (!this.message){//Inproper condition + if (!this.message) {// Inproper condition this.close(); return; } @@ -120,7 +120,7 @@ export class ConfirmationDialogComponent { } confirm(): void { - if (!this.message){//Inproper condition + if (!this.message) {// Inproper condition this.close(); return; } diff --git a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts index ad8f33677..e5e49a266 100644 --- a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts +++ b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts @@ -54,7 +54,7 @@ import {Observable} from "rxjs/Observable"; }) export class ListReplicationRuleComponent implements OnInit, OnChanges { - nullTime: string = '0001-01-01T00:00:00Z'; + nullTime = '0001-01-01T00:00:00Z'; @Input() projectId: number; @Input() isSystemAdmin: boolean; @@ -72,7 +72,7 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges { @Output() openNewRule = new EventEmitter(); @Output() replicateManual = new EventEmitter(); - projectScope: boolean = false; + projectScope = false; rules: ReplicationRule[]; changedRules: ReplicationRule[]; @@ -108,7 +108,7 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges { } ngOnInit(): void { - //Global scope + // Global scope if (!this.projectScope) { this.retrieveRules(); } @@ -120,15 +120,15 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges { if (proIdChange.currentValue !== proIdChange.previousValue) { if (proIdChange.currentValue) { this.projectId = proIdChange.currentValue; - this.projectScope = true; //Scope is project, not global list - //Initially load the replication rule data + this.projectScope = true; // Scope is project, not global list + // Initially load the replication rule data this.retrieveRules(); } } } } - retrieveRules(ruleName: string = ''): void { + retrieveRules(ruleName = ''): void { this.loading = true; /*this.selectedRow = null;*/ toPromise(this.replicationService @@ -184,7 +184,7 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges { jobList(id: string | number): Promise { let ruleData: ReplicationJobItem[]; this.canDeleteRule = true; - let count: number = 0; + let count = 0; return toPromise(this.replicationService .getJobs(id)) .then(response => { diff --git a/src/ui_ng/lib/src/log/recent-log.component.spec.ts b/src/ui_ng/lib/src/log/recent-log.component.spec.ts index 6ca327c88..ed6851fa5 100644 --- a/src/ui_ng/lib/src/log/recent-log.component.spec.ts +++ b/src/ui_ng/lib/src/log/recent-log.component.spec.ts @@ -58,7 +58,7 @@ describe('RecentLogComponent (inline template)', () => { serviceConfig = TestBed.get(SERVICE_CONFIG); logService = fixture.debugElement.injector.get(AccessLogService); - //Mock data + // Mock data for (let i = 0; i < 18; i++) { let item: AccessLogItem = { log_id: 23 + i, @@ -80,7 +80,7 @@ describe('RecentLogComponent (inline template)', () => { if (params && params.get('repository')) { return Promise.resolve(mockData2); } else { - if (params.get('page') == '1') { + if (params.get('page') === '1') { mockData.data = mockItems.slice(0, 15); } else { mockData.data = mockItems.slice(15, 18) @@ -205,7 +205,7 @@ describe('RecentLogComponent (inline template)', () => { fixture.whenStable().then(() => { fixture.detectChanges(); - let els: HTMLElement[] = fixture.nativeElement.querySelectorAll('.datagrid-row'); + els = fixture.nativeElement.querySelectorAll('.datagrid-row'); expect(els).toBeTruthy(); expect(els.length).toEqual(16); }); diff --git a/src/ui_ng/lib/src/service/system-info.service.ts b/src/ui_ng/lib/src/service/system-info.service.ts index 9e60dfd47..a4e30585c 100644 --- a/src/ui_ng/lib/src/service/system-info.service.ts +++ b/src/ui_ng/lib/src/service/system-info.service.ts @@ -13,7 +13,7 @@ export abstract class SystemInfoService { /** * Get global system information. * @abstract - * @returns + * @returns */ abstract getSystemInfo(): Observable | Promise | SystemInfo; } @@ -23,14 +23,14 @@ export class SystemInfoDefaultService extends SystemInfoService { constructor( @Inject(SERVICE_CONFIG) private config: IServiceConfig, private http: Http) { - super(); + super(); } getSystemInfo(): Observable | Promise | SystemInfo { let url = this.config.systemInfoEndpoint ? this.config.systemInfoEndpoint : '/api/systeminfo'; return this.http.get(url, HTTP_GET_OPTIONS) .toPromise() - .then(systemInfo=>systemInfo.json() as SystemInfo) - .catch(error=>Promise.reject(error)); + .then(systemInfo => systemInfo.json() as SystemInfo) + .catch(error => Promise.reject(error)); } } diff --git a/src/ui_ng/src/app/project/member/add-member/add-member.component.html b/src/ui_ng/src/app/project/member/add-member/add-member.component.html index c754a366b..6cb1cdac9 100644 --- a/src/ui_ng/src/app/project/member/add-member/add-member.component.html +++ b/src/ui_ng/src/app/project/member/add-member/add-member.component.html @@ -8,7 +8,7 @@