From cf306ec66e3930253657d6fbb16e44689679cb39 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Wed, 24 May 2017 16:34:33 +0800 Subject: [PATCH 1/2] refactor statistics API --- src/common/dao/repository.go | 44 +----------------- src/common/dao/repository_test.go | 76 +------------------------------ src/ui/api/repository.go | 3 +- src/ui/api/statistic.go | 76 ++++++++++++++++--------------- 4 files changed, 46 insertions(+), 153 deletions(-) diff --git a/src/common/dao/repository.go b/src/common/dao/repository.go index 6191bccbc..8e448edd8 100644 --- a/src/common/dao/repository.go +++ b/src/common/dao/repository.go @@ -125,50 +125,10 @@ func GetTotalOfRepositories(name string) (int64, error) { return qs.Count() } -// GetTotalOfPublicRepositories ... -func GetTotalOfPublicRepositories(name string) (int64, error) { - params := []interface{}{} - sql := `select count(*) from repository r - join project p - on r.project_id = p.project_id and p.public = 1 ` - if len(name) != 0 { - sql += ` where r.name like ?` - params = append(params, "%"+escape(name)+"%") - } - - var total int64 - err := GetOrmer().Raw(sql, params).QueryRow(&total) - return total, err -} - -// GetTotalOfUserRelevantRepositories ... -func GetTotalOfUserRelevantRepositories(userID int, name string) (int64, error) { - params := []interface{}{} - sql := `select count(*) - from repository r - join ( - select p.project_id, p.public - from project p - join project_member pm - on p.project_id = pm.project_id - where pm.user_id = ? - ) as pp - on r.project_id = pp.project_id ` - params = append(params, userID) - if len(name) != 0 { - sql += ` where r.name like ?` - params = append(params, "%"+escape(name)+"%") - } - - var total int64 - err := GetOrmer().Raw(sql, params).QueryRow(&total) - return total, err -} - // GetTotalOfRepositoriesByProject ... -func GetTotalOfRepositoriesByProject(projectID int64, name string) (int64, error) { +func GetTotalOfRepositoriesByProject(projectIDs []int64, name string) (int64, error) { qs := GetOrmer().QueryTable(&models.RepoRecord{}). - Filter("ProjectID", projectID) + Filter("project_id__in", projectIDs) if len(name) != 0 { qs = qs.Filter("Name__contains", name) diff --git a/src/common/dao/repository_test.go b/src/common/dao/repository_test.go index 94a769c3e..ff457aeac 100644 --- a/src/common/dao/repository_test.go +++ b/src/common/dao/repository_test.go @@ -88,78 +88,6 @@ func TestGetTotalOfRepositories(t *testing.T) { } } -func TestGetTotalOfPublicRepositories(t *testing.T) { - total, err := GetTotalOfPublicRepositories("") - if err != nil { - t.Fatalf("failed to get total of public repositoreis: %v", err) - } - - if err := addRepository(repository); err != nil { - t.Fatalf("failed to add repository %s: %v", name, err) - } - defer func() { - if err := deleteRepository(name); err != nil { - t.Fatalf("failed to delete repository %s: %v", name, err) - } - }() - - n, err := GetTotalOfPublicRepositories("") - if err != nil { - t.Fatalf("failed to get total of public repositoreis: %v", err) - } - - if n != total+1 { - t.Errorf("unexpected total: %d != %d", n, total+1) - } -} - -func TestGetTotalOfUserRelevantRepositories(t *testing.T) { - total, err := GetTotalOfUserRelevantRepositories(1, "") - if err != nil { - t.Fatalf("failed to get total of repositoreis for user %d: %v", 1, err) - } - - if err := addRepository(repository); err != nil { - t.Fatalf("failed to add repository %s: %v", name, err) - } - defer func() { - if err := deleteRepository(name); err != nil { - t.Fatalf("failed to delete repository %s: %v", name, err) - } - }() - - users, err := GetUserByProject(1, models.User{}) - if err != nil { - t.Fatalf("failed to list members of project %d: %v", 1, err) - } - exist := false - for _, user := range users { - if user.UserID == 1 { - exist = true - break - } - } - if !exist { - if err = AddProjectMember(1, 1, models.DEVELOPER); err != nil { - t.Fatalf("failed to add user %d to be member of project %d: %v", 1, 1, err) - } - defer func() { - if err = DeleteProjectMember(1, 1); err != nil { - t.Fatalf("failed to delete user %d from member of project %d: %v", 1, 1, err) - } - }() - } - - n, err := GetTotalOfUserRelevantRepositories(1, "") - if err != nil { - t.Fatalf("failed to get total of public repositoreis for user %d: %v", 1, err) - } - - if n != total+1 { - t.Errorf("unexpected total: %d != %d", n, total+1) - } -} - func TestGetTopRepos(t *testing.T) { var err error require := require.New(t) @@ -226,7 +154,7 @@ func TestGetTotalOfRepositoriesByProject(t *testing.T) { var projectID int64 = 1 repoName := "library/total_count" - total, err := GetTotalOfRepositoriesByProject(projectID, repoName) + total, err := GetTotalOfRepositoriesByProject([]int64{projectID}, repoName) if err != nil { t.Errorf("failed to get total of repositoreis of project %d: %v", projectID, err) return @@ -246,7 +174,7 @@ func TestGetTotalOfRepositoriesByProject(t *testing.T) { } }() - n, err := GetTotalOfRepositoriesByProject(projectID, repoName) + n, err := GetTotalOfRepositoriesByProject([]int64{projectID}, repoName) if err != nil { t.Errorf("failed to get total of repositoreis of project %d: %v", projectID, err) return diff --git a/src/ui/api/repository.go b/src/ui/api/repository.go index cc831afc7..0782ca04e 100644 --- a/src/ui/api/repository.go +++ b/src/ui/api/repository.go @@ -103,7 +103,8 @@ func (ra *RepositoryAPI) Get() { keyword := ra.GetString("q") - total, err := dao.GetTotalOfRepositoriesByProject(projectID, keyword) + total, err := dao.GetTotalOfRepositoriesByProject( + []int64{projectID}, keyword) if err != nil { ra.HandleInternalServerError(fmt.Sprintf("failed to get total of repositories of project %d: %v", projectID, err)) diff --git a/src/ui/api/statistic.go b/src/ui/api/statistic.go index 4183b0a80..647f1a8d1 100644 --- a/src/ui/api/statistic.go +++ b/src/ui/api/statistic.go @@ -15,9 +15,9 @@ package api import ( + "fmt" "net/http" - "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" @@ -40,42 +40,45 @@ const ( // StatisticAPI handles request to /api/statistics/ type StatisticAPI struct { - api.BaseAPI - userID int + BaseController + username string } //Prepare validates the URL and the user func (s *StatisticAPI) Prepare() { - s.userID = s.ValidateUser() + s.BaseController.Prepare() + if !s.SecurityCtx.IsAuthenticated() { + s.HandleUnauthorized() + return + } + s.username = s.SecurityCtx.GetUsername() } // Get total projects and repos of the user func (s *StatisticAPI) Get() { statistic := map[string]int64{} - 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, "") - } - statistic[PPC] = n - n, err = dao.GetTotalOfPublicRepositories("") + projects, err := s.ProjectMgr.GetPublic() + if err != nil { + s.HandleInternalServerError(fmt.Sprintf( + "failed to get public projects: %v", err)) + return + } + + statistic[PPC] = (int64)(len(projects)) + + ids := []int64{} + for _, p := range projects { + ids = append(ids, p.ProjectID) + } + n, err := dao.GetTotalOfRepositoriesByProject(ids, "") if err != nil { log.Errorf("failed to get total of public repositories: %v", err) s.CustomAbort(http.StatusInternalServerError, "") } statistic[PRC] = n - isAdmin, err := dao.IsAdminRole(s.userID) - if err != nil { - log.Errorf("Error occured in check admin, error: %v", err) - s.CustomAbort(http.StatusInternalServerError, "Internal error.") - } - - if isAdmin { + if s.SecurityCtx.IsSysAdmin() { n, err := dao.GetTotalOfProjects(nil) if err != nil { log.Errorf("failed to get total of projects: %v", err) @@ -92,28 +95,29 @@ func (s *StatisticAPI) Get() { statistic[MRC] = n statistic[TRC] = n } else { - user, err := dao.GetUser(models.User{ - UserID: s.userID, - }) - if err != nil { - log.Errorf("failed to get user %d: %v", s.userID, err) - s.CustomAbort(http.StatusInternalServerError, "") - } - n, err := dao.GetTotalOfProjects(&models.QueryParam{ + projects, err := s.ProjectMgr.GetAll(&models.QueryParam{ Member: &models.Member{ - Name: user.Username, + Name: s.username, }, }) if err != nil { - log.Errorf("failed to get total of projects for user %d: %v", s.userID, err) - s.CustomAbort(http.StatusInternalServerError, "") + s.HandleInternalServerError(fmt.Sprintf( + "failed to get projects: %v", err)) + return } - statistic[MPC] = n + statistic[MPC] = (int64)(len(projects)) - n, err = dao.GetTotalOfUserRelevantRepositories(s.userID, "") + ids := []int64{} + for _, p := range projects { + ids = append(ids, p.ProjectID) + } + + n, err = dao.GetTotalOfRepositoriesByProject(ids, "") if err != nil { - log.Errorf("failed to get total of repositories for user %d: %v", s.userID, err) - s.CustomAbort(http.StatusInternalServerError, "") + s.HandleInternalServerError(fmt.Sprintf( + "failed to get total of repositories for user %s: %v", + s.username, err)) + return } statistic[MRC] = n } From e0fe068308deefb94ee8b968866d716a8b0f15e6 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Fri, 2 Jun 2017 14:17:01 +0800 Subject: [PATCH 2/2] update --- src/ui/api/statistic.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/api/statistic.go b/src/ui/api/statistic.go index 647f1a8d1..a76a3f0ba 100644 --- a/src/ui/api/statistic.go +++ b/src/ui/api/statistic.go @@ -102,7 +102,7 @@ func (s *StatisticAPI) Get() { }) if err != nil { s.HandleInternalServerError(fmt.Sprintf( - "failed to get projects: %v", err)) + "failed to get projects of user %s: %v", s.username, err)) return } statistic[MPC] = (int64)(len(projects))