headless_api: gate request on new Repo.automation_permission (bug 1971103)#1044
headless_api: gate request on new Repo.automation_permission (bug 1971103)#1044
Conversation
|
View this pull request in Lando to land it once approved. |
b5850ff to
09a737f
Compare
| if not repo.user_can_use_automation(request.user): | ||
| error = f"User {request.user.email} is not allowed to use this API. Missing permission: {repo.automation_permission}." | ||
| logger.info( | ||
| error, | ||
| extra={"user": request.user.email, "token": request.auth.token_prefix}, | ||
| ) | ||
| return 403, {"details": error} |
There was a problem hiding this comment.
@cgsheeh With this in place, I wonder if
lando/src/lando/headless_api/api.py
Lines 83 to 86 in 48d0876
There was a problem hiding this comment.
I think it can be removed. That permission is currently used for "does this user have automation API access". With the more granular control, we can simply remove their automation-level permissions instead.
There was a problem hiding this comment.
Ok, I'll file a bug to remove later, so we can confirm that the new system works adequately first.
cgsheeh
left a comment
There was a problem hiding this comment.
One more thing that isn't clear to me from this is whether we intend to use scm levels as the automation_permission. I guess these will be the SCM_ALLOW_DIRECT_PUSH permission in most cases? I think we could make an argument that we could manage these permissions without SCM levels, for example our own custom create_automation_firefox. This would allow us to use Django groups to manage access to teams (sheriffs, thunderbird, etc) without having to use the manual checks we have for SCM levels.
| def _user_has_direct_permission(self, user: User, required_permission: Permission): | ||
| """ | ||
| Test that the user has permission to push to this repo. | ||
| Test that the user has a specific permission directly rather than via a role. |
There was a problem hiding this comment.
Checking that a user has a specific permission from LDAP/mirrored groups makes sense for scm levels. I would imagine granting permissions to all users in a specific group would be useful for us in the future (for example, creating a sheriff group and allowing all sheriffs access to the automation API).
There was a problem hiding this comment.
This is for Django roles, rather than LDAP groups. I'm not sure we have a mapping for groups to Django roles at the moment. It would certainly be useful.
FWIW, this _user_has_direct_permission is there avoid granting super-users SCM permissions they don't have outright. We could loosen the check and allow role-inheritane if needed, but I don't think that's the case at the moment.
There was a problem hiding this comment.
Thinking more about this, in a way, if we grant sheriff_firefox or scm_sheriff_firefox we'd create an implicit group of users who have this permission. Unless we want to associate more than just that permission to them (maybe scm3 comes with at the same time), I think we are already here.
There was a problem hiding this comment.
FWIW I think this will be resolved in a much cleaner way once we stop using superusers in Lando.
| # Use this field to enable/disable access to this repo via the automation API. | ||
| automation_enabled = models.BooleanField(default=False) | ||
| automation_permission = models.CharField( | ||
| default="main.scm_direct_push", |
There was a problem hiding this comment.
See my other comment about changing this to a ForeignKey.
However if we keep this as a CharField, the default should just be None/blank, which would be a proxy for "there is no permission which can grant you access". We could potentially remove the automation_enabled flag as well, though there's probably an argument to be made that enabling the flag without wiping the permission would be ideal.
There was a problem hiding this comment.
None by default would be good, but this means that firefox repos will find themselves without direct push access when we deploy that change. Not a big deal, but something to remember to fix manually at the time of deploy.
We can also add a dedicated data-migration step that would set it correctly for fx repos on migrate, but we don't have a very clean way to do this at the moment https://bugzilla.mozilla.org/show_bug.cgi?id=2013991 @zzzeid maybe it's an opportunity to work on this pattern?
There was a problem hiding this comment.
It would be good to set up the data migration "framework" so to speak, even if it's as simple as a management command that calls other management commands (the latter being the actual migrations). They can probably all sit in their own app.
However, for this particular migration I would say it's probably fine to do the changes manually in the admin, while Lando is in maintenance.
There was a problem hiding this comment.
🌮 I added a stub migration script, that we can run manually during the upgrade.
| if not repo.user_can_use_automation(request.user): | ||
| error = f"User {request.user.email} is not allowed to use this API. Missing permission: {repo.automation_permission}." | ||
| logger.info( | ||
| error, | ||
| extra={"user": request.user.email, "token": request.auth.token_prefix}, | ||
| ) | ||
| return 403, {"details": error} |
There was a problem hiding this comment.
I think it can be removed. That permission is currently used for "does this user have automation API access". With the more granular control, we can simply remove their automation-level permissions instead.
With the change, we're aiming to continue have that link to SCM levels in LDAP. My reasoning is that doing so lines up with current access practices and processes, which means we don't need to manage it in an ad hoc manner in Lando. With the coming comm and nss migration, this will likely require the creation of dedicated LDAP groups similar to Happy to discuss more, though (: |
72af2a4 to
87209ae
Compare
| # Use this field to enable/disable access to this repo via the automation API. | ||
| automation_enabled = models.BooleanField(default=False) | ||
| automation_permission = models.CharField( | ||
| default="main.scm_direct_push", |
There was a problem hiding this comment.
It would be good to set up the data migration "framework" so to speak, even if it's as simple as a management command that calls other management commands (the latter being the actual migrations). They can probably all sit in their own app.
However, for this particular migration I would say it's probably fine to do the changes manually in the admin, while Lando is in maintenance.
e14ccbd to
4324fef
Compare
There was a problem hiding this comment.
@zzzeid here's a very stubby data-migration script built for immediate purpose, and we can iterate on it when working on bug 2013991 for real.
There was a problem hiding this comment.
Sounds good. I have some comments but I can save them to a different discussion when we are working on bug 2013991 for real.
86c23c7 to
b168ea8
Compare
There was a problem hiding this comment.
Sounds good. I have some comments but I can save them to a different discussion when we are working on bug 2013991 for real.
| def _user_has_direct_permission(self, user: User, required_permission: Permission): | ||
| """ | ||
| Test that the user has permission to push to this repo. | ||
| Test that the user has a specific permission directly rather than via a role. |
There was a problem hiding this comment.
FWIW I think this will be resolved in a much cleaner way once we stop using superusers in Lando.
d679156 to
d6e0938
Compare
|
Rebase and force-push to work around landing problems https://lando.moz.tools/landings/35783/ |
d6e0938 to
05cc56e
Compare
|
Rebase and squash fixups... https://lando.moz.tools/landings/35790/ |
headless_api: gate API request to user having the correct repo's automation_permission test: test automation_api gating on repo automation_permission migrations: renumber after merge repo: fail closed on empty permissions strings tests: better coverage of Repo._user_has_direct_permissions repo: rename automation_permission to required_automation_permission utils: add stub data migration command (bug 2013991) tests: fix permission issues Update src/lando/main/models/repo.py Co-authored-by: Zeid <2043828+zzzeid@users.noreply.github.com> pr comments test: no need to create the scm_allow_direct_push permission
05cc56e to
af050af
Compare
|
Squish squash 🙄 https://lando.moz.tools/landings/35793/ |
…1103) r=sheehan,zeid * repo: add `automation_permission` and `user_can_use_automation()` * headless_api: gate API request to user having the correct repo's `required_automation_permission` * test: test headless_api gating on repo `required_automation_permission` * repo: fail closed on empty permissions strings * utils: add stub data migration command (bug 2013991) Pull request: #1044
|
Pull request closed by commit 9e90472 |
automation_permissionanduser_can_use_automation()required_automation_permissionrequired_automation_permission