//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 }
// 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) }
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 (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() }
// Get total projects and repos of the user func (s *StatisticAPI) Get() { statistic := map[string]int64{} n, err := dao.GetTotalOfProjects("", 1) 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("") 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 { n, err := dao.GetTotalOfProjects("") if err != nil { log.Errorf("failed to get total of projects: %v", err) s.CustomAbort(http.StatusInternalServerError, "") } statistic[MPC] = n statistic[TPC] = n n, err = dao.GetTotalOfRepositories("") if err != nil { log.Errorf("failed to get total of repositories: %v", err) s.CustomAbort(http.StatusInternalServerError, "") } statistic[MRC] = n statistic[TRC] = n } else { n, err := dao.GetTotalOfUserRelevantProjects(s.userID, "") if err != nil { log.Errorf("failed to get total of projects for user %d: %v", s.userID, err) s.CustomAbort(http.StatusInternalServerError, "") } statistic[MPC] = n n, err = dao.GetTotalOfUserRelevantRepositories(s.userID, "") if err != nil { log.Errorf("failed to get total of repositories for user %d: %v", s.userID, err) s.CustomAbort(http.StatusInternalServerError, "") } statistic[MRC] = n } s.Data["json"] = statistic s.ServeJSON() }
// Prepare for validating user if an admin. func (sia *SystemInfoAPI) Prepare() { sia.currentUserID = sia.ValidateUser() var err error sia.isAdmin, err = dao.IsAdminRole(sia.currentUserID) if err != nil { log.Errorf("Error occurred in IsAdminRole:%v", err) sia.CustomAbort(http.StatusInternalServerError, "Internal error.") } }
// Prepare validates whether the user has system admin role func (pa *RepPolicyAPI) Prepare() { uid := pa.ValidateUser() var err error isAdmin, err := dao.IsAdminRole(uid) if err != nil { log.Errorf("Failed to Check if the user is admin, error: %v, uid: %d", err, uid) } if !isAdmin { pa.CustomAbort(http.StatusForbidden, "") } }
// 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.") } }
// Prepare validates the URL and parms func (ia *InternalAPI) Prepare() { var currentUserID int currentUserID = ia.ValidateUser() isAdmin, err := dao.IsAdminRole(currentUserID) if err != nil { log.Errorf("Error occurred in IsAdminRole:%v", err) ia.CustomAbort(http.StatusInternalServerError, "Internal error.") } if !isAdmin { log.Error("Guests doesn't have the permisson to request harbor internal API.") ia.CustomAbort(http.StatusForbidden, "Guests doesn't have the permisson to request harbor internal API.") } }
// 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) }
// Prepare validates the user func (t *TargetAPI) Prepare() { t.secretKey = config.SecretKey() userID := t.ValidateUser() isSysAdmin, err := dao.IsAdminRole(userID) if err != nil { log.Errorf("error occurred in IsAdminRole: %v", err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } if !isSysAdmin { t.CustomAbort(http.StatusForbidden, http.StatusText(http.StatusForbidden)) } }
// Get renders the admin options page func (aoc *AdminOptionController) Get() { sessionUserID, ok := aoc.GetSession("userId").(int) if ok { isAdmin, err := dao.IsAdminRole(sessionUserID) if err != nil { log.Errorf("Error occurred in IsAdminRole: %v", err) } if isAdmin { aoc.Forward("page_title_admin_option", "admin-options.htm") return } } aoc.Redirect("/dashboard", 302) }
// Get renders project page func (pc *ProjectController) Get() { var err error isSysAdmin := false uid := pc.GetSession("userId") if uid != nil { isSysAdmin, err = dao.IsAdminRole(uid) if err != nil { log.Warningf("Error in checking Admin Role for user, id: %d, error: %v", uid, err) isSysAdmin = false } } pc.Data["CanCreate"] = !config.OnlyAdminCreateProject() || isSysAdmin pc.Forward("page_title_project", "project.htm") }
// 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() }
// Get renders the add new page func (anc *AddNewController) Get() { sessionUserID := anc.GetSession("userId") anc.Data["AddNew"] = false if sessionUserID != nil { isAdmin, err := dao.IsAdminRole(sessionUserID.(int)) if err != nil { log.Errorf("Error occurred in IsAdminRole: %v", err) anc.CustomAbort(http.StatusInternalServerError, "") } if isAdmin && anc.AuthMode == "db_auth" { anc.Data["AddNew"] = true anc.Forward("page_title_add_new", "sign-up.htm") return } } anc.CustomAbort(http.StatusUnauthorized, "Status Unauthorized.") }
// Post ... func (p *ProjectAPI) Post() { p.userID = p.ValidateUser() isSysAdmin, err := dao.IsAdminRole(p.userID) if err != nil { log.Errorf("Failed to check admin role: %v", err) } if !isSysAdmin && config.OnlyAdminCreateProject() { log.Errorf("Only sys admin can create project") p.RenderError(http.StatusForbidden, "Only system admin can create project") return } 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)) }
// Prepare validates that whether user has system admin role func (ra *RepJobAPI) Prepare() { uid := ra.ValidateUser() isAdmin, err := dao.IsAdminRole(uid) if err != nil { log.Errorf("Failed to Check if the user is admin, error: %v, uid: %d", err, uid) } if !isAdmin { ra.CustomAbort(http.StatusForbidden, "") } idStr := ra.Ctx.Input.Param(":id") if len(idStr) != 0 { id, err := strconv.ParseInt(idStr, 10, 64) if err != nil { ra.CustomAbort(http.StatusBadRequest, "ID is invalid") } ra.jobID = id } }
// List ... func (p *ProjectAPI) List() { var total int64 var public int var err error page, pageSize := p.GetPaginationParams() var projectList []models.Project projectName := p.GetString("project_name") 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 { total, err = dao.GetTotalOfProjects(projectName, 1) if err != nil { log.Errorf("failed to get total of projects: %v", err) p.CustomAbort(http.StatusInternalServerError, "") } projectList, err = dao.GetProjects(projectName, 1, pageSize, pageSize*(page-1)) if err != nil { log.Errorf("failed to get projects: %v", err) p.CustomAbort(http.StatusInternalServerError, "") } } 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 { total, err = dao.GetTotalOfProjects(projectName) if err != nil { log.Errorf("failed to get total of projects: %v", err) p.CustomAbort(http.StatusInternalServerError, "") } projectList, err = dao.GetProjects(projectName, pageSize, pageSize*(page-1)) if err != nil { log.Errorf("failed to get projects: %v", err) p.CustomAbort(http.StatusInternalServerError, "") } } else { total, err = dao.GetTotalOfUserRelevantProjects(p.userID, projectName) if err != nil { log.Errorf("failed to get total of projects: %v", err) p.CustomAbort(http.StatusInternalServerError, "") } projectList, err = dao.GetUserRelevantProjects(p.userID, projectName, pageSize, pageSize*(page-1)) if err != nil { log.Errorf("failed to get projects: %v", err) p.CustomAbort(http.StatusInternalServerError, "") } } } for i := 0; i < len(projectList); i++ { if public != 1 { if isAdmin { projectList[i].Role = models.PROJECTADMIN } else { roles, err := dao.GetUserProjectRoles(p.userID, projectList[i].ProjectID) if err != nil { log.Errorf("failed to get user's project role: %v", err) p.CustomAbort(http.StatusInternalServerError, "") } projectList[i].Role = roles[0].RoleID } if projectList[i].Role == models.PROJECTADMIN { projectList[i].Togglable = true } } repos, err := dao.GetRepositoryByProjectName(projectList[i].Name) if err != nil { log.Errorf("failed to get repositories of project %s: %v", projectList[i].Name, err) p.CustomAbort(http.StatusInternalServerError, "") } projectList[i].RepoCount = len(repos) } p.SetPaginationHeader(total, page, pageSize) p.Data["json"] = projectList p.ServeJSON() }
// Prepare extracts the language information from request and populate data for rendering templates. func (b *BaseController) Prepare() { var lang string var langHasChanged bool var showDownloadCert bool langRequest := b.GetString("lang") if langRequest != "" { lang = langRequest langHasChanged = true } else { langCookie, err := b.Ctx.Request.Cookie("language") if err != nil { log.Errorf("Error occurred in Request.Cookie: %v", err) } if langCookie != nil { lang = langCookie.Value } else { al := b.Ctx.Request.Header.Get("Accept-Language") if len(al) > 4 { al = al[:5] // Only compare first 5 letters. if i18n.IsExist(al) { lang = al } } langHasChanged = true } } if langHasChanged { if _, exist := supportLanguages[lang]; !exist { //Check if support the request language. lang = defaultLang //Set default language if not supported. } cookies := &http.Cookie{ Name: "language", Value: lang, HttpOnly: true, Path: "/", } http.SetCookie(b.Ctx.ResponseWriter, cookies) } curLang := langType{ Lang: lang, } restLangs := make([]*langType, 0, len(langTypes)-1) for _, v := range langTypes { if lang != v.Lang { restLangs = append(restLangs, v) } else { curLang.Name = v.Name } } // Set language properties. b.Lang = lang b.Data["Lang"] = curLang.Lang b.Data["CurLang"] = curLang.Name b.Data["RestLangs"] = restLangs authMode := config.AuthMode() if authMode == "" { authMode = "db_auth" } b.AuthMode = authMode b.Data["AuthMode"] = b.AuthMode useCompressedJS := os.Getenv("USE_COMPRESSED_JS") if useCompressedJS == "on" { b.UseCompressedJS = true } m, err := filepath.Glob(filepath.Join("static", "resources", "js", "harbor.app.min.*.js")) if err != nil || len(m) == 0 { b.UseCompressedJS = false } b.SelfRegistration = config.SelfRegistration() b.Data["SelfRegistration"] = config.SelfRegistration() sessionUserID := b.GetSession("userId") if sessionUserID != nil { isAdmin, err := dao.IsAdminRole(sessionUserID.(int)) if err != nil { log.Errorf("Error occurred in IsAdminRole: %v", err) } if isAdmin { if _, err := os.Stat(defaultRootCert); !os.IsNotExist(err) { showDownloadCert = true } } } b.Data["ShowDownloadCert"] = showDownloadCert }