-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
authz: Make root project/org no longer special #1092
Conversation
This instead relies on keycloak claims to determine if a user is a member of staff or not. Thus removing the "specialness" from the root project and organization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regardless of whether we remove superadmins entirely, I think making it a bool on the claims is an improvement.
For testing if nothing else...
@@ -307,20 +307,5 @@ CREATE TRIGGER update_policy_status | |||
EXECUTE PROCEDURE update_policy_status(); | |||
|
|||
-- Create default root organization and get id so we can create the root project |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do we create the root project? Also, what does "root project" mean here? It's it just a name?
(The previous root org was special, but actually didn't normally have any useful groups / projects in it.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It means nothing, I could just delete this actually. We could use a root project if we wanted the phantom root we talked about, but maybe we should just remove what we don't use.
|
||
func containsSuperadminRole(openIdToken openid.Token) bool { | ||
if realmAccess, ok := openIdToken.Get("realm_access"); ok { | ||
if realms, ok := realmAccess.(map[string]interface{}); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to cast to map[string] [] string
once here, and avoid the subsequent casts? (You can also use the default map lookup property then...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was just copy pasta, I guess we could do that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a suggestion so you can compare.
@@ -48,10 +49,11 @@ func TestKeysHandler(t *testing.T) { | |||
|
|||
ctx := auth.WithPermissionsContext(context.Background(), auth.UserPermissions{ | |||
UserId: 1, | |||
OrganizationId: rootOrganization, | |||
ProjectIds: []uuid.UUID{rootProject}, | |||
OrganizationId: orgID, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need these, or just the super admin claim?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wanted it to work, some of these will probably be deleted later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wanted it to work, some of these will probably be deleted later.
ProjectIds: []uuid.UUID{rootProject}, | ||
OrganizationId: orgID, | ||
ProjectIds: []uuid.UUID{projectID}, | ||
IsStaff: true, // TODO: remove this | ||
Roles: []auth.RoleInfo{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need these roles, either?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to remove this structure in the same PR that would remove the roles db table
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, though I was going to suggest refactoring to have a func testSuperAdmin() auth.UserPermissions
method to centralize this throughout all the tests. We might also have func testOrgAdmin(org string)
and func testNormalUser(project string)
methods to encapsulate this.
if err != nil { | ||
return nil, status.Errorf(codes.Internal, "failed to create default organization records: %s", err) | ||
} | ||
// otherwise self-enroll user, by creating a new org and project and making the user an admin of those |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does "otherwise" make sense here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotta remove this old comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reflecting further, it actually seems like it might be a good pattern if superadmins didn't actually have organizations -- it would discourage casual use of the super-powered token (and presumably reduce the risk of losing one).
|
||
func containsSuperadminRole(openIdToken openid.Token) bool { | ||
if realmAccess, ok := openIdToken.Get("realm_access"); ok { | ||
if realms, ok := realmAccess.(map[string]interface{}); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a suggestion so you can compare.
if realms, ok := realmAccess.(map[string]interface{}); ok { | ||
if roles, ok := realms["roles"]; ok { | ||
if userRoles, ok := roles.([]interface{}); ok { | ||
if slices.Contains(userRoles, "superadmin") { | ||
return true | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if realms, ok := realmAccess.(map[string]interface{}); ok { | |
if roles, ok := realms["roles"]; ok { | |
if userRoles, ok := roles.([]interface{}); ok { | |
if slices.Contains(userRoles, "superadmin") { | |
return true | |
} | |
} | |
} | |
if realms, ok := realmAccess.(map[string][]string); ok { | |
return slices.Contains(realms["roles"], "superadmin") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason, the proposal didn't quite work and results in superuser calls always getting permission denied. I'm not gonna spend too much time on optimizing this as we hope to get rid of this in the near future.
ProjectIds: []uuid.UUID{rootProject}, | ||
OrganizationId: orgID, | ||
ProjectIds: []uuid.UUID{projectID}, | ||
IsStaff: true, // TODO: remove this | ||
Roles: []auth.RoleInfo{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, though I was going to suggest refactoring to have a func testSuperAdmin() auth.UserPermissions
method to centralize this throughout all the tests. We might also have func testOrgAdmin(org string)
and func testNormalUser(project string)
methods to encapsulate this.
This instead relies on keycloak claims to determine if a user is a member of staff
or not. Thus removing the "specialness" from the root project and organization.
Note that this is simply an intermediary step before we start removing the superadmin user entirely.