예제 #1
0
파일: utils.go 프로젝트: vmware/harbor
//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
}
예제 #2
0
// 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)
}
예제 #3
0
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
}
예제 #4
0
파일: search.go 프로젝트: vmware/harbor
// 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()
}
예제 #5
0
파일: statistic.go 프로젝트: vmware/harbor
// 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()
}
예제 #6
0
// 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.")
	}
}
예제 #7
0
// 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, "")
	}
}
예제 #8
0
파일: user.go 프로젝트: vmware/harbor
// 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.")
	}

}
예제 #9
0
파일: internal.go 프로젝트: vmware/harbor
// 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.")
	}
}
예제 #10
0
파일: authutils.go 프로젝트: vmware/harbor
// 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)
}
예제 #11
0
// 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))
	}
}
예제 #12
0
// 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)
}
예제 #13
0
// 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")
}
예제 #14
0
// 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()

}
예제 #15
0
파일: addnew.go 프로젝트: vmware/harbor
// 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.")
}
예제 #16
0
// 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))
}
예제 #17
0
// 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
	}

}
예제 #18
0
// 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()
}
예제 #19
0
// 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
}