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

service: Add admin user concept and app definition scaling endpoint #400

Merged
merged 6 commits into from
Feb 12, 2025

Conversation

lucas-koehler
Copy link
Contributor

Summary

This PR adds the concept of admin users to the Theia Cloud REST service. They are identified by a configurable admin group name in MicroProfile JWT's groups claim.
Admin only endpoints and resources can be configured via new annotation @AdminOnly. This is used for a new endpoint that allows updating an app definition's min and max instances. In addition an admin ping endpoint was added.
The terraform Keycloak module was extended to configure the default admin group and export realm, group, and test user infos for further usage in consuming modules.

A corresponding PR for the Helm chart allows configuring the admin group name as a value: eclipse-theia/theia-cloud-helm#87

How to test

  • Setup Minikube using the terraform test configurations. To use a configure a custom group name for the service set value keycloak.adminGroup on the theia-cloud Helm chart.
    • You'll need to rename the group created by the Keycloak module manually in Keycloak's admin UI. You can find it in the TheiaCloud realm under Groups.
  • You'll need an access token for the user foo which is configured to be an admin user by the terraform test setup
curl -s --insecure --request POST \
  --url https://$(minikube ip).nip.io/keycloak/realms/TheiaCloud/protocol/openid-connect/token \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data grant_type=password \
  --data client_id=theia-cloud \
  --data username=foo \
  --data password=foo | jq .access_token
  • Use this as a Bearer token in your request
  • A GET request to https://$(minikube ip).nip.io/service/service/admin/asdfghjkl should return true with a token for user foo. It should return 403 for user bar because bar is not an admin user
  • Update an app definition at endpoint PATCH $(minikube ip).nip.io/service/service/admin/appdefinition/<appdef-name> . The payload is a JSON object like so:
{
  "appId": "asdfghjkl",
  "minInstances": 2,
  "maxInstances": 4
}

Implementation details

Implementation details

Add admin user support via annotation

  • Introduce the @AdminOnly annotation to mark REST resources or methods as accessible only to admin users.
  • Implement AdminOnlyFilter that intercepts requests and aborts non-admin users with a 403 Forbidden response.
  • Update ApplicationProperties to include a configurable admin group name property ("theia.cloud.auth.admin.group")
    with a default value of "theia-cloud/admin".
  • Enhance TheiaCloudUser by adding an admin flag.
  • Modify TheiaCloudUserProducer to derive the admin status from the MicroProfile JWT's groups claim.
  • Add tests for the new admin-only filter, properties, and user producer functionality.
  • Extend service Dockerfile to allow configuring the admin group name via environment variable.

Add admin endpoint to update app def's min/max instances

  • Add new resource AdminAppDefinitionAdminResource for all admin endpoints regarding app definitions
  • Minor extensions in K8SUtil, AppDefinitionSpec to allow editing min/max instances
  • Add tests for AdminAppDefintionAdminResource
  • Add RootAdminResource with a ping endpoint that only returns if the user is an admin

terrafom: Add admin user group and outputs for Keycloak module

Extend Keycloak terraform module:

  • Define an admin group with the default name
  • Export realm, admin group and test users via outputs

Test setup:

  • Add test user foo to the admin group

fix: Update Keycloak URL in tasks.json to include realm path

This is required for the Quarkus dev server to discover the OIDC config.
Also see the official documentation: https://quarkus.io/guides/security-oidc-configuration-properties-reference#quarkus-oidc_quarkus-oidc-auth-server-url

- Introduce the `@AdminOnly` annotation to mark REST resources or methods as accessible only to admin users.
- Implement AdminOnlyFilter that intercepts requests and aborts non-admin users with a 403 Forbidden response.
- Update ApplicationProperties to include a configurable admin group name property ("theia.cloud.auth.admin.group")
  with a default value of "theia-cloud/admin".
- Enhance TheiaCloudUser by adding an admin flag.
- Modify TheiaCloudUserProducer to derive the admin status from the MicroProfile JWT's groups claim.
- Add tests for the new admin-only filter, properties, and user producer functionality.
- Extend service Dockerfile to allow configuring the admin group name via environment variable.
- Add new resource AdminAppDefinitionAdminResource for all admin endpoints regarding app definitions
- Minor extensions in K8SUtil, AppDefinitionSpec to allow editing min/max instances
- Add tests for AdminAppDefintionAdminResource
- Add RootAdminResource with a ping endpoint that only returns if the user is an admin
Extend Keycloak terraform module:
- Define an admin group with the default name
- Export realm, admin group and test users via outputs

Test setup:
- Add test user foo to the admin group
@lucas-koehler lucas-koehler added the enhancement New feature or request label Feb 11, 2025
Copy link
Contributor

@jfaltermeier jfaltermeier left a comment

Choose a reason for hiding this comment

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

Thanks, looks great! I just have two comments about log messages.

Also, could you include this part of the testing instructions in a README?

curl -s --insecure --request POST \
  --url https://$(minikube ip).nip.io/keycloak/realms/TheiaCloud/protocol/openid-connect/token \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data grant_type=password \
  --data client_id=theia-cloud \
  --data username=foo \
  --data password=foo | jq .access_token

I think it would be useful to have this easily accessible.

Besides that, we need to regenerate the openapi.json and probably also regenerate the common npm library + markdown documentation.

@lucas-koehler
Copy link
Contributor Author

Hi @jfaltermeier , thanks for the review. I addressed all issues mentioned in your review :)
I did not yet add the admin endpoints to the non-generated part of the common npm library due to time constraints and because the endpoints are not that useful without the corresponding operator implementations. IMO, we can expose them later there. The generated code already inlcudes them though.

@lucas-koehler lucas-koehler merged commit 58a376d into main Feb 12, 2025
18 checks passed
@lucas-koehler lucas-koehler deleted the lk/admin-users branch February 12, 2025 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants