From 41f5a7f468daff49e00bc3908e82eab3063d5e1b Mon Sep 17 00:00:00 2001 From: wemeya Date: Wed, 15 Jun 2016 18:26:21 +0800 Subject: [PATCH 1/6] add code to list author of top repos --- dao/accesslog.go | 16 ++++++++++++++++ models/toprepo.go | 2 ++ 2 files changed, 18 insertions(+) diff --git a/dao/accesslog.go b/dao/accesslog.go index b407acb37..bc228f36b 100644 --- a/dao/accesslog.go +++ b/dao/accesslog.go @@ -159,5 +159,21 @@ func GetTopRepos(countNum int) ([]models.TopRepo, error) { if err != nil { return nil, err } + var repoString string + for _, v := range lists { + repoString += v.RepoName + "," + } + repoString = repoString[0 : len(repoString)-1] + var usrnameList []models.TopRepo + sql = "select username as creator from user left join access_log on user.user_id = access_log.user_id where access_log.operation = 'push' and access_log.repo_name in (?)" + queryParam = nil + queryParam = append(queryParam, repoString) + _, err = o.Raw(sql, queryParam).QueryRows(&usrnameList) + if err != nil { + return nil, err + } + for i := 0; i < len(lists); i++ { + lists[i].Creator = usrnameList[i].Creator + } return lists, nil } diff --git a/models/toprepo.go b/models/toprepo.go index 14bcffa66..3a27d2a67 100644 --- a/models/toprepo.go +++ b/models/toprepo.go @@ -19,4 +19,6 @@ package models type TopRepo struct { RepoName string `json:"name"` AccessCount int64 `json:"count"` + Size int64 `json:"size"` + Creator string `json:"creator"` } From 9b41d9f5c19dea55dffc232364a68b070d690337 Mon Sep 17 00:00:00 2001 From: wemeya Date: Tue, 21 Jun 2016 18:43:31 +0800 Subject: [PATCH 2/6] add creator field to models/toprepo.go --- dao/accesslog.go | 53 ++++++++++++++++++++++++++++++----------------- models/toprepo.go | 1 - ui/router.go | 3 +-- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/dao/accesslog.go b/dao/accesslog.go index bc228f36b..18d2291cf 100644 --- a/dao/accesslog.go +++ b/dao/accesslog.go @@ -152,28 +152,43 @@ func GetTopRepos(countNum int) ([]models.TopRepo, error) { o := GetOrmer() sql := "select repo_name, COUNT(repo_name) as access_count from access_log left join project on access_log.project_id=project.project_id where project.public = 1 and access_log.operation = 'pull' group by repo_name order by access_count desc limit ? " - queryParam := make([]interface{}, 1) + queryParam := []interface{}{} queryParam = append(queryParam, countNum) - var lists []models.TopRepo - _, err := o.Raw(sql, queryParam).QueryRows(&lists) + var list []models.TopRepo + _, err := o.Raw(sql, queryParam).QueryRows(&list) if err != nil { return nil, err } - var repoString string - for _, v := range lists { - repoString += v.RepoName + "," + if len(list) == 0 { + return list, nil + } else { + place_holder := make([]string, len(list)) + repos := make([]string, len(list)) + for i, v := range list { + repos[i] = v.RepoName + place_holder[i] = "?" + } + place_holder_str := strings.Join(place_holder, ",") + queryParam = nil + queryParam = append(queryParam, repos) + var usrnameList []models.TopRepo + sql = `select a.username as creator, a.repo_name from (select access_log.repo_name, user.username, + access_log.op_time from user left join access_log on user.user_id = access_log.user_id where + access_log.operation = 'push' and access_log.repo_name in (######) order by access_log.repo_name, + access_log.op_time ASC) a group by a.repo_name` + sql = strings.Replace(sql, "######", place_holder_str, 1) + _, err = o.Raw(sql, queryParam).QueryRows(&usrnameList) + if err != nil { + return nil, err + } + for i := 0; i < len(list); i++ { + for _, v := range usrnameList { + if v.RepoName == list[i].RepoName { + list[i].Creator = v.Creator + break + } + } + } + return list, nil } - repoString = repoString[0 : len(repoString)-1] - var usrnameList []models.TopRepo - sql = "select username as creator from user left join access_log on user.user_id = access_log.user_id where access_log.operation = 'push' and access_log.repo_name in (?)" - queryParam = nil - queryParam = append(queryParam, repoString) - _, err = o.Raw(sql, queryParam).QueryRows(&usrnameList) - if err != nil { - return nil, err - } - for i := 0; i < len(lists); i++ { - lists[i].Creator = usrnameList[i].Creator - } - return lists, nil } diff --git a/models/toprepo.go b/models/toprepo.go index 3a27d2a67..6ccb46227 100644 --- a/models/toprepo.go +++ b/models/toprepo.go @@ -19,6 +19,5 @@ package models type TopRepo struct { RepoName string `json:"name"` AccessCount int64 `json:"count"` - Size int64 `json:"size"` Creator string `json:"creator"` } diff --git a/ui/router.go b/ui/router.go index c560b0d07..a58996dab 100644 --- a/ui/router.go +++ b/ui/router.go @@ -79,8 +79,7 @@ func initRouters() { beego.Router("/api/targets/ping", &api.TargetAPI{}, "post:Ping") beego.Router("/api/users/:id/sysadmin", &api.UserAPI{}, "put:ToggleUserAdminRole") beego.Router("/api/repositories/top", &api.RepositoryAPI{}, "get:GetTopRepos") - beego.Router("api/logs", &api.LogAPI{}) - + beego.Router("/api/logs", &api.LogAPI{}) //external service that hosted on harbor process: beego.Router("/service/notifications", &service.NotificationHandler{}) beego.Router("/service/token", &token.Handler{}) From 5f9edba5a6cec9d98cb79089bd1a046e23a892ed Mon Sep 17 00:00:00 2001 From: wemeya Date: Wed, 22 Jun 2016 14:15:32 +0800 Subject: [PATCH 3/6] modify code for travis CI --- dao/accesslog.go | 53 ++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/dao/accesslog.go b/dao/accesslog.go index 18d2291cf..c9f887029 100644 --- a/dao/accesslog.go +++ b/dao/accesslog.go @@ -161,34 +161,33 @@ func GetTopRepos(countNum int) ([]models.TopRepo, error) { } if len(list) == 0 { return list, nil - } else { - place_holder := make([]string, len(list)) - repos := make([]string, len(list)) - for i, v := range list { - repos[i] = v.RepoName - place_holder[i] = "?" - } - place_holder_str := strings.Join(place_holder, ",") - queryParam = nil - queryParam = append(queryParam, repos) - var usrnameList []models.TopRepo - sql = `select a.username as creator, a.repo_name from (select access_log.repo_name, user.username, - access_log.op_time from user left join access_log on user.user_id = access_log.user_id where - access_log.operation = 'push' and access_log.repo_name in (######) order by access_log.repo_name, - access_log.op_time ASC) a group by a.repo_name` - sql = strings.Replace(sql, "######", place_holder_str, 1) - _, err = o.Raw(sql, queryParam).QueryRows(&usrnameList) - if err != nil { - return nil, err - } - for i := 0; i < len(list); i++ { - for _, v := range usrnameList { - if v.RepoName == list[i].RepoName { - list[i].Creator = v.Creator - break - } + } + placeHolder := make([]string, len(list)) + repos := make([]string, len(list)) + for i, v := range list { + repos[i] = v.RepoName + placeHolder[i] = "?" + } + placeHolderStr := strings.Join(placeHolder, ",") + queryParam = nil + queryParam = append(queryParam, repos) + var usrnameList []models.TopRepo + sql = `select a.username as creator, a.repo_name from (select access_log.repo_name, user.username, + access_log.op_time from user left join access_log on user.user_id = access_log.user_id where + access_log.operation = 'push' and access_log.repo_name in (######) order by access_log.repo_name, + access_log.op_time ASC) a group by a.repo_name` + sql = strings.Replace(sql, "######", placeHolderStr, 1) + _, err = o.Raw(sql, queryParam).QueryRows(&usrnameList) + if err != nil { + return nil, err + } + for i := 0; i < len(list); i++ { + for _, v := range usrnameList { + if v.RepoName == list[i].RepoName { + list[i].Creator = v.Creator + break } } - return list, nil } + return list, nil } From f3203272e226a9a1386311a93c7eda4f33940bcd Mon Sep 17 00:00:00 2001 From: wemeya Date: Wed, 22 Jun 2016 16:36:36 +0800 Subject: [PATCH 4/6] modify sql where condition --- dao/accesslog.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dao/accesslog.go b/dao/accesslog.go index c9f887029..930607701 100644 --- a/dao/accesslog.go +++ b/dao/accesslog.go @@ -150,8 +150,8 @@ func GetRecentLogs(userID, linesNum int, startTime, endTime string) ([]models.Ac func GetTopRepos(countNum int) ([]models.TopRepo, error) { o := GetOrmer() - - sql := "select repo_name, COUNT(repo_name) as access_count from access_log left join project on access_log.project_id=project.project_id where project.public = 1 and access_log.operation = 'pull' group by repo_name order by access_count desc limit ? " + // hide the where condition: project.public = 1, Can add to the sql when necessary. + sql := "select repo_name, COUNT(repo_name) as access_count from access_log left join project on access_log.project_id=project.project_id where access_log.operation = 'pull' group by repo_name order by access_count desc limit ? " queryParam := []interface{}{} queryParam = append(queryParam, countNum) var list []models.TopRepo From f037b23fb8e33fb38fa51bd19cbea2a848a5fa28 Mon Sep 17 00:00:00 2001 From: wemeya Date: Thu, 23 Jun 2016 18:15:58 +0800 Subject: [PATCH 5/6] modify code for test --- api/project.go | 2 +- controllers/password.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/project.go b/api/project.go index da26b8a0a..d38e5c40d 100644 --- a/api/project.go +++ b/api/project.go @@ -291,7 +291,7 @@ func validateProjectReq(req projectReq) error { if isIllegalLength(req.ProjectName, projectNameMinLen, projectNameMaxLen) { return fmt.Errorf("project name is illegal in length. (greater than 4 or less than 30)") } - if isContainIllegalChar(req.ProjectName, []string{"~", "-", "$", "\\", "[", "]", "{", "}", "(", ")", "&", "^", "%", "*", "<", ">", "\"", "'", "/", "?", "@"}) { + if isContainIllegalChar(req.ProjectName, []string{"~", "-", "$", "\\", "[", "]", "{", "}", "(", ")", "&", "^", "%", "*", "<", ">", "\"", "'", "/", "?", "@", " "}) { return fmt.Errorf("project name contains illegal characters") } diff --git a/controllers/password.go b/controllers/password.go index f285e64a9..b1dc3becc 100644 --- a/controllers/password.go +++ b/controllers/password.go @@ -59,7 +59,7 @@ func (cc *CommonController) SendEmail() { cc.CustomAbort(http.StatusInternalServerError, "Internal error.") } err = messageTemplate.Execute(message, messageDetail{ - Hint: cc.Tr("reset_email_hint"), + Hint: cc.Tr("Warning: You're receiving this because you're requesting for changing password in Harbor, if it is not your operation, please ignore; otherwise, please click the link below"), URL: harborURL, UUID: uuid, }) From 8af26bb95159a5d747242bbe58a09e5ee5c8ced1 Mon Sep 17 00:00:00 2001 From: wemeya Date: Fri, 24 Jun 2016 16:52:08 +0800 Subject: [PATCH 6/6] add regular expression to check project name --- api/project.go | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/api/project.go b/api/project.go index d38e5c40d..fdbce7591 100644 --- a/api/project.go +++ b/api/project.go @@ -18,7 +18,7 @@ package api import ( "fmt" "net/http" - "strings" + "regexp" "github.com/vmware/harbor/dao" "github.com/vmware/harbor/models" @@ -285,19 +285,13 @@ func isProjectAdmin(userID int, pid int64) bool { func validateProjectReq(req projectReq) error { pn := req.ProjectName - if len(pn) == 0 { - return fmt.Errorf("Project name can not be empty") - } if isIllegalLength(req.ProjectName, projectNameMinLen, projectNameMaxLen) { - return fmt.Errorf("project name is illegal in length. (greater than 4 or less than 30)") + return fmt.Errorf("Project name is illegal in length. (greater than 4 or less than 30)") } - if isContainIllegalChar(req.ProjectName, []string{"~", "-", "$", "\\", "[", "]", "{", "}", "(", ")", "&", "^", "%", "*", "<", ">", "\"", "'", "/", "?", "@", " "}) { - return fmt.Errorf("project name contains illegal characters") + validProjectName := regexp.MustCompile(`^[a-z0-9](?:-*[a-z0-9])*(?:[._][a-z0-9](?:-*[a-z0-9])*)*$`) + legal := validProjectName.MatchString(pn) + if !legal { + return fmt.Errorf("Project name is not in lower case or contains illegal characters!") } - - if pn != strings.ToLower(pn) { - return fmt.Errorf("project name must be in lower case") - } - return nil }