From 7df2be19de9f4e12aa410a30dd5d04147153bf07 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Fri, 19 May 2017 13:05:44 +0800 Subject: [PATCH] update --- src/common/dao/dao_test.go | 9 ++-- src/common/dao/project.go | 56 +++++++++++++++++++--- src/common/models/project.go | 31 ++++++++++++ src/common/security/rbac/context_test.go | 5 +- src/ui/api/project.go | 15 +++--- src/ui/api/search.go | 2 +- src/ui/api/statistic.go | 14 ++++-- src/ui/projectmanager/db/pm.go | 61 ++++-------------------- src/ui/projectmanager/db/pm_test.go | 19 ++++---- src/ui/projectmanager/pm.go | 25 +--------- 10 files changed, 127 insertions(+), 110 deletions(-) diff --git a/src/common/dao/dao_test.go b/src/common/dao/dao_test.go index 12439a813..a7400702b 100644 --- a/src/common/dao/dao_test.go +++ b/src/common/dao/dao_test.go @@ -802,7 +802,7 @@ func TestProjectPermission(t *testing.T) { } func TestGetTotalOfProjects(t *testing.T) { - total, err := GetTotalOfProjects("", "", "", "", 0) + total, err := GetTotalOfProjects(nil) if err != nil { t.Fatalf("failed to get total of projects: %v", err) } @@ -813,7 +813,7 @@ func TestGetTotalOfProjects(t *testing.T) { } func TestGetProjects(t *testing.T) { - projects, err := GetProjects("", "", "", "", 0, 0, 0) + projects, err := GetProjects(nil) if err != nil { t.Errorf("Error occurred in GetAllProjects: %v", err) } @@ -826,7 +826,10 @@ func TestGetProjects(t *testing.T) { } func TestGetPublicProjects(t *testing.T) { - projects, err := GetProjects("", "", "true", "", 0, 0, 0) + value := true + projects, err := GetProjects(&models.QueryParam{ + Public: &value, + }) if err != nil { t.Errorf("Error occurred in getProjects: %v", err) } diff --git a/src/common/dao/project.go b/src/common/dao/project.go index 9496c8892..319f423be 100644 --- a/src/common/dao/project.go +++ b/src/common/dao/project.go @@ -183,8 +183,26 @@ func SearchProjects(userID int) ([]*models.Project, error) { // GetTotalOfProjects returns the total count of projects // according to the query conditions -func GetTotalOfProjects(owner, name, public, member string, - role int) (int64, error) { +func GetTotalOfProjects(query *models.QueryParam) (int64, error) { + + var ( + owner string + name string + public *bool + member string + role int + ) + + if query != nil { + owner = query.Owner + name = query.Name + public = query.Public + if query.Member != nil { + member = query.Member.Name + role = query.Member.Role + } + } + sql, params := queryConditions(owner, name, public, member, role) sql = `select count(*) ` + sql @@ -195,8 +213,32 @@ func GetTotalOfProjects(owner, name, public, member string, } // GetProjects returns a project list according to the query conditions -func GetProjects(owner, name, public, member string, - role int, page, size int64) ([]*models.Project, error) { +func GetProjects(query *models.QueryParam) ([]*models.Project, error) { + + var ( + owner string + name string + public *bool + member string + role int + page int64 + size int64 + ) + + if query != nil { + owner = query.Owner + name = query.Name + public = query.Public + if query.Member != nil { + member = query.Member.Name + role = query.Member.Role + } + if query.Pagination != nil { + page = query.Pagination.Page + size = query.Pagination.Size + } + } + sql, params := queryConditions(owner, name, public, member, role) sql = `select distinct p.project_id, p.name, p.public, p.owner_id, @@ -216,7 +258,7 @@ func GetProjects(owner, name, public, member string, return projects, err } -func queryConditions(owner, name, public, member string, +func queryConditions(owner, name string, public *bool, member string, role int) (string, []interface{}) { params := []interface{}{} @@ -245,9 +287,9 @@ func queryConditions(owner, name, public, member string, params = append(params, "%"+escape(name)+"%") } - if len(public) != 0 { + if public != nil { sql += ` and p.public = ?` - if public == "true" { + if *public { params = append(params, 1) } else { params = append(params, 0) diff --git a/src/common/models/project.go b/src/common/models/project.go index a85ec465c..558299169 100644 --- a/src/common/models/project.go +++ b/src/common/models/project.go @@ -57,3 +57,34 @@ func (ps *ProjectSorter) Less(i, j int) bool { func (ps *ProjectSorter) Swap(i, j int) { ps.Projects[i], ps.Projects[j] = ps.Projects[j], ps.Projects[i] } + +// QueryParam can be used to set query parameters when listing projects. +// The query condition will be set in the query if its corresponding field +// is not nil. Leave it empty if you don't want to apply this condition. +// +// e.g. +// List all projects: query := nil +// List all public projects: query := &QueryParam{Public: true} +// List projects the owner of which is user1: query := &QueryParam{Owner:"user1"} +// List all public projects the owner of which is user1: query := &QueryParam{Owner:"user1",Public:true} +// List projects which user1 is member of: query := &QueryParam{Member:&Member{Name:"user1"}} +// List projects which user1 is the project admin : query := &QueryParam{Memeber:&Member{Name:"user1",Role:1}} +type QueryParam struct { + Name string // the name of project + Owner string // the username of project owner + Public *bool // the project is public or not, can be ture, false and nil + Member *Member // the member of project + Pagination *Pagination // pagination information +} + +// Member fitler by member's username and role +type Member struct { + Name string // the username of member + Role int // the role of the member has to the project +} + +// Pagination ... +type Pagination struct { + Page int64 + Size int64 +} diff --git a/src/common/security/rbac/context_test.go b/src/common/security/rbac/context_test.go index 9d94998d2..817c73977 100644 --- a/src/common/security/rbac/context_test.go +++ b/src/common/security/rbac/context_test.go @@ -21,7 +21,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/vmware/harbor/src/common" "github.com/vmware/harbor/src/common/models" - "github.com/vmware/harbor/src/ui/projectmanager" ) var ( @@ -107,12 +106,12 @@ func (f *fakePM) Update(projectIDOrName interface{}, project *models.Project) er } // nil implement -func (f *fakePM) GetAll(*projectmanager.QueryParam) ([]*models.Project, error) { +func (f *fakePM) GetAll(*models.QueryParam) ([]*models.Project, error) { return []*models.Project{}, nil } // nil implement -func (f *fakePM) GetTotal(*projectmanager.QueryParam) (int64, error) { +func (f *fakePM) GetTotal(*models.QueryParam) (int64, error) { return 0, nil } diff --git a/src/ui/api/project.go b/src/ui/api/project.go index 92b301470..347663b6d 100644 --- a/src/ui/api/project.go +++ b/src/ui/api/project.go @@ -24,7 +24,6 @@ import ( "github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/utils/log" "github.com/vmware/harbor/src/ui/config" - "github.com/vmware/harbor/src/ui/projectmanager" "strconv" "time" @@ -142,7 +141,6 @@ func (p *ProjectAPI) Post() { OpTime: time.Now(), }); err != nil { log.Errorf("failed to add access log: %v", err) - p.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } }() @@ -260,7 +258,7 @@ func projectContainsPolicy(id int64) (bool, error) { // TODO refacter pattern to: // /api/repositories?owner=xxx&name=xxx&public=true&member=xxx&role=1&page=1&size=3 func (p *ProjectAPI) List() { - query := &projectmanager.QueryParam{} + query := &models.QueryParam{} query.Name = p.GetString("project_name") public := p.GetString("is_public") @@ -270,11 +268,12 @@ func (p *ProjectAPI) List() { return } if public == "1" { - query.Public = "true" + t := true + query.Public = &t } } - if query.Public != "true" { + if query.Public == nil || *query.Public == false { //if the request is not for public projects, user must login or provide credential if !p.SecurityCtx.IsAuthenticated() { p.HandleUnauthorized() @@ -282,7 +281,7 @@ func (p *ProjectAPI) List() { } if !p.SecurityCtx.IsSysAdmin() { - query.Member = &projectmanager.Member{ + query.Member = &models.Member{ Name: p.SecurityCtx.GetUsername(), } } @@ -295,7 +294,7 @@ func (p *ProjectAPI) List() { } page, size := p.GetPaginationParams() - query.Pagination = &projectmanager.Pagination{ + query.Pagination = &models.Pagination{ Page: page, Size: size, } @@ -307,7 +306,7 @@ func (p *ProjectAPI) List() { } for _, project := range projects { - if query.Public != "true" { + if query.Public == nil || *query.Public == false { roles, err := p.ProjectMgr.GetRoles(p.SecurityCtx.GetUsername(), project.ProjectID) if err != nil { p.HandleInternalServerError(fmt.Sprintf("failed to get roles of user %s to project %d: %v", diff --git a/src/ui/api/search.go b/src/ui/api/search.go index 1f54f031c..20612f5f6 100644 --- a/src/ui/api/search.go +++ b/src/ui/api/search.go @@ -55,7 +55,7 @@ func (s *SearchAPI) Get() { var projects []*models.Project if isSysAdmin { - projects, err = dao.GetProjects("", "", "", "", 0, 0, 0) + projects, err = dao.GetProjects(nil) if err != nil { log.Errorf("failed to get all projects: %v", err) s.CustomAbort(http.StatusInternalServerError, "internal error") diff --git a/src/ui/api/statistic.go b/src/ui/api/statistic.go index c151c2e84..4183b0a80 100644 --- a/src/ui/api/statistic.go +++ b/src/ui/api/statistic.go @@ -52,8 +52,10 @@ func (s *StatisticAPI) Prepare() { // Get total projects and repos of the user func (s *StatisticAPI) Get() { statistic := map[string]int64{} - - n, err := dao.GetTotalOfProjects("", "", "true", "", 0) + t := true + n, err := dao.GetTotalOfProjects(&models.QueryParam{ + Public: &t, + }) if err != nil { log.Errorf("failed to get total of public projects: %v", err) s.CustomAbort(http.StatusInternalServerError, "") @@ -74,7 +76,7 @@ func (s *StatisticAPI) Get() { } if isAdmin { - n, err := dao.GetTotalOfProjects("", "", "", "", 0) + n, err := dao.GetTotalOfProjects(nil) if err != nil { log.Errorf("failed to get total of projects: %v", err) s.CustomAbort(http.StatusInternalServerError, "") @@ -97,7 +99,11 @@ func (s *StatisticAPI) Get() { log.Errorf("failed to get user %d: %v", s.userID, err) s.CustomAbort(http.StatusInternalServerError, "") } - n, err := dao.GetTotalOfProjects("", "", "", user.Username, 0) + n, err := dao.GetTotalOfProjects(&models.QueryParam{ + Member: &models.Member{ + Name: user.Username, + }, + }) if err != nil { log.Errorf("failed to get total of projects for user %d: %v", s.userID, err) s.CustomAbort(http.StatusInternalServerError, "") diff --git a/src/ui/projectmanager/db/pm.go b/src/ui/projectmanager/db/pm.go index 5c0446d94..96736d8f7 100644 --- a/src/ui/projectmanager/db/pm.go +++ b/src/ui/projectmanager/db/pm.go @@ -21,7 +21,6 @@ import ( "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/ui/projectmanager" ) // ProjectManager implements pm.PM interface based on database @@ -107,16 +106,17 @@ func (p *ProjectManager) GetRoles(username string, projectIDOrName interface{}) // GetPublic returns all public projects func (p *ProjectManager) GetPublic() ([]*models.Project, error) { - return p.GetAll(&projectmanager.QueryParam{ - Public: "true", + t := true + return p.GetAll(&models.QueryParam{ + Public: &t, }) } // GetByMember returns all projects which the user is a member of func (p *ProjectManager) GetByMember(username string) ( []*models.Project, error) { - return p.GetAll(&projectmanager.QueryParam{ - Member: &projectmanager.Member{ + return p.GetAll(&models.QueryParam{ + Member: &models.Member{ Name: username, }, }) @@ -190,56 +190,13 @@ func (p *ProjectManager) Update(projectIDOrName interface{}, } // GetAll returns a project list according to the query parameters -func (p *ProjectManager) GetAll(query *projectmanager.QueryParam) ( +func (p *ProjectManager) GetAll(query *models.QueryParam) ( []*models.Project, error) { - - var ( - owner string - name string - public string - member string - role int - page int64 - size int64 - ) - - if query != nil { - owner = query.Owner - name = query.Name - public = query.Public - if query.Member != nil { - member = query.Member.Name - role = query.Member.Role - } - if query.Pagination != nil { - page = query.Pagination.Page - size = query.Pagination.Size - } - } - - return dao.GetProjects(owner, name, public, member, role, page, size) + return dao.GetProjects(query) } // GetTotal returns the total count according to the query parameters -func (p *ProjectManager) GetTotal(query *projectmanager.QueryParam) ( +func (p *ProjectManager) GetTotal(query *models.QueryParam) ( int64, error) { - var ( - owner string - name string - public string - member string - role int - ) - - if query != nil { - owner = query.Owner - name = query.Name - public = query.Public - if query.Member != nil { - member = query.Member.Name - role = query.Member.Role - } - } - - return dao.GetTotalOfProjects(owner, name, public, member, role) + return dao.GetTotalOfProjects(query) } diff --git a/src/ui/projectmanager/db/pm_test.go b/src/ui/projectmanager/db/pm_test.go index 91519fa24..24255887b 100644 --- a/src/ui/projectmanager/db/pm_test.go +++ b/src/ui/projectmanager/db/pm_test.go @@ -24,7 +24,6 @@ import ( "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/projectmanager" ) func TestMain(m *testing.M) { @@ -230,22 +229,23 @@ func TestGetTotal(t *testing.T) { defer pm.Delete(id) // get by name - total, err := pm.GetTotal(&projectmanager.QueryParam{ + total, err := pm.GetTotal(&models.QueryParam{ Name: "get_total_test", }) assert.Nil(t, err) assert.Equal(t, int64(1), total) // get by owner - total, err = pm.GetTotal(&projectmanager.QueryParam{ + total, err = pm.GetTotal(&models.QueryParam{ Owner: "admin", }) assert.Nil(t, err) assert.NotEqual(t, 0, total) // get by public - total, err = pm.GetTotal(&projectmanager.QueryParam{ - Public: "true", + value := true + total, err = pm.GetTotal(&models.QueryParam{ + Public: &value, }) assert.Nil(t, err) assert.NotEqual(t, 0, total) @@ -263,14 +263,14 @@ func TestGetAll(t *testing.T) { defer pm.Delete(id) // get by name - projects, err := pm.GetAll(&projectmanager.QueryParam{ + projects, err := pm.GetAll(&models.QueryParam{ Name: "get_all_test", }) assert.Nil(t, err) assert.Equal(t, id, projects[0].ProjectID) // get by owner - projects, err = pm.GetAll(&projectmanager.QueryParam{ + projects, err = pm.GetAll(&models.QueryParam{ Owner: "admin", }) assert.Nil(t, err) @@ -284,8 +284,9 @@ func TestGetAll(t *testing.T) { assert.True(t, exist) // get by public - projects, err = pm.GetAll(&projectmanager.QueryParam{ - Public: "true", + value := true + projects, err = pm.GetAll(&models.QueryParam{ + Public: &value, }) assert.Nil(t, err) exist = false diff --git a/src/ui/projectmanager/pm.go b/src/ui/projectmanager/pm.go index 1b80a4282..14ad4af2f 100644 --- a/src/ui/projectmanager/pm.go +++ b/src/ui/projectmanager/pm.go @@ -18,27 +18,6 @@ import ( "github.com/vmware/harbor/src/common/models" ) -// QueryParam can be used to set query parameters when listing projects -type QueryParam struct { - Name string // the name of project - Owner string // the username of project owner - Public string // the project is public or not, can be "ture","false" and "" - Member *Member // the member of project - Pagination *Pagination // pagination information -} - -// Member fitler by member's username and role -type Member struct { - Name string // the username of member - Role int // the role of the member has to the project -} - -// Pagination ... -type Pagination struct { - Page int64 - Size int64 -} - // ProjectManager is the project mamager which abstracts the operations related // to projects type ProjectManager interface { @@ -54,7 +33,7 @@ type ProjectManager interface { Delete(projectIDOrName interface{}) error Update(projectIDOrName interface{}, project *models.Project) error // GetAll returns a project list according to the query parameters - GetAll(query *QueryParam) ([]*models.Project, error) + GetAll(query *models.QueryParam) ([]*models.Project, error) // GetTotal returns the total count according to the query parameters - GetTotal(query *QueryParam) (int64, error) + GetTotal(query *models.QueryParam) (int64, error) }