// Delete ... func (t *TargetAPI) Delete() { id := t.GetIDFromURL() target, err := dao.GetRepTarget(id) if err != nil { log.Errorf("failed to get target %d: %v", id, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } if target == nil { t.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound)) } policies, err := dao.GetRepPolicyByTarget(id) if err != nil { log.Errorf("failed to get policies according target %d: %v", id, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } if len(policies) > 0 { t.CustomAbort(http.StatusBadRequest, "the target is used by policies, can not be deleted") } if err = dao.DeleteRepTarget(id); err != nil { log.Errorf("failed to delete target %d: %v", id, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } }
// List ... func (t *TargetAPI) List() { name := t.GetString("name") targets, err := dao.FilterRepTargets(name) if err != nil { log.Errorf("failed to filter targets %s: %v", name, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } for _, target := range targets { if len(target.Password) == 0 { continue } str, err := utils.ReversibleDecrypt(target.Password) if err != nil { log.Errorf("failed to decrypt password: %v", err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } target.Password = str } t.Data["json"] = targets t.ServeJSON() return }
//GetTopRepos handles request GET /api/repositories/top func (ra *RepositoryAPI) GetTopRepos() { var err error var countNum int count := ra.GetString("count") if len(count) == 0 { countNum = 10 } else { countNum, err = strconv.Atoi(count) if err != nil { log.Errorf("Get parameters error--count, err: %v", err) ra.CustomAbort(http.StatusBadRequest, "bad request of count") } if countNum <= 0 { log.Warning("count must be a positive integer") ra.CustomAbort(http.StatusBadRequest, "count is 0 or negative") } } repos, err := dao.GetTopRepos(countNum) if err != nil { log.Errorf("error occured in get top 10 repos: %v", err) ra.CustomAbort(http.StatusInternalServerError, "internal server error") } ra.Data["json"] = repos ra.ServeJSON() }
// Prepare validates the URL and parms func (pma *ProjectMemberAPI) Prepare() { pid, err := strconv.ParseInt(pma.Ctx.Input.Param(":pid"), 10, 64) if err != nil { log.Errorf("Error parsing project id: %d, error: %v", pid, err) pma.CustomAbort(http.StatusBadRequest, "invalid project Id") return } p, err := dao.GetProjectByID(pid) if err != nil { log.Errorf("Error occurred in GetProjectById, error: %v", err) pma.CustomAbort(http.StatusInternalServerError, "Internal error.") } if p == nil { log.Warningf("Project with id: %d does not exist.", pid) pma.CustomAbort(http.StatusNotFound, "Project does not exist") } pma.project = p pma.currentUserID = pma.ValidateUser() mid := pma.Ctx.Input.Param(":mid") if mid == "current" { pma.memberID = pma.currentUserID } else if len(mid) == 0 { pma.memberID = 0 } else if len(mid) > 0 { memberID, err := strconv.Atoi(mid) if err != nil { log.Errorf("Invalid member Id, error: %v", err) pma.CustomAbort(http.StatusBadRequest, "Invalid member id") } pma.memberID = memberID } }
// Get ... func (t *TargetAPI) Get() { id := t.GetIDFromURL() target, err := dao.GetRepTarget(id) if err != nil { log.Errorf("failed to get target %d: %v", id, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } if target == nil { t.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound)) } // The reason why the password is returned is that when user just wants to // modify other fields of target he does not need to input the password again. // The security issue can be fixed by enable https. if len(target.Password) != 0 { pwd, err := utils.ReversibleDecrypt(target.Password) if err != nil { log.Errorf("failed to decrypt password: %v", err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } target.Password = pwd } t.Data["json"] = target t.ServeJSON() }
func isProjectAdmin(userID int, pid int64) bool { isSysAdmin, err := dao.IsAdminRole(userID) if err != nil { log.Errorf("Error occurred in IsAdminRole, returning false, error: %v", err) return false } if isSysAdmin { return true } rolelist, err := dao.GetUserProjectRoles(userID, pid) if err != nil { log.Errorf("Error occurred in GetUserProjectRoles, returning false, error: %v", err) return false } hasProjectAdminRole := false for _, role := range rolelist { if role.RoleID == models.PROJECTADMIN { hasProjectAdminRole = true break } } return hasProjectAdminRole }
// GetLog ... func (ra *RepJobAPI) GetLog() { if ra.jobID == 0 { ra.CustomAbort(http.StatusBadRequest, "id is nil") } resp, err := http.Get(buildJobLogURL(strconv.FormatInt(ra.jobID, 10))) if err != nil { log.Errorf("failed to get log for job %d: %v", ra.jobID, err) ra.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } if resp.StatusCode == http.StatusOK { ra.Ctx.ResponseWriter.Header().Set(http.CanonicalHeaderKey("Content-Length"), resp.Header.Get(http.CanonicalHeaderKey("Content-Length"))) ra.Ctx.ResponseWriter.Header().Set(http.CanonicalHeaderKey("Content-Type"), "text/plain") if _, err = io.Copy(ra.Ctx.ResponseWriter, resp.Body); err != nil { log.Errorf("failed to write log to response; %v", err) ra.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } return } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { log.Errorf("failed to read reponse body: %v", err) ra.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } ra.CustomAbort(resp.StatusCode, string(b)) }
// ToggleProjectPublic ... func (p *ProjectAPI) ToggleProjectPublic() { p.userID = p.ValidateUser() var req projectReq var public int projectID, err := strconv.ParseInt(p.Ctx.Input.Param(":id"), 10, 64) if err != nil { log.Errorf("Error parsing project id: %d, error: %v", projectID, err) p.RenderError(http.StatusBadRequest, "invalid project id") return } p.DecodeJSONReq(&req) if req.Public { public = 1 } if !isProjectAdmin(p.userID, projectID) { log.Warningf("Current user, id: %d does not have project admin role for project, id: %d", p.userID, projectID) p.RenderError(http.StatusForbidden, "") return } err = dao.ToggleProjectPublicity(p.projectID, public) if err != nil { log.Errorf("Error while updating project, project id: %d, error: %v", projectID, err) p.RenderError(http.StatusInternalServerError, "Failed to update project") } }
// Get ... func (ua *UserAPI) Get() { if ua.userID == 0 { //list users if !ua.IsAdmin { log.Errorf("Current user, id: %d does not have admin role, can not list users", ua.currentUserID) ua.RenderError(http.StatusForbidden, "User does not have admin role") return } username := ua.GetString("username") userQuery := models.User{} if len(username) > 0 { userQuery.Username = "******" + username + "%" } userList, err := dao.ListUsers(userQuery) if err != nil { log.Errorf("Failed to get data from database, error: %v", err) ua.RenderError(http.StatusInternalServerError, "Failed to query from database") return } ua.Data["json"] = userList } else if ua.userID == ua.currentUserID || ua.IsAdmin { userQuery := models.User{UserID: ua.userID} u, err := dao.GetUser(userQuery) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) ua.CustomAbort(http.StatusInternalServerError, "Internal error.") } ua.Data["json"] = u } else { log.Errorf("Current user, id: %d does not have admin role, can not view other user's detail", ua.currentUserID) ua.RenderError(http.StatusForbidden, "User does not have admin role") return } ua.ServeJSON() }
// Post ... func (p *ProjectAPI) Post() { p.userID = p.ValidateUser() var req projectReq var public int p.DecodeJSONReq(&req) if req.Public { public = 1 } err := validateProjectReq(req) if err != nil { log.Errorf("Invalid project request, error: %v", err) p.RenderError(http.StatusBadRequest, fmt.Sprintf("invalid request: %v", err)) return } projectName := req.ProjectName exist, err := dao.ProjectExists(projectName) if err != nil { log.Errorf("Error happened checking project existence in db, error: %v, project name: %s", err, projectName) } if exist { p.RenderError(http.StatusConflict, "") return } project := models.Project{OwnerID: p.userID, Name: projectName, CreationTime: time.Now(), Public: public} projectID, err := dao.AddProject(project) if err != nil { log.Errorf("Failed to add project, error: %v", err) p.RenderError(http.StatusInternalServerError, "Failed to add project") } p.Redirect(http.StatusCreated, strconv.FormatInt(projectID, 10)) }
// ValidateUser checks if the request triggered by a valid user func (b *BaseAPI) ValidateUser() int { username, password, ok := b.Ctx.Request.BasicAuth() if ok { log.Infof("Requst with Basic Authentication header, username: %s", username) user, err := auth.Login(models.AuthModel{ Principal: username, Password: password, }) if err != nil { log.Errorf("Error while trying to login, username: %s, error: %v", username, err) user = nil } if user != nil { return user.UserID } } sessionUserID := b.GetSession("userId") if sessionUserID == nil { log.Warning("No user id in session, canceling request") b.CustomAbort(http.StatusUnauthorized, "") } userID := sessionUserID.(int) u, err := dao.GetUser(models.User{UserID: userID}) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) b.CustomAbort(http.StatusInternalServerError, "Internal error.") } if u == nil { log.Warningf("User was deleted already, user id: %d, canceling request.", userID) b.CustomAbort(http.StatusUnauthorized, "") } return userID }
// ResetPassword handles request from the reset page and reset password func (cc *CommonController) ResetPassword() { resetUUID := cc.GetString("reset_uuid") if resetUUID == "" { cc.CustomAbort(http.StatusBadRequest, "Reset uuid is blank.") } queryUser := models.User{ResetUUID: resetUUID} user, err := dao.GetUser(queryUser) if err != nil { log.Errorf("Error occurred in GetUser: %v", err) cc.CustomAbort(http.StatusInternalServerError, "Internal error.") } if user == nil { log.Error("User does not exist") cc.CustomAbort(http.StatusBadRequest, "User does not exist") } password := cc.GetString("password") if password != "" { user.Password = password err = dao.ResetUserPassword(*user) if err != nil { log.Errorf("Error occurred in ResetUserPassword: %v", err) cc.CustomAbort(http.StatusInternalServerError, "Internal error.") } } else { cc.CustomAbort(http.StatusBadRequest, "password_is_required") } }
// GetManifests handles GET /api/repositories/manifests func (ra *RepositoryAPI) GetManifests() { repoName := ra.GetString("repo_name") tag := ra.GetString("tag") if len(repoName) == 0 || len(tag) == 0 { ra.CustomAbort(http.StatusBadRequest, "repo_name or tag is nil") } projectName := getProjectName(repoName) project, err := dao.GetProjectByName(projectName) if err != nil { log.Errorf("failed to get project %s: %v", projectName, err) ra.CustomAbort(http.StatusInternalServerError, "") } if project.Public == 0 { userID := ra.ValidateUser() if !checkProjectPermission(userID, project.ProjectID) { ra.CustomAbort(http.StatusForbidden, "") } } rc, err := ra.initRepositoryClient(repoName) if err != nil { log.Errorf("error occurred while initializing repository client for %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } item := models.RepoItem{} mediaTypes := []string{schema1.MediaTypeManifest} _, _, payload, err := rc.PullManifest(tag, mediaTypes) if err != nil { if regErr, ok := err.(*registry_error.Error); ok { ra.CustomAbort(regErr.StatusCode, regErr.Detail) } log.Errorf("error occurred while getting manifest of %s:%s: %v", repoName, tag, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } mani := models.Manifest{} err = json.Unmarshal(payload, &mani) if err != nil { log.Errorf("Failed to decode json from response for manifests, repo name: %s, tag: %s, error: %v", repoName, tag, err) ra.RenderError(http.StatusInternalServerError, "Internal Server Error") return } v1Compatibility := mani.History[0].V1Compatibility err = json.Unmarshal([]byte(v1Compatibility), &item) if err != nil { log.Errorf("Failed to decode V1 field for repo, repo name: %s, tag: %s, error: %v", repoName, tag, err) ra.RenderError(http.StatusInternalServerError, "Internal Server Error") return } item.DurationDays = strconv.Itoa(int(time.Since(item.Created).Hours()/24)) + " days" ra.Data["json"] = item ra.ServeJSON() }
//sysadmin has all privileges to all projects func listRoles(userID int, projectID int64) ([]models.Role, error) { roles := make([]models.Role, 0, 1) isSysAdmin, err := dao.IsAdminRole(userID) if err != nil { log.Errorf("failed to determine whether the user %d is system admin: %v", userID, err) return roles, err } if isSysAdmin { role, err := dao.GetRoleByID(models.PROJECTADMIN) if err != nil { log.Errorf("failed to get role %d: %v", models.PROJECTADMIN, err) return roles, err } roles = append(roles, *role) return roles, nil } rs, err := dao.GetUserProjectRoles(userID, projectID) if err != nil { log.Errorf("failed to get user %d 's roles for project %d: %v", userID, projectID, err) return roles, err } roles = append(roles, rs...) return roles, nil }
// Get ... func (s *SearchAPI) Get() { userID, ok := s.GetSession("userId").(int) if !ok { userID = dao.NonExistUserID } keyword := s.GetString("q") isSysAdmin, err := dao.IsAdminRole(userID) if err != nil { log.Errorf("failed to check whether the user %d is system admin: %v", userID, err) s.CustomAbort(http.StatusInternalServerError, "internal error") } var projects []models.Project if isSysAdmin { projects, err = dao.GetAllProjects("") if err != nil { log.Errorf("failed to get all projects: %v", err) s.CustomAbort(http.StatusInternalServerError, "internal error") } } else { projects, err = dao.SearchProjects(userID) if err != nil { log.Errorf("failed to get user %d 's relevant projects: %v", userID, err) s.CustomAbort(http.StatusInternalServerError, "internal error") } } projectSorter := &models.ProjectSorter{Projects: projects} sort.Sort(projectSorter) projectResult := []map[string]interface{}{} for _, p := range projects { match := true if len(keyword) > 0 && !strings.Contains(p.Name, keyword) { match = false } if match { entry := make(map[string]interface{}) entry["id"] = p.ProjectID entry["name"] = p.Name entry["public"] = p.Public projectResult = append(projectResult, entry) } } repositories, err2 := cache.GetRepoFromCache() if err2 != nil { log.Errorf("Failed to get repos from cache, error: %v", err2) s.CustomAbort(http.StatusInternalServerError, "Failed to get repositories search result") } sort.Strings(repositories) repositoryResult := filterRepositories(repositories, projects, keyword) result := &searchResult{Project: projectResult, Repository: repositoryResult} s.Data["json"] = result s.ServeJSON() }
// Prepare validates the URL and parms func (ua *UserAPI) Prepare() { authMode := strings.ToLower(os.Getenv("AUTH_MODE")) if authMode == "" { authMode = "db_auth" } ua.AuthMode = authMode selfRegistration := strings.ToLower(os.Getenv("SELF_REGISTRATION")) if selfRegistration == "on" { ua.SelfRegistration = true } if ua.Ctx.Input.IsPost() { sessionUserID := ua.GetSession("userId") _, _, ok := ua.Ctx.Request.BasicAuth() if sessionUserID == nil && !ok { return } } ua.currentUserID = ua.ValidateUser() id := ua.Ctx.Input.Param(":id") if id == "current" { ua.userID = ua.currentUserID } else if len(id) > 0 { var err error ua.userID, err = strconv.Atoi(id) if err != nil { log.Errorf("Invalid user id, error: %v", err) ua.CustomAbort(http.StatusBadRequest, "Invalid user Id") } userQuery := models.User{UserID: ua.userID} u, err := dao.GetUser(userQuery) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) ua.CustomAbort(http.StatusInternalServerError, "Internal error.") } if u == nil { log.Errorf("User with Id: %d does not exist", ua.userID) ua.CustomAbort(http.StatusNotFound, "") } } var err error ua.IsAdmin, err = dao.IsAdminRole(ua.currentUserID) if err != nil { log.Errorf("Error occurred in IsAdminRole:%v", err) ua.CustomAbort(http.StatusInternalServerError, "Internal error.") } }
// Post handles POST request, and records audit log or refreshes cache based on event. func (n *NotificationHandler) Post() { var notification models.Notification err := json.Unmarshal(n.Ctx.Input.CopyBody(1<<32), ¬ification) if err != nil { log.Errorf("failed to decode notification: %v", err) return } events, err := filterEvents(¬ification) if err != nil { log.Errorf("failed to filter events: %v", err) return } for _, event := range events { repository := event.Target.Repository project := "" if strings.Contains(repository, "/") { project = repository[0:strings.LastIndex(repository, "/")] } tag := event.Target.Tag action := event.Action user := event.Actor.Name if len(user) == 0 { user = "******" } go func() { if err := dao.AccessLog(user, project, repository, tag, action); err != nil { log.Errorf("failed to add access log: %v", err) } }() if action == "push" { go func() { if err := cache.RefreshCatalogCache(); err != nil { log.Errorf("failed to refresh cache: %v", err) } }() operation := "" if action == "push" { operation = models.RepOpTransfer } go api.TriggerReplicationByRepository(repository, []string{tag}, operation) } } }
// FilterAccess modify the action list in access based on permission // determine if the request needs to be authenticated. func FilterAccess(username string, authenticated bool, a *token.ResourceActions) { if a.Type == "registry" && a.Name == "catalog" { log.Infof("current access, type: %s, name:%s, actions:%v \n", a.Type, a.Name, a.Actions) return } //clear action list to assign to new acess element after perm check. a.Actions = []string{} if a.Type == "repository" { if strings.Contains(a.Name, "/") { //Only check the permission when the requested image has a namespace, i.e. project projectName := a.Name[0:strings.LastIndex(a.Name, "/")] var permission string if authenticated { isAdmin, err := dao.IsAdminRole(username) if err != nil { log.Errorf("Error occurred in IsAdminRole: %v", err) } if isAdmin { exist, err := dao.ProjectExists(projectName) if err != nil { log.Errorf("Error occurred in CheckExistProject: %v", err) return } if exist { permission = "RWM" } else { permission = "" log.Infof("project %s does not exist, set empty permission for admin\n", projectName) } } else { permission, err = dao.GetPermission(username, projectName) if err != nil { log.Errorf("Error occurred in GetPermission: %v", err) return } } } if strings.Contains(permission, "W") { a.Actions = append(a.Actions, "push") } if strings.Contains(permission, "M") { a.Actions = append(a.Actions, "*") } if strings.Contains(permission, "R") || dao.IsProjectPublic(projectName) { a.Actions = append(a.Actions, "pull") } } } log.Infof("current access, type: %s, name:%s, actions:%v \n", a.Type, a.Name, a.Actions) }
// GetTags handles GET /api/repositories/tags func (ra *RepositoryAPI) GetTags() { repoName := ra.GetString("repo_name") if len(repoName) == 0 { ra.CustomAbort(http.StatusBadRequest, "repo_name is nil") } projectName := getProjectName(repoName) project, err := dao.GetProjectByName(projectName) if err != nil { log.Errorf("failed to get project %s: %v", projectName, err) ra.CustomAbort(http.StatusInternalServerError, "") } if project.Public == 0 { userID := ra.ValidateUser() if !checkProjectPermission(userID, project.ProjectID) { ra.CustomAbort(http.StatusForbidden, "") } } rc, err := ra.initRepositoryClient(repoName) if err != nil { log.Errorf("error occurred while initializing repository client for %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } tags := []string{} ts, err := rc.ListTag() if err != nil { regErr, ok := err.(*registry_error.Error) if !ok { log.Errorf("error occurred while listing tags of %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } // TODO remove the logic if the bug of registry is fixed // It's a workaround for a bug of registry: when listing tags of // a repository which is being pushed, a "NAME_UNKNOWN" error will // been returned, while the catalog API can list this repository. if regErr.StatusCode != http.StatusNotFound { ra.CustomAbort(regErr.StatusCode, regErr.Detail) } } tags = append(tags, ts...) sort.Strings(tags) ra.Data["json"] = tags ra.ServeJSON() }
// List ... func (p *ProjectAPI) List() { var projectList []models.Project projectName := p.GetString("project_name") if len(projectName) > 0 { projectName = "%" + projectName + "%" } var public int var err error isPublic := p.GetString("is_public") if len(isPublic) > 0 { public, err = strconv.Atoi(isPublic) if err != nil { log.Errorf("Error parsing public property: %v, error: %v", isPublic, err) p.CustomAbort(http.StatusBadRequest, "invalid project Id") } } isAdmin := false if public == 1 { projectList, err = dao.GetPublicProjects(projectName) } else { //if the request is not for public projects, user must login or provide credential p.userID = p.ValidateUser() isAdmin, err = dao.IsAdminRole(p.userID) if err != nil { log.Errorf("Error occured in check admin, error: %v", err) p.CustomAbort(http.StatusInternalServerError, "Internal error.") } if isAdmin { projectList, err = dao.GetAllProjects(projectName) } else { projectList, err = dao.GetUserRelevantProjects(p.userID, projectName) } } if err != nil { log.Errorf("Error occured in get projects info, error: %v", err) p.CustomAbort(http.StatusInternalServerError, "Internal error.") } for i := 0; i < len(projectList); i++ { if public != 1 { if isAdmin { projectList[i].Role = models.PROJECTADMIN } if projectList[i].Role == models.PROJECTADMIN { projectList[i].Togglable = true } } projectList[i].RepoCount = getRepoCountByProject(projectList[i].Name) } p.Data["json"] = projectList p.ServeJSON() }
func TestGetRepoJobToStop(t *testing.T) { jobs := [...]models.RepJob{ models.RepJob{ Repository: "library/ubuntu", PolicyID: policyID, Operation: "transfer", Status: models.JobRunning, }, models.RepJob{ Repository: "library/ubuntu", PolicyID: policyID, Operation: "transfer", Status: models.JobFinished, }, models.RepJob{ Repository: "library/ubuntu", PolicyID: policyID, Operation: "transfer", Status: models.JobCanceled, }, } var err error var i int64 var ids []int64 for _, j := range jobs { i, err = AddRepJob(j) ids = append(ids, i) if err != nil { log.Errorf("Failed to add Job: %+v, error: %v", j, err) return } } res, err := GetRepJobToStop(policyID) if err != nil { log.Errorf("Failed to Get Jobs, error: %v", err) return } //time.Sleep(15 * time.Second) if len(res) != 1 { log.Errorf("Expected length of stoppable jobs, expected:1, in fact: %d", len(res)) return } for _, id := range ids { err = DeleteRepJob(id) if err != nil { log.Errorf("Failed to delete job, id: %d, error: %v", id, err) return } } }
// Get total projects and repos of the user func (s *StatisticAPI) Get() { 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.") } var projectList []models.Project if isAdmin { projectList, err = dao.GetAllProjects("") } else { projectList, err = dao.GetUserRelevantProjects(s.userID, "") } if err != nil { log.Errorf("Error occured in QueryProject, error: %v", err) s.CustomAbort(http.StatusInternalServerError, "Internal error.") } proMap := map[string]int{} proMap["my_project_count"] = 0 proMap["my_repo_count"] = 0 proMap["public_project_count"] = 0 proMap["public_repo_count"] = 0 var publicProjects []models.Project publicProjects, err = dao.GetPublicProjects("") if err != nil { log.Errorf("Error occured in QueryPublicProject, error: %v", err) s.CustomAbort(http.StatusInternalServerError, "Internal error.") } proMap["public_project_count"] = len(publicProjects) for i := 0; i < len(publicProjects); i++ { proMap["public_repo_count"] += getRepoCountByProject(publicProjects[i].Name) } if isAdmin { proMap["total_project_count"] = len(projectList) proMap["total_repo_count"] = getTotalRepoCount() } for i := 0; i < len(projectList); i++ { if isAdmin { projectList[i].Role = models.PROJECTADMIN } if projectList[i].Role == models.PROJECTADMIN || projectList[i].Role == models.DEVELOPER || projectList[i].Role == models.GUEST { proMap["my_project_count"]++ proMap["my_repo_count"] += getRepoCountByProject(projectList[i].Name) } } s.Data["json"] = proMap s.ServeJSON() }
func filterEvents(notification *models.Notification) ([]*models.Event, error) { events := []*models.Event{} for _, event := range notification.Events { isManifest, err := regexp.MatchString(manifestPattern, event.Target.MediaType) if err != nil { log.Errorf("failed to match the media type against pattern: %v", err) continue } if !isManifest { continue } //pull and push manifest by docker-client if strings.HasPrefix(event.Request.UserAgent, "docker") && (event.Action == "pull" || event.Action == "push") { events = append(events, &event) continue } //push manifest by docker-client or job-service if strings.ToLower(strings.TrimSpace(event.Request.UserAgent)) == "harbor-registry-client" && event.Action == "push" { events = append(events, &event) continue } } return events, nil }
// DecodeJSONReq decodes a json request func (b *BaseAPI) DecodeJSONReq(v interface{}) { err := json.Unmarshal(b.Ctx.Input.CopyBody(1<<32), v) if err != nil { log.Errorf("Error while decoding the json request, error: %v", err) b.CustomAbort(http.StatusBadRequest, "Invalid json request") } }
// FilterAccessLog handles GET to /api/projects/{}/logs func (p *ProjectAPI) FilterAccessLog() { p.userID = p.ValidateUser() var filter models.AccessLog p.DecodeJSONReq(&filter) username := filter.Username keywords := filter.Keywords beginTime := time.Unix(filter.BeginTimestamp, 0) endTime := time.Unix(filter.EndTimestamp, 0) query := models.AccessLog{ProjectID: p.projectID, Username: "******" + username + "%", Keywords: keywords, BeginTime: beginTime, BeginTimestamp: filter.BeginTimestamp, EndTime: endTime, EndTimestamp: filter.EndTimestamp} log.Infof("Query AccessLog: begin: %v, end: %v, keywords: %s", query.BeginTime, query.EndTime, query.Keywords) accessLogList, err := dao.GetAccessLogs(query) if err != nil { log.Errorf("Error occurred in GetAccessLogs, error: %v", err) p.CustomAbort(http.StatusInternalServerError, "Internal error.") } p.Data["json"] = accessLogList p.ServeJSON() }
// Head ... func (p *ProjectAPI) Head() { projectName := p.GetString("project_name") if len(projectName) == 0 { p.CustomAbort(http.StatusBadRequest, "project_name is needed") } project, err := dao.GetProjectByName(projectName) if err != nil { log.Errorf("error occurred in GetProjectByName: %v", err) p.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } // only public project can be Headed by user without login if project != nil && project.Public == 1 { return } userID := p.ValidateUser() if project == nil { p.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound)) } if !checkProjectPermission(userID, project.ProjectID) { p.CustomAbort(http.StatusForbidden, http.StatusText(http.StatusForbidden)) } }
//InitDB initializes the database func InitDB() { orm.RegisterDriver("mysql", orm.DRMySQL) addr := os.Getenv("MYSQL_HOST") port := os.Getenv("MYSQL_PORT") username := os.Getenv("MYSQL_USR") password := os.Getenv("MYSQL_PWD") log.Debugf("db url: %s:%s, db user: %s", addr, port, username) dbStr := username + ":" + password + "@tcp(" + addr + ":" + port + ")/registry" ch := make(chan int, 1) go func() { var err error var c net.Conn for { c, err = net.DialTimeout("tcp", addr+":"+port, 20*time.Second) if err == nil { c.Close() ch <- 1 } else { log.Errorf("failed to connect to db, retry after 2 seconds :%v", err) time.Sleep(2 * time.Second) } } }() select { case <-ch: case <-time.After(60 * time.Second): panic("Failed to connect to DB after 60 seconds") } err := orm.RegisterDataBase("default", "mysql", dbStr) if err != nil { panic(err) } }
func init() { //conf/app.conf -> os.Getenv("config_path") configPath := os.Getenv("CONFIG_PATH") if len(configPath) != 0 { log.Infof("Config path: %s", configPath) beego.LoadAppConfig("ini", configPath) } beego.AddFuncMap("i18n", i18n.Tr) langs := strings.Split(beego.AppConfig.String("lang::types"), "|") names := strings.Split(beego.AppConfig.String("lang::names"), "|") supportLanguages = make(map[string]langType) langTypes = make([]*langType, 0, len(langs)) for i, lang := range langs { t := langType{ Lang: lang, Name: names[i], } langTypes = append(langTypes, &t) supportLanguages[lang] = t if err := i18n.SetMessage(lang, "static/i18n/"+"locale_"+lang+".ini"); err != nil { log.Errorf("Fail to set message file: %s", err.Error()) } } }
// NewLogger create a logger for a speicified job func NewLogger(jobID int64) *log.Logger { logFile := GetJobLogPath(jobID) d := filepath.Dir(logFile) if _, err := os.Stat(d); os.IsNotExist(err) { err := os.MkdirAll(d, 0660) if err != nil { log.Errorf("Failed to create directory for log file %s, the error: %v", logFile, err) } } f, err := os.OpenFile(logFile, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660) if err != nil { log.Errorf("Failed to open log file %s, the log of job %d will be printed to standard output, the error: %v", logFile, jobID, err) f = os.Stdout } return log.New(f, log.NewTextFormatter(), log.InfoLevel) }
// Start kicks off the statemachine to transit from current state to s, and moves on // It will search the transit map if the next state is "_continue", and // will enter error state if there's more than one possible path when next state is "_continue" func (sm *SM) Start(s string) { n, err := sm.EnterState(s) log.Debugf("Job id: %d, next state from handler: %s", sm.JobID, n) for len(n) > 0 && err == nil { if d := sm.getDesiredState(); len(d) > 0 { log.Debugf("Job id: %d. Desired state: %s, will ignore the next state from handler", sm.JobID, d) n = d sm.setDesiredState("") continue } if n == models.JobContinue && len(sm.Transitions[sm.CurrentState]) == 1 { for n = range sm.Transitions[sm.CurrentState] { break } log.Debugf("Job id: %d, Continue to state: %s", sm.JobID, n) continue } if n == models.JobContinue && len(sm.Transitions[sm.CurrentState]) != 1 { log.Errorf("Job id: %d, next state is continue but there are %d possible next states in transition table", sm.JobID, len(sm.Transitions[sm.CurrentState])) err = fmt.Errorf("Unable to continue") break } n, err = sm.EnterState(n) log.Debugf("Job id: %d, next state from handler: %s", sm.JobID, n) } if err != nil { log.Warningf("Job id: %d, the statemachin will enter error state due to error: %v", sm.JobID, err) sm.EnterState(models.JobError) } }