From 7e57c685ac0f0543b15577d1361716413765ad11 Mon Sep 17 00:00:00 2001 From: stonezdj Date: Mon, 16 Apr 2018 18:03:57 +0800 Subject: [PATCH] Add project member search by name Previous implementation contains the search user by name feature. This implementation can search user and user group by name. --- docs/swagger.yaml | 4 +++ src/common/dao/project/projectmember.go | 30 ++++++++++++++++ src/common/dao/project/projectmember_test.go | 36 ++++++++++++++++++++ src/ui/api/ldap.go | 2 +- src/ui/api/projectmember.go | 7 ++-- src/ui/api/projectmember_test.go | 25 ++++++++++++++ 6 files changed, 100 insertions(+), 4 deletions(-) diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 7a52174ea..f2a002a52 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -459,6 +459,10 @@ paths: format: int64 required: true description: Relevant project ID. + - name: entityname + in: query + type: string + description: The entity name to search. tags: - Products responses: diff --git a/src/common/dao/project/projectmember.go b/src/common/dao/project/projectmember.go index 91facea00..d78aecd17 100644 --- a/src/common/dao/project/projectmember.go +++ b/src/common/dao/project/projectmember.go @@ -118,3 +118,33 @@ func DeleteProjectMemberByID(pmid int) error { } return nil } + +// SearchMemberByName search members of the project by entity_name +func SearchMemberByName(projectID int64, entityName string) ([]*models.Member, error) { + o := dao.GetOrmer() + sql := `(select pm.id, pm.project_id, + u.username as entity_name, + r.name as rolename, + pm.role, pm.entity_id, pm.entity_type + from project_member pm + left join user u on pm.entity_id = u.user_id and pm.entity_type = 'u' + left join role r on pm.role = r.role_id + where u.deleted = 0 and pm.project_id = ? and u.username like ? order by entity_name ) + union + (select pm.id, pm.project_id, + ug.group_name as entity_name, + r.name as rolename, + pm.role, pm.entity_id, pm.entity_type + from project_member pm + left join user_group ug on pm.entity_id = ug.id and pm.entity_type = 'g' + left join role r on pm.role = r.role_id + where pm.project_id = ? and ug.group_name like ? order by entity_name ) ` + queryParam := make([]interface{}, 4) + queryParam = append(queryParam, projectID) + queryParam = append(queryParam, "%"+dao.Escape(entityName)+"%") + queryParam = append(queryParam, projectID) + queryParam = append(queryParam, "%"+dao.Escape(entityName)+"%") + members := []*models.Member{} + _, err := o.Raw(sql, queryParam).QueryRows(&members) + return members, err +} diff --git a/src/common/dao/project/projectmember_test.go b/src/common/dao/project/projectmember_test.go index 16f0e89c5..bf918b9de 100644 --- a/src/common/dao/project/projectmember_test.go +++ b/src/common/dao/project/projectmember_test.go @@ -149,6 +149,25 @@ func TestAddProjectMember(t *testing.T) { if len(memberList) == 0 { t.Errorf("Failed to query project member, %v", queryMember) } + + _, err = AddProjectMember(models.Member{ + ProjectID: -1, + EntityID: 1, + EntityType: common.UserMember, + Role: models.PROJECTADMIN, + }) + if err == nil { + t.Fatal("Should failed with negative projectID") + } + _, err = AddProjectMember(models.Member{ + ProjectID: 1, + EntityID: -1, + EntityType: common.UserMember, + Role: models.PROJECTADMIN, + }) + if err == nil { + t.Fatal("Should failed with negative entityID") + } } func TestUpdateProjectMemberRole(t *testing.T) { currentProject, err := dao.GetProjectByName("member_test_01") @@ -195,6 +214,23 @@ func TestUpdateProjectMemberRole(t *testing.T) { t.Errorf("member doesn't match!") } + memberList2, err := SearchMemberByName(currentProject.ProjectID, "pm_sample") + if err != nil { + t.Errorf("Error occurred when SearchMemberByName: %v", err) + } + if len(memberList2) == 0 { + t.Errorf("Failed to search user pm_sample, project_id:%v, entityname:%v", + currentProject.ProjectID, "pm_sample") + } + + memberList3, err := SearchMemberByName(currentProject.ProjectID, "") + if err != nil { + t.Errorf("Error occurred when SearchMemberByName: %v", err) + } + if len(memberList3) == 0 { + t.Errorf("Failed to search user pm_sample, project_id:%v, entityname is empty", + currentProject.ProjectID) + } } func TestGetProjectMember(t *testing.T) { diff --git a/src/ui/api/ldap.go b/src/ui/api/ldap.go index bc4c572cd..29cae8823 100644 --- a/src/ui/api/ldap.go +++ b/src/ui/api/ldap.go @@ -118,7 +118,7 @@ func (l *LdapAPI) ImportUser() { } if len(ldapFailedImportUsers) > 0 { - l.HandleNotFound("Import LDAP user have internal error") + l.HandleNotFound("Import LDAP user is not found") l.Data["json"] = ldapFailedImportUsers l.ServeJSON() return diff --git a/src/ui/api/projectmember.go b/src/ui/api/projectmember.go index fd3813699..102ce2811 100644 --- a/src/ui/api/projectmember.go +++ b/src/ui/api/projectmember.go @@ -73,7 +73,7 @@ func (pma *ProjectMemberAPI) Prepare() { pmid, err := pma.GetInt64FromPath(":pmid") if err != nil { - log.Errorf("Failed to get pmid from path, error %v", err) + log.Warningf("Failed to get pmid from path, error %v", err) } if pmid <= 0 && (pma.Ctx.Input.IsPut() || pma.Ctx.Input.IsDelete()) { pma.HandleBadRequest(fmt.Sprintf("The project member id is invalid, pmid:%s", pma.GetStringFromPath(":pmid"))) @@ -89,8 +89,8 @@ func (pma *ProjectMemberAPI) Get() { queryMember.ProjectID = projectID pma.Data["json"] = make([]models.Member, 0) if pma.id == 0 { - //member id not set, return all member of current project - memberList, err := project.GetProjectMember(queryMember) + entityname := pma.GetString("entityname") + memberList, err := project.SearchMemberByName(projectID, entityname) if err != nil { pma.HandleInternalServerError(fmt.Sprintf("Failed to query database for member list, error: %v", err)) return @@ -98,6 +98,7 @@ func (pma *ProjectMemberAPI) Get() { if len(memberList) > 0 { pma.Data["json"] = memberList } + } else { //return a specific member queryMember.ID = pma.id diff --git a/src/ui/api/projectmember_test.go b/src/ui/api/projectmember_test.go index 6f912b413..49b15e2b1 100644 --- a/src/ui/api/projectmember_test.go +++ b/src/ui/api/projectmember_test.go @@ -61,6 +61,15 @@ func TestProjectMemberAPI_Get(t *testing.T) { }, code: http.StatusNotFound, }, + // 404 + &codeCheckingCase{ + request: &testingRequest{ + method: http.MethodGet, + url: "/api/projects/99999/members/121", + credential: admin, + }, + code: http.StatusNotFound, + }, } runCodeCheckingCases(t, cases...) } @@ -119,6 +128,22 @@ func TestProjectMemberAPI_Post(t *testing.T) { }, code: http.StatusInternalServerError, }, + &codeCheckingCase{ + request: &testingRequest{ + method: http.MethodGet, + url: "/api/projects/1/members?entityname=restuser", + credential: admin, + }, + code: http.StatusOK, + }, + &codeCheckingCase{ + request: &testingRequest{ + method: http.MethodGet, + url: "/api/projects/1/members", + credential: admin, + }, + code: http.StatusOK, + }, } runCodeCheckingCases(t, cases...) }