// loadCtx is a pre-request wrapper function that populates a model.Context from request vars, // and attaches it to the request. func (ra *restAPI) loadCtx(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) taskId := vars["task_id"] buildId := vars["build_id"] versionId := vars["version_id"] patchId := vars["patch_id"] projectId := vars["project_id"] ctx, err := model.LoadContext(taskId, buildId, versionId, patchId, projectId) if err != nil { // Some database lookup failed when fetching the data - log it ra.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error loading project context: %v", err)) return } if ctx.ProjectRef != nil && ctx.ProjectRef.Private && GetUser(r) == nil { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } if ctx.Patch != nil && GetUser(r) == nil { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } context.Set(r, RestContext, &ctx) next(w, r) } }
// LoadProjectContext builds a projectContext from vars in the request's URL. // This is done by reading in specific variables and inferring other required // context variables when necessary (e.g. loading a project based on the task). func (uis *UIServer) LoadProjectContext(rw http.ResponseWriter, r *http.Request) (projectContext, error) { dbUser := GetUser(r) vars := mux.Vars(r) taskId := vars["task_id"] buildId := vars["build_id"] versionId := vars["version_id"] patchId := vars["patch_id"] projectId := uis.getRequestProjectId(r) pc := projectContext{AuthRedirect: uis.UserManager.IsRedirect()} isSuperUser := (dbUser != nil) && auth.IsSuperUser(uis.Settings, dbUser) err := pc.populateProjectRefs(dbUser != nil, isSuperUser, dbUser) if err != nil { return pc, err } // If we still don't have a default projectId, just use the first project in the list // if there is one. if len(projectId) == 0 && len(pc.AllProjects) > 0 { projectId = pc.AllProjects[0].Identifier } // Build a model.Context using the data available. ctx, err := model.LoadContext(taskId, buildId, versionId, patchId, projectId) pc.Context = ctx if err != nil { return pc, err } // set the cookie for the next request if a project was found if ctx.ProjectRef != nil { ctx.Project, err = model.FindProject("", ctx.ProjectRef) if err != nil { return pc, err } // A project was found, update the project cookie for subsequent request. http.SetCookie(rw, &http.Cookie{ Name: ProjectCookieName, Value: ctx.ProjectRef.Identifier, Path: "/", Expires: time.Now().Add(7 * 24 * time.Hour), }) } if len(uis.GetAppPlugins()) > 0 { pluginNames := []string{} for _, p := range uis.GetAppPlugins() { pluginNames = append(pluginNames, p.Name()) } pc.PluginNames = pluginNames } return pc, nil }