package rbac import ( "context" "net/http" "git.haelnorr.com/h/golib/hws" "git.haelnorr.com/h/oslstats/internal/contexts" "git.haelnorr.com/h/oslstats/internal/db" "git.haelnorr.com/h/oslstats/internal/permissions" "git.haelnorr.com/h/oslstats/internal/roles" "github.com/pkg/errors" "github.com/uptrace/bun" ) // LoadPermissionsMiddleware loads user permissions into context after authentication // MUST run AFTER auth.Authenticate() middleware func (c *Checker) LoadPermissionsMiddleware() hws.Middleware { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { user := db.CurrentUser(r.Context()) // Build permission cache cache := &contexts.PermissionCache{ Permissions: make(map[permissions.Permission]bool), Roles: make(map[roles.Role]bool), } defer func() { ctx := context.WithValue(r.Context(), contexts.PermissionCacheKey, cache) next.ServeHTTP(w, r.WithContext(ctx)) }() if user == nil { return } var roles_ []*db.Role var perms []*db.Permission if err := db.WithTxFailSilently(r.Context(), c.conn, func(ctx context.Context, tx bun.Tx) error { var err error roles_, err = user.GetRoles(ctx, tx) if err != nil { return errors.Wrap(err, "user.GetRoles") } perms, err = user.GetPermissions(ctx, tx) if err != nil { return errors.Wrap(err, "user.GetPermissions") } return nil }); err != nil { c.s.LogError(hws.HWSError{ Message: "Database error", Error: err, Level: hws.ErrorERROR, }) return } // Check for wildcard permission hasWildcard := false for _, perm := range perms { cache.Permissions[perm.Name] = true if perm.Name == permissions.Wildcard { hasWildcard = true } } cache.HasWildcard = hasWildcard for _, role := range roles_ { cache.Roles[role.Name] = true } }) } }