Open NotActuallyTerry opened 1 year ago
It's possible to query for user via custom attribute, see https://stackoverflow.com/questions/54667407/how-to-get-users-by-custom-attributes-in-keycloak This would allow LTPermissions to query for the specified user simply by passing the user's Minecraft username to the API
Random notes from some command line testing:
Curl to get initial access/refresh token
curl -X POST https://auth.cocytus.services/realms/master/protocol/openid-connect/token --user admin-cli:REDACTED -H 'content-type: application/x-www-form-urlencoded' -d 'username=ltpermissions-dev&password=REDACTED&grant_type=password'
Gives a response like
{
"access_token":"ey...",
"expires_in":600,
"refresh_expires_in":1800,
"refresh_token":"ey...",
"token_type":"Bearer",
"not-before-policy":0,
"session_state":"...",
"scope":"profile email"
}
with these tokens the mod probably needs to run a check periodically as to whether the access token has expired, could probably do this in the server tick
steps to fetch user groups:
query by minecraft username:
curl -v -H "Authorization: Bearer $auth_token" 'https://auth.cocytus.services/admin/realms/master/users?q=minecraftUsername:AshhhleyyyB'
Extract user id from response:
[
{
"id":"d25d85a5-5d93-4a3f-b535-daee4fb88080",
"createdTimestamp":1692614614582,
"username":"ashhhleyyy",
"enabled":true,
"totp":false,
"emailVerified":true,
"firstName":"Ashley",
"lastName":"",
"email":"...",
"attributes":{"minecraftUsername":["AshhhleyyyB"]},"disableableCredentialTypes":[],"requiredActions":[],"notBefore":0,
"access":{"manageGroupMembership":true,"view":true,"mapRoles":true,"impersonate":true,"manage":true}
}
]
user id can be used to query the list of user groups
curl -v -H "Authorization: Bearer $auth_token" 'https://auth.cocytus.services/admin/realms/master/users/d25d85a5-5d93-4a3f-b535-daee4fb88080/groups'
then provide a config mapping keycloak group id -> ltpermissions roles, as well as functionality for whitelisting
[
{"id":"a2b39cb0-8b0e-4ba5-a887-d96fcf452811","name":"Builders","path":"/Builders"},
{"id":"87547a11-3bb4-4bc2-bb2f-3fbb25c49e90","name":"Helpers","path":"/Helpers"},
{"id":"2fee7881-df2e-421a-b266-85fb48a54a16","name":"Modders","path":"/Modders"}
]
It would likely be beneficial to have a separate service that provided this data from Keycloak so not only is it available to other projects but also so that only the actual relevant data is returned.
For the purposes of LTPerms, I don't think tying it into a LT-specific service is a good idea. It'd be handy if it were standalone, allowing others (and us) to use the mod without needing a 'stack running
One of the reasons I suggested this is so that the mod is not directly communicating with Keycloak and having access to any data it likes, having an extra service outside of the mod ensures it only has access to the actual relevant data.
I don't think that will actually be an issue, considering fine-grained admin permissions is coming down the pipeline (which would prevent anything major) I also don't think tying LTPerms to work with our services specifically is a good idea. Right now (as far as I'm aware) it has no dependency on our technical infrastructure, and I want to keep it that way.
To be clear, I never specified one of our internal services. It could just as easy be a separate application. Allowing the mod direct access to the Keycloak instance makes me uncomfortable, but that's just my 2c.
There's probably a Keycloak extension that abstracts custom attributes out already anyway tbh
Keycloak is an extensible Java-based Identity Provider that allows sysadmins to configure how users can authenticate with services. My main areas of interest for integration are:
Our current Keycloak instance allows users to specify their Minecraft username in their profile, which will then be reported as attribute
minecraft-username