Skip to content

Commit

Permalink
EVEREST-1104 | API endpoint for fetching permissions of the currently…
Browse files Browse the repository at this point in the history
… logged in user (#472)
  • Loading branch information
mayankshah1607 authored Jul 4, 2024
1 parent ca08607 commit d6fce8a
Show file tree
Hide file tree
Showing 6 changed files with 633 additions and 335 deletions.
349 changes: 187 additions & 162 deletions api/everest-server.gen.go

Large diffs are not rendered by default.

15 changes: 9 additions & 6 deletions api/everest.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"net/http"
"slices"

"github.com/casbin/casbin/v2"
"github.com/getkin/kin-openapi/openapi3filter"
"github.com/golang-jwt/jwt/v5"
casbinmiddleware "github.com/labstack/echo-contrib/casbin"
Expand All @@ -49,11 +50,12 @@ import (

// EverestServer represents the server struct.
type EverestServer struct {
config *config.EverestConfig
l *zap.SugaredLogger
echo *echo.Echo
kubeClient *kubernetes.Kubernetes
sessionMgr *session.Manager
config *config.EverestConfig
l *zap.SugaredLogger
echo *echo.Echo
kubeClient *kubernetes.Kubernetes
sessionMgr *session.Manager
rbacEnforcer *casbin.Enforcer
}

// NewEverestServer creates and configures everest API.
Expand Down Expand Up @@ -205,10 +207,11 @@ func (e *EverestServer) rbacMiddleware(ctx context.Context, basePath string) (ec
if err != nil {
return nil, errors.Join(err, errors.New("could not create casbin enforcer"))
}
e.rbacEnforcer = enforcer

return casbinmiddleware.MiddlewareWithConfig(casbinmiddleware.Config{
Skipper: rbac.Skipper,
UserGetter: rbac.UserGetter,
UserGetter: rbac.GetUser,
EnforceHandler: rbac.NewEnforceHandler(basePath, enforcer),
}), nil
}
Expand Down
53 changes: 53 additions & 0 deletions api/permissions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package api

import (
"errors"
"net/http"

"github.com/AlekSi/pointer"
"github.com/labstack/echo/v4"
"go.uber.org/zap"

"github.com/percona/everest/api/rbac"
)

// GetUserPermissions returns the permissions for the currently logged in user.
func (e *EverestServer) GetUserPermissions(c echo.Context) error {
user, err := rbac.GetUser(c)
if err != nil {
e.l.Error("Failed to get user from context: ", zap.Error(err))
return err
}

permissions, err := e.rbacEnforcer.GetImplicitPermissionsForUser(user)
if err != nil {
e.l.Error("Failed to get implicit permissions: ", zap.Error(err))
return err
}

if err := e.resolveRoles(user, permissions); err != nil {
e.l.Error(err)
return err
}

return c.JSON(http.StatusOK, &UserPermissions{
Permissions: pointer.To(permissions),
})
}

// For a given set of `permissions` for a `user`, this function
// will resolve all roles for the user.
func (e *EverestServer) resolveRoles(user string, permissions [][]string) error {
userRoles, err := e.rbacEnforcer.GetRolesForUser(user)
if err != nil {
return errors.Join(err, errors.New("cannot get user roles"))
}
for _, role := range userRoles {
for i, perm := range permissions {
if perm[0] == role {
permissions[i][0] = user
}
}
}
return nil
}
5 changes: 3 additions & 2 deletions api/rbac/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ func NewEnforcer(ctx context.Context, kubeClient *kubernetes.Kubernetes, l *zap.
return enforcer, refreshEnforcerInBackground(ctx, kubeClient, enforcer, l)
}

// UserGetter is a function that extracts the user from the JWT token.
func UserGetter(c echo.Context) (string, error) {
// GetUser extracts the user from the JWT token in the context.
func GetUser(c echo.Context) (string, error) {
token, ok := c.Get("user").(*jwt.Token) // by default token is stored under `user` key
if !ok {
return "", errors.New("failed to get token from context")
Expand Down Expand Up @@ -185,6 +185,7 @@ func Skipper(c echo.Context) bool {
"/resources",
"/namespaces",
"/settings",
"/permissions",
}
path := strings.TrimPrefix(c.Request().URL.Path, "/v1")
return slices.Contains(skipPaths, path)
Expand Down
Loading

0 comments on commit d6fce8a

Please sign in to comment.