// 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 } }
// Post ... func (p *ProjectAPI) Post() { p.userID = p.ValidateUser() var req projectReq p.DecodeJSONReq(&req) public := req.Public 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) dup, _ := regexp.MatchString(dupProjectPattern, err.Error()) if dup { p.RenderError(http.StatusConflict, "") } else { p.RenderError(http.StatusInternalServerError, "Failed to add project") } return } p.Redirect(http.StatusCreated, strconv.FormatInt(projectID, 10)) }
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 }
// 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() }
// FilterAccess modify the action list in access based on permission func FilterAccess(username string, 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" { repoSplit := strings.Split(a.Name, "/") repoLength := len(repoSplit) if repoLength > 1 { //Only check the permission when the requested image has a namespace, i.e. project var projectName string registryURL := config.ExtRegistryURL() if repoSplit[0] == registryURL { projectName = repoSplit[1] log.Infof("Detected Registry URL in Project Name. Assuming this is a notary request and setting Project Name as %s\n", projectName) } else { projectName = repoSplit[0] } var permission string if len(username) > 0 { 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) }
// 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") } }
// 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, t.secretKey) 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() }
//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 }
// Delete : policies which are disabled and have no running jobs // can be deleted func (pa *RepPolicyAPI) Delete() { id := pa.GetIDFromURL() policy, err := dao.GetRepPolicy(id) if err != nil { log.Errorf("failed to get policy %d: %v", id, err) pa.CustomAbort(http.StatusInternalServerError, "") } if policy == nil || policy.Deleted == 1 { pa.CustomAbort(http.StatusNotFound, "") } if policy.Enabled == 1 { pa.CustomAbort(http.StatusPreconditionFailed, "plicy is enabled, can not be deleted") } jobs, err := dao.GetRepJobByPolicy(id) if err != nil { log.Errorf("failed to get jobs of policy %d: %v", id, err) pa.CustomAbort(http.StatusInternalServerError, "") } for _, job := range jobs { if job.Status == models.JobRunning || job.Status == models.JobRetrying || job.Status == models.JobPending { pa.CustomAbort(http.StatusPreconditionFailed, "policy has running/retrying/pending jobs, can not be deleted") } } if err = dao.DeleteRepPolicy(id); err != nil { log.Errorf("failed to delete policy %d: %v", id, err) pa.CustomAbort(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, t.secretKey) 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 }
// 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)) } }
// FilterAccessLog handles GET to /api/projects/{}/logs func (p *ProjectAPI) FilterAccessLog() { p.userID = p.ValidateUser() var query models.AccessLog p.DecodeJSONReq(&query) if !checkProjectPermission(p.userID, p.projectID) { log.Warningf("Current user, user id: %d does not have permission to read accesslog of project, id: %d", p.userID, p.projectID) p.RenderError(http.StatusForbidden, "") return } query.ProjectID = p.projectID query.BeginTime = time.Unix(query.BeginTimestamp, 0) query.EndTime = time.Unix(query.EndTimestamp, 0) page, pageSize := p.GetPaginationParams() total, err := dao.GetTotalOfAccessLogs(query) if err != nil { log.Errorf("failed to get total of access log: %v", err) p.CustomAbort(http.StatusInternalServerError, "") } logs, err := dao.GetAccessLogs(query, pageSize, pageSize*(page-1)) if err != nil { log.Errorf("failed to get access log: %v", err) p.CustomAbort(http.StatusInternalServerError, "") } p.SetPaginationHeader(total, page, pageSize) p.Data["json"] = logs p.ServeJSON() }
// Get ... func (s *SearchAPI) Get() { userID, _, ok := s.GetUserIDForRequest() 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.GetProjects("") 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, err := cache.GetRepoFromCache() if err != nil { log.Errorf("failed to list repositories: %v", err) s.CustomAbort(http.StatusInternalServerError, "") } sort.Strings(repositories) repositoryResult := filterRepositories(repositories, projects, keyword) result := &searchResult{Project: projectResult, Repository: repositoryResult} s.Data["json"] = result s.ServeJSON() }
// List filters jobs according to the parameters func (ra *RepJobAPI) List() { policyID, err := ra.GetInt64("policy_id") if err != nil || policyID <= 0 { ra.CustomAbort(http.StatusBadRequest, "invalid policy_id") } policy, err := dao.GetRepPolicy(policyID) if err != nil { log.Errorf("failed to get policy %d: %v", policyID, err) ra.CustomAbort(http.StatusInternalServerError, "") } if policy == nil { ra.CustomAbort(http.StatusNotFound, fmt.Sprintf("policy %d not found", policyID)) } repository := ra.GetString("repository") status := ra.GetString("status") var startTime *time.Time startTimeStr := ra.GetString("start_time") if len(startTimeStr) != 0 { i, err := strconv.ParseInt(startTimeStr, 10, 64) if err != nil { ra.CustomAbort(http.StatusBadRequest, "invalid start_time") } t := time.Unix(i, 0) startTime = &t } var endTime *time.Time endTimeStr := ra.GetString("end_time") if len(endTimeStr) != 0 { i, err := strconv.ParseInt(endTimeStr, 10, 64) if err != nil { ra.CustomAbort(http.StatusBadRequest, "invalid end_time") } t := time.Unix(i, 0) endTime = &t } page, pageSize := ra.GetPaginationParams() jobs, total, err := dao.FilterRepJobs(policyID, repository, status, startTime, endTime, pageSize, pageSize*(page-1)) if err != nil { log.Errorf("failed to filter jobs according policy ID %d, repository %s, status %s, start time %v, end time %v: %v", policyID, repository, status, startTime, endTime, err) ra.CustomAbort(http.StatusInternalServerError, "") } ra.SetPaginationHeader(total, page, pageSize) ra.Data["json"] = jobs ra.ServeJSON() }
// Get ... func (ra *RepositoryAPI) Get() { projectID, err := ra.GetInt64("project_id") if err != nil || projectID <= 0 { ra.CustomAbort(http.StatusBadRequest, "invalid project_id") } page, pageSize := ra.GetPaginationParams() project, err := dao.GetProjectByID(projectID) if err != nil { log.Errorf("failed to get project %d: %v", projectID, err) ra.CustomAbort(http.StatusInternalServerError, "") } if project == nil { ra.CustomAbort(http.StatusNotFound, fmt.Sprintf("project %d not found", projectID)) } if project.Public == 0 { var userID int if svc_utils.VerifySecret(ra.Ctx.Request) { userID = 1 } else { userID = ra.ValidateUser() } if !checkProjectPermission(userID, projectID) { ra.CustomAbort(http.StatusForbidden, "") } } repositories, err := getReposByProject(project.Name, ra.GetString("q")) if err != nil { log.Errorf("failed to get repository: %v", err) ra.CustomAbort(http.StatusInternalServerError, "") } total := int64(len(repositories)) if (page-1)*pageSize > total { repositories = []string{} } else { repositories = repositories[(page-1)*pageSize:] } if page*pageSize <= total { repositories = repositories[:pageSize] } ra.SetPaginationHeader(total, page, pageSize) ra.Data["json"] = repositories ra.ServeJSON() }
// 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, _ := utils.ParseRepository(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 == nil { ra.CustomAbort(http.StatusNotFound, fmt.Sprintf("project %s not found", projectName)) } 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() }
// 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.") } }
// FilterAccess modify the action list in access based on permission func FilterAccess(username string, 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 len(username) > 0 { 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) }
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 renders optional menu, Admin user has "Add User" menu func (omc *OptionalMenuController) Get() { sessionUserID := omc.GetSession("userId") var hasLoggedIn bool var allowAddNew bool var isAdminForLdap bool var allowSettingAccount bool if sessionUserID != nil { hasLoggedIn = true userID := sessionUserID.(int) u, err := dao.GetUser(models.User{UserID: userID}) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) omc.CustomAbort(http.StatusInternalServerError, "Internal error.") } if u == nil { log.Warningf("User was deleted already, user id: %d, canceling request.", userID) omc.CustomAbort(http.StatusUnauthorized, "") } omc.Data["Username"] = u.Username if userID == 1 { isAdminForLdap = true } if omc.AuthMode == "db_auth" || isAdminForLdap { allowSettingAccount = true } isAdmin, err := dao.IsAdminRole(sessionUserID.(int)) if err != nil { log.Errorf("Error occurred in IsAdminRole: %v", err) omc.CustomAbort(http.StatusInternalServerError, "") } if isAdmin && omc.AuthMode == "db_auth" { allowAddNew = true } } omc.Data["AddNew"] = allowAddNew omc.Data["SettingAccount"] = allowSettingAccount omc.Data["HasLoggedIn"] = hasLoggedIn omc.TplName = "optional-menu.htm" omc.Render() }
// 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) }
// GetUserIDForRequest tries to get user ID from basic auth header and session. // It returns the user ID, whether need further verification(when the id is from session) and if the action is successful func (b *BaseAPI) GetUserIDForRequest() (int, bool, bool) { 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 { // User login successfully no further check required. return user.UserID, false, true } } sessionUserID, ok := b.GetSession("userId").(int) if ok { // The ID is from session return sessionUserID, true, true } log.Debug("No valid user id in session.") return 0, false, false }
// 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") } }
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()) } } }
// 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) } }
func init() { var err error Cache, err = cache.NewCache("memory", `{"interval":720}`) if err != nil { log.Errorf("Failed to initialize cache, error:%v", err) } }
func filterEvents(notification *models.Notification) ([]*models.Event, error) { events := []*models.Event{} for _, event := range notification.Events { log.Debugf("receive an event: \n----ID: %s \n----target: %s:%s \n----digest: %s \n----action: %s \n----mediatype: %s \n----user-agent: %s", event.ID, event.Target.Repository, event.Target.Tag, event.Target.Digest, event.Action, event.Target.MediaType, event.Request.UserAgent) 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 or vic if (strings.HasPrefix(event.Request.UserAgent, "docker") || strings.HasPrefix(event.Request.UserAgent, vicPrefix)) && (event.Action == "pull" || event.Action == "push") { events = append(events, &event) log.Debugf("add event to collect: %s", event.ID) 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) log.Debugf("add event to collect: %s", event.ID) continue } } return events, nil }
// 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)) } }
// Delete ... func (ua *UserAPI) Delete() { if !ua.IsAdmin { log.Warningf("current user, id: %d does not have admin role, can not remove user", ua.currentUserID) ua.RenderError(http.StatusForbidden, "User does not have admin role") return } // TODO read from conifg authMode := os.Getenv("AUTH_MODE") if authMode == "ldap_auth" { ua.CustomAbort(http.StatusForbidden, "user can not be deleted in LDAP authentication mode") } if ua.currentUserID == ua.userID { ua.CustomAbort(http.StatusForbidden, "can not delete yourself") } var err error err = dao.DeleteUser(ua.userID) if err != nil { log.Errorf("Failed to delete data from database, error: %v", err) ua.RenderError(http.StatusInternalServerError, "Failed to delete User") return } }
// Post ... func (pma *ProjectMemberAPI) Post() { currentUserID := pma.currentUserID projectID := pma.project.ProjectID if !hasProjectAdminRole(currentUserID, projectID) { log.Warningf("Current user, id: %d does not have project admin role for project, id:", currentUserID, projectID) pma.RenderError(http.StatusForbidden, "") return } var req memberReq pma.DecodeJSONReq(&req) username := req.Username userID := checkUserExists(username) if userID <= 0 { log.Warningf("User does not exist, user name: %s", username) pma.RenderError(http.StatusNotFound, "User does not exist") return } rolelist, err := dao.GetUserProjectRoles(userID, projectID) if err != nil { log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err) pma.CustomAbort(http.StatusInternalServerError, "Internal error.") } if len(rolelist) > 0 { log.Warningf("user is already added to project, user id: %d, project id: %d", userID, projectID) pma.RenderError(http.StatusConflict, "user is ready in project") return } if len(req.Roles) <= 0 || len(req.Roles) > 1 { pma.CustomAbort(http.StatusBadRequest, "only one role is supported") } rid := req.Roles[0] if !(rid == models.PROJECTADMIN || rid == models.DEVELOPER || rid == models.GUEST) { pma.CustomAbort(http.StatusBadRequest, "invalid role") } err = dao.AddProjectMember(projectID, userID, rid) if err != nil { log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", projectID, userID, rid) pma.RenderError(http.StatusInternalServerError, "Failed to update data in database") return } }