Skip to content
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

Allow disabling object-level roles #475

Closed
wants to merge 6 commits into from

Conversation

AlanCoding
Copy link
Member

@AlanCoding AlanCoding commented Jun 15, 2024

Fixes #424

Enabling work for AAP-25268

@AlanCoding AlanCoding added the blocked Can not be done right now for some reason, but want to do later label Jun 17, 2024
@AlanCoding AlanCoding marked this pull request as ready for review June 17, 2024 15:46
@AlanCoding AlanCoding requested review from fosterseth and relrod June 17, 2024 16:20
@AlanCoding AlanCoding added Ready for review This PR is ready for review either initially or comments have been address and removed blocked Can not be done right now for some reason, but want to do later labels Jun 17, 2024
Copy link

sonarcloud bot commented Jun 21, 2024

Copy link
Member

@john-westcott-iv john-westcott-iv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a couple minor comments which likely don't need to be address if they are non-issues.

@@ -60,7 +60,11 @@ def get(self, request, format=None):
if cls is None:
cls_repr = 'system'
else:
info = permission_registry.get_info(cls)
if not info.allow_object_roles:
continue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we warn or info if we hit this continue?

if model._meta.model_name not in self._registry:
info = ModelPermissionInfo(model, **kwargs)
self._registry[info.model_name] = info
elif self._registry[model._meta.model_name] is model:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will account for the app_name because we are comparing the whole model right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will yell at you if you register 2 models with the same name, even if they're in different apps. Proxy models are fine, but don't register the original... and also register the proxy.

return None
return model._meta.get_field(parent_field_name).related_model
return model._meta.get_field(info.parent_field_name).related_model
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to register a model with a parent but not the parent?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, very much so, InstanceGroup does not have a related organization. So you can have an object-level role, but no organization association. This call was made in fairly recent development, but before any work on the new RBAC system had started.

Even more interestingly, the Instance model is the one case where not being organization-scoped is truly defensible (an instance is a property of the cluster...), but object-level roles might also not make sense. It's more likely that you would only want to delegate permissions with system-level roles. Because you're kind of either managing an AWX cluster or you're not... it's 1 thing, and sub-dividing it doesn't make a ton of sense.

return None
return model._meta.get_field(parent_field_name).related_model
return model._meta.get_field(info.parent_field_name).related_model

def get_parent_fd_name(self, model) -> Optional[str]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be really nice to rename this to get_parent_field_name for clarity.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed to merge this PR if its too much.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used that method name once, and only in eda-server tests, so it shouldn't be difficult to rename. But it is a cross-repo change.

if not managed:
if not permission_registry.object_roles_enabled(role_model):
print_model = role_model._meta.verbose_name if role_model else 'global roles'
raise ValidationError({'content_type': f'Creating roles for the {print_model} model is disabled'})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the right termonology in the exception? the global roles model is disabled.
Also, we should likely translate these strings if they can get raised to the browser.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the flow of this isn't good. The method object_roles_enabled unconditionally returns True if passed None, and the None value signifies a global role. So, it would be more clear to have this block be if (not managed) and role_model:, so we're only considering this condition when it's an object-based (as opposed to system) role definition.

@john-westcott-iv john-westcott-iv added Ready To Merge comments left This PR was reviewed with comments and removed Ready for review This PR is ready for review either initially or comments have been address labels Jun 21, 2024
@AlanCoding
Copy link
Member Author

Retrospective:

The problem here is the creator roles. Permissions are an inter-connected system. If someone has "add" permission for a model, then after creating an object, they need the object-level admin role (or whatever role is configured for creators) after creation.

This means that we could only disable object-level roles created in the API, but they would still have to exist generally. This is an additional piece of information which would have to be communicated to clients, and increases confusion.

For overall system stability and sanity I am backing out of this approach. I may also close the issue as a won't-fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comments left This PR was reviewed with comments Ready To Merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow disabling object-level permissions for a given model in the RBAC registry
2 participants