// Authorize validates privileges for the current user. Each route must have // an array of privileges that point which users can make a call to it. // // Note: // // It is assumed that ValidateAuth was called before this function, or at // least some other session check was done before this. func Authorize(h httputils.ContextHandler) httputils.ContextHandler { return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { var ( requiredRoles []string sessionData *httputils.SessionData route routes.Route ok bool ) sessionData, ok = ctx.Value("sessionData").(*httputils.SessionData) if !ok { httputils.WriteError(w, http.StatusInternalServerError, "") return fmt.Errorf("authorize: could not cast value as session data: %s", ctx.Value("sessionData")) } route, ok = ctx.Value("route").(routes.Route) if !ok { httputils.WriteError(w, http.StatusInternalServerError, "") return fmt.Errorf("authorize: could not cast value as route: %s", ctx.Value("route")) } requiredRoles = route.RequiredRoles() if len(requiredRoles) == 0 { return h(ctx, w, r) } for _, role := range requiredRoles { if role == "ADMIN" && sessionData.IsAdmin { return h(ctx, w, r) } else if role == "TEACHER" && sessionData.IsTeacher { return h(ctx, w, r) } } http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return nil } }
// handleWithMiddlewares applies all middlewares to the specified route. Some // middleware functions are applied depending on the route's properties, such // as ValidateAuth and Authorize middlewares. These last 2 functions require // that the route RequiresAuth() and that RequiredRoles() > 0. func (s *Server) handleWithMiddlewares(route routes.Route) httputils.ContextHandler { return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { serverCtx := context.WithValue(ctx, "cookieStore", s.cookieStore) serverCtx = context.WithValue(serverCtx, "route", route) serverCtx = context.WithValue(serverCtx, "config", s.cfg) h := route.HandlerFunc() h = handlers.HandleHTTPError(h) h = handlers.GzipContent(h) if route.RequiresAuth() { if requiredRoles := route.RequiredRoles(); len(requiredRoles) > 0 { h = handlers.Authorize(h) } h = handlers.ValidateAuth(h) } return h(serverCtx, w, r) } }