Skip to content

Commit

Permalink
Allow Organization Listing to be Scoped (#233)
Browse files Browse the repository at this point in the history
You can specify an `email` query parameter that will look for all
organizations that exist for a named user.  If the user doesn't exist,
then this returns a 404.  If the caller doesn't have the global
`identity:users` permission this returns a 403.
  • Loading branch information
spjmurray authored Mar 5, 2025
1 parent 82c06de commit ccfe40e
Show file tree
Hide file tree
Showing 8 changed files with 359 additions and 275 deletions.
4 changes: 2 additions & 2 deletions charts/identity/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ description: A Helm chart for deploying Unikorn's IdP

type: application

version: v0.2.59-rc6
appVersion: v0.2.59-rc6
version: v0.2.59-rc7
appVersion: v0.2.59-rc7

icon: https://raw.githubusercontent.com/unikorn-cloud/assets/main/images/logos/dark-on-light/icon.png

Expand Down
4 changes: 2 additions & 2 deletions pkg/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,8 @@ func (h *Handler) DeleteApiV1OrganizationsOrganizationIDOauth2providersProviderI
w.WriteHeader(http.StatusOK)
}

func (h *Handler) GetApiV1Organizations(w http.ResponseWriter, r *http.Request) {
result, err := organizations.New(h.client, h.namespace).List(r.Context(), h.rbac)
func (h *Handler) GetApiV1Organizations(w http.ResponseWriter, r *http.Request, params openapi.GetApiV1OrganizationsParams) {
result, err := organizations.New(h.client, h.namespace).List(r.Context(), h.rbac, params.Email)
if err != nil {
errors.HandleError(w, r, err)
return
Expand Down
19 changes: 15 additions & 4 deletions pkg/handler/organizations/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,13 @@ func (c *Client) list(ctx context.Context) (map[string]*unikornv1.Organization,
return out, nil
}

func (c *Client) List(ctx context.Context, rbacClient *rbac.RBAC) (openapi.Organizations, error) {
//nolint:cyclop
func (c *Client) List(ctx context.Context, rbacClient *rbac.RBAC, email *string) (openapi.Organizations, error) {
// This is the only special case in the system. When requesting organizations we
// will have an unscoped ACL, so can check for global access to all organizations.
// If we don't have that then we need to use RBAC to get a list of organizations we are
// members of and return only them.
if err := rbac.AllowGlobalScope(ctx, "identity:organizations", openapi.Read); err == nil {
if err := rbac.AllowGlobalScope(ctx, "identity:organizations", openapi.Read); err == nil && email == nil {
var result unikornv1.OrganizationList

if err := c.client.List(ctx, &result, &client.ListOptions{Namespace: c.namespace}); err != nil {
Expand All @@ -187,9 +188,19 @@ func (c *Client) List(ctx context.Context, rbacClient *rbac.RBAC) (openapi.Organ
return nil, errors.OAuth2ServerError("failed to list organizations").WithError(err)
}

user, err := rbacClient.GetActiveUser(ctx, info.Userinfo.Sub)
subject := info.Userinfo.Email

if email != nil {
if err := rbac.AllowGlobalScope(ctx, "identity:users", openapi.Read); err != nil {
return nil, errors.HTTPForbidden("user not permitted to read users globally").WithError(err)
}

subject = email
}

user, err := rbacClient.GetActiveUser(ctx, *subject)
if err != nil {
return nil, errors.OAuth2ServerError("failed to list active subjects").WithError(err)
return nil, errors.HTTPNotFound().WithError(err)
}

selector := labels.SelectorFromSet(map[string]string{
Expand Down
52 changes: 45 additions & 7 deletions pkg/openapi/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 16 additions & 3 deletions pkg/openapi/router.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ccfe40e

Please sign in to comment.