mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-24 03:05:39 +01:00
Merge branch 'new-ui-with-sync-image' of https://github.com/vmware/harbor into new-ui-with-sync-image
This commit is contained in:
commit
d5dc67a166
@ -18,7 +18,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"regexp"
|
||||||
|
|
||||||
"github.com/vmware/harbor/dao"
|
"github.com/vmware/harbor/dao"
|
||||||
"github.com/vmware/harbor/models"
|
"github.com/vmware/harbor/models"
|
||||||
@ -285,19 +285,13 @@ func isProjectAdmin(userID int, pid int64) bool {
|
|||||||
|
|
||||||
func validateProjectReq(req projectReq) error {
|
func validateProjectReq(req projectReq) error {
|
||||||
pn := req.ProjectName
|
pn := req.ProjectName
|
||||||
if len(pn) == 0 {
|
|
||||||
return fmt.Errorf("Project name can not be empty")
|
|
||||||
}
|
|
||||||
if isIllegalLength(req.ProjectName, projectNameMinLen, projectNameMaxLen) {
|
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{"~", "-", "$", "\\", "[", "]", "{", "}", "(", ")", "&", "^", "%", "*", "<", ">", "\"", "'", "/", "?", "@"}) {
|
validProjectName := regexp.MustCompile(`^[a-z0-9](?:-*[a-z0-9])*(?:[._][a-z0-9](?:-*[a-z0-9])*)*$`)
|
||||||
return fmt.Errorf("project name contains illegal characters")
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ func (cc *CommonController) SendEmail() {
|
|||||||
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||||
}
|
}
|
||||||
err = messageTemplate.Execute(message, messageDetail{
|
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,
|
URL: harborURL,
|
||||||
UUID: uuid,
|
UUID: uuid,
|
||||||
})
|
})
|
||||||
|
@ -150,14 +150,44 @@ func GetRecentLogs(userID, linesNum int, startTime, endTime string) ([]models.Ac
|
|||||||
func GetTopRepos(countNum int) ([]models.TopRepo, error) {
|
func GetTopRepos(countNum int) ([]models.TopRepo, error) {
|
||||||
|
|
||||||
o := GetOrmer()
|
o := GetOrmer()
|
||||||
|
// 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 project.public = 1 and access_log.operation = 'pull' group by repo_name order by access_count desc limit ? "
|
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 := make([]interface{}, 1)
|
queryParam := []interface{}{}
|
||||||
queryParam = append(queryParam, countNum)
|
queryParam = append(queryParam, countNum)
|
||||||
var lists []models.TopRepo
|
var list []models.TopRepo
|
||||||
_, err := o.Raw(sql, queryParam).QueryRows(&lists)
|
_, err := o.Raw(sql, queryParam).QueryRows(&list)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return lists, nil
|
if len(list) == 0 {
|
||||||
|
return list, nil
|
||||||
|
}
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
@ -19,4 +19,5 @@ package models
|
|||||||
type TopRepo struct {
|
type TopRepo struct {
|
||||||
RepoName string `json:"name"`
|
RepoName string `json:"name"`
|
||||||
AccessCount int64 `json:"count"`
|
AccessCount int64 `json:"count"`
|
||||||
|
Creator string `json:"creator"`
|
||||||
}
|
}
|
||||||
|
@ -81,8 +81,7 @@ func initRouters() {
|
|||||||
beego.Router("/api/targets/ping", &api.TargetAPI{}, "post:Ping")
|
beego.Router("/api/targets/ping", &api.TargetAPI{}, "post:Ping")
|
||||||
beego.Router("/api/users/:id/sysadmin", &api.UserAPI{}, "put:ToggleUserAdminRole")
|
beego.Router("/api/users/:id/sysadmin", &api.UserAPI{}, "put:ToggleUserAdminRole")
|
||||||
beego.Router("/api/repositories/top", &api.RepositoryAPI{}, "get:GetTopRepos")
|
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:
|
//external service that hosted on harbor process:
|
||||||
beego.Router("/service/notifications", &service.NotificationHandler{})
|
beego.Router("/service/notifications", &service.NotificationHandler{})
|
||||||
beego.Router("/service/token", &token.Handler{})
|
beego.Router("/service/token", &token.Handler{})
|
||||||
|
Loading…
Reference in New Issue
Block a user