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

[Request] an API endpoint to find out what permissions are granted with the provided key #3418

Closed
fieldOfView opened this issue Jan 6, 2020 · 10 comments
Labels
done Done but not yet released request Feature request
Milestone

Comments

@fieldOfView
Copy link
Contributor

Is your feature request related to a problem? Please describe.
OctoPrint 1.4.0 introduces granular permissions. Given a (limited) list of permissions available for the user accessing OctoPrint through the API, an application may want to disable parts of its UI (eg disable the jog controls if the Permissions.CONTROL permission is not granted for the user).

Currently there is no way for an application to query the user and/or permissions that are granted to the user accessing the API. It is possible to query this information if the user name is known, but if an application is only given an appkey to work with, there is no way for the application to know the user name associated with the appkey.

Describe the solution you'd like
An API endpoint to list the available permissions, eg: /api/access/permissions/available. This would return either a subset of '/api/access/permissions' (with all the metadata for each permission) or only a list of permission keys.

An alternative that would have other benefits is some way to find out the username that is associated with the provided key, which could then be used with the `/api/access/users/[username]' endpoint. It could also be an option to allow the API key as an argument in '/api/access/users/[username or API key]'.

Describe alternatives you've considered
The current alternative is for the application just to try and respond if a permission denied error is returned by OctoPrint and ask the user for forgiveness.

Additional context
I can do the work adding the API endpoint(s) if we can come up with what would be the most optimal solution.

@GitIssueBot GitIssueBot added the request Feature request label Jan 6, 2020
@foosel
Copy link
Member

foosel commented Jan 13, 2020

There already is something that you can do now, which is doing a passive login request against /api/login. It will return the user object which includes all the needs (group or role) assigned by permissions, and additional permissions assigned to the user specifically:

$ curl -H "X-Api-Key: ..." -X POST http://localhost:5000/api/login?passive=true
{
  "_is_external_client": false,
  "active": true,
  "admin": true,
  "apikey": "...",
  "groups": [
    "admins",
    "users"
  ],
  "name": "admin",
  "needs": {
    "group": [
      "admins",
      "users"
    ],
    "role": [
      "plugin_pluginmanager_manage",
      "slice",
      "webcam",
      "status",
      "timelapse_delete",
      "files_delete",
      "plugin_printer_safety_check_display",
      "files_list",
      "plugin_softwareupdate_check",
      "timelapse_admin",
      "plugin_logging_manage",
      "system",
      "plugin_softwareupdate_update",
      "plugin_announcements_read",
      "plugin_backup_access",
      "control",
      "monitor_terminal",
      "timelapse_download",
      "admin",
      "plugin_pluginmanager_install",
      "files_upload",
      "plugin_announcements_manage",
      "plugin_action_command_prompt_interact",
      "print",
      "gcodeviewer",
      "settings",
      "connection",
      "timelapse_list",
      "files_select",
      "plugin_appkeys_admin",
      "files_download"
    ]
  },
  "permissions": [],
  "roles": [
    "user",
    "admin"
  ],
  "session": "...",
  "settings": {
    "interface": {
      "language": "_default"
    }
  },
  "user": true
}

However it might indeed make sense to provide a list of the actual permission identifiers associated with the user instead of the needs defined therein since those might change internally.

Since I'll definitely need another RC based on the current feedback, I'll see that I can look into this for that still. Makes sense to have as part of the new permission system right from the get go.

@foosel foosel added this to the 1.4.0 milestone Jan 13, 2020
@fieldOfView
Copy link
Contributor Author

For the record, I can work with the passive login solution especially since that also returns data in 1.3.x.

foosel added a commit that referenced this issue Jan 22, 2020
@foosel foosel added the done Done but not yet released label Jan 22, 2020
@foosel
Copy link
Member

foosel commented Jan 22, 2020

That is now implemented by the above commit under /api/access/current or /api/access/current/permissions respectively.

@fieldOfView
Copy link
Contributor Author

Awesome. For the benefit of anyone reading this issue and not the code: the endpoints are actually /api/access/user and /api/access/user/permissions.

It is a bit strange that the output of /api/access/user is so different from /api/access/users/[username], but I'll happily accept that.

@foosel
Copy link
Member

foosel commented Jan 23, 2020

It is a bit strange that the output of /api/access/user is so different from /api/access/users/[username], but I'll happily accept that.

Yeah, I'm not completely happy with that either yet, but didn't have a good idea... maybe /api/access/currentuser instead (and as a sidenote, apologies for the mixup of endpoint names, at that point I had been writing the missing API docs for the whole /api/access namespace for the past hours and was a bit 😫). That would make it distinct enough from /api/access/users and also better transport what it is. Thoughts?

@fieldOfView
Copy link
Contributor Author

I don't actually mind the user vs users (and I like the simplicity of /api/access/user), but find it strange that one lists permissions, the other lists roles. But maybe that's because I am still not quite sure of the effective difference between roles and permissions.

@foosel
Copy link
Member

foosel commented Jan 23, 2020

I don't actually mind the user vs users (and I like the simplicity of /api/access/user)

I fear it could get confusing in the future ("was it user or users... damnit").

But maybe that's because I am still not quite sure of the effective difference between roles and permissions.

It's permissions and needs actually. The needs are what is actually used to decide if some action is allowed or not by flask. Can be something like "role:settings" or "group:admin" or "id:foosel" and so on. Permissions only model the "role:*" stuff of that. So you assign a permission to a user, that contains one or more role needs. How the needs are named and such is an implementation detail that while it's being exposed on the API (for reasons which right now I'm not even sure about anymore) it shouldn't actually be considered stable or at least stably named. I can vouch for the SETTINGS permission to stay named SETTINGS, but at one point I might have to slightly tweak the associated needs, or add others too (e.g. something that requires a username to match as well). Hope this makes it a bit clearer. It's a bit tricky to make this usable by third parties without confusing everyone XD

foosel added a commit that referenced this issue Jan 24, 2020
Update documentation accordingly.

See also #3418
@foosel
Copy link
Member

foosel commented Jan 24, 2020

Slight change of plans. It now lives under /api/currentuser and I've gotten rid of the ./name, ./permissions and ./groups endpoints underneath that for now - feels like needless granularity.

@foosel
Copy link
Member

foosel commented Jan 24, 2020

Documentation is updated as well (staging only for now).

@foosel
Copy link
Member

foosel commented Mar 4, 2020

1.4.0 has been released.

@foosel foosel closed this as completed Mar 4, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
done Done but not yet released request Feature request
Projects
None yet
Development

No branches or pull requests

3 participants