From ac0dbcd6840642ca0690010d751563e9511a1969 Mon Sep 17 00:00:00 2001 From: Mats Blomdahl Date: Mon, 15 Apr 2024 11:02:24 +0200 Subject: [PATCH] Add Post-Login Action for MinIO Policy Claims This PR adds a new post-login type action for adding a custom claim with MinIO policies for different users. Tested and verified with https://minio.owntube.tv, related to OwnTube-tv/minio-microk8s-ansible#10 Resolves #19 --- CONTRIBUTING.md | 2 +- .../code.js | 61 +++++++++++++++++++ .../manifest.yaml | 30 +++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 templates/add-minio-policy-open-id-claim-POST_LOGIN/code.js create mode 100644 templates/add-minio-policy-open-id-claim-POST_LOGIN/manifest.yaml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dda90d3..387412d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ ### Actions Templates -For best practices, please review [our documentaton](https://auth0.com/docs/customize/actions/actions-templates#best-practices) and accompanying coding guidelines +For best practices, please review [our documentation](https://auth0.com/docs/customize/actions/actions-templates#best-practices) and accompanying coding guidelines #### Creating an Actions Template diff --git a/templates/add-minio-policy-open-id-claim-POST_LOGIN/code.js b/templates/add-minio-policy-open-id-claim-POST_LOGIN/code.js new file mode 100644 index 0000000..c5408ce --- /dev/null +++ b/templates/add-minio-policy-open-id-claim-POST_LOGIN/code.js @@ -0,0 +1,61 @@ +/** + * Handler that will be called during the execution of a PostLogin flow. + * + * --- AUTH0 ACTIONS TEMPLATE https://github.com/auth0/opensource-marketplace/blob/main/templates/add-minio-policy-open-id-claim-POST_LOGIN --- + * + * @param {Event} event - Details about the user and the context in which they are logging in. + * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login. + */ +exports.onExecutePostLogin = async (event, api) => { + // get the JWT Claim prefix for MinIO + const jwtClaimPrefix = event.secrets.POST_LOGIN_MINIO_CLAIM_PREFIX; + if (!jwtClaimPrefix) { + return api.access.deny('Invalid configuration, missing POST_LOGIN_MINIO_CLAIM_PREFIX'); + } + + // get the fallback/default policy for un-mapped users + const defaultPolicy = event.secrets.POST_LOGIN_MINIO_CLAIM_DEFAULT_POLICY; + if (!defaultPolicy) { + return api.access.deny('Invalid configuration, missing POST_LOGIN_MINIO_CLAIM_DEFAULT_POLICY'); + } + + // get the mapping of users to (pre-configured) MinIO policy names + const userToPolicyMapJson = event.secrets.POST_LOGIN_MINIO_CLAIM_USER_POLICY_MAP; + let userToPolicyMap; + try { + userToPolicyMap = JSON.parse(userToPolicyMapJson); + if (typeof userToPolicyMap !== 'object' || Array.isArray(userToPolicyMap) || userToPolicyMap === null) { + return api.access.deny('Mal-formatted userEmail-to-policyName mapping in POST_LOGIN_MINIO_CLAIM_USER_POLICY_MAP'); + } + } catch (e) { + console.error('Parsing POST_LOGIN_MINIO_CLAIM_USER_POLICY_MAP failed', e); + return api.access.deny('Invalid configuration, POST_LOGIN_MINIO_CLAIM_USER_POLICY_MAP is invalid'); + } + + // reject login if the user's email is not available or verified + if (!event.user.email || !event.user.email_verified) { + return api.access.deny('Access denied, user email not available/verified'); + } + + // check if user email is in the mapping, if not, use the default policy + const userMinioPolicy = userToPolicyMap[event.user.email.toLowerCase()] || defaultPolicy; + + // format the claim name, e.g. "https://minio.example.com/policy" + const minioClaimName = jwtClaimPrefix.endsWith('/') ? `${jwtClaimPrefix}policy` : `${jwtClaimPrefix}/policy`; + + api.idToken.setCustomClaim(minioClaimName, userMinioPolicy); + api.accessToken.setCustomClaim(minioClaimName, userMinioPolicy); + + // store the last assigned policy in the user's app_metadata property + api.user.setAppMetadata('minioPolicyOpenIdClaim', `${minioClaimName}=${userMinioPolicy}`); +}; + +/** + * Handler that will be invoked when this action is resuming after an external redirect. If your + * onExecutePostLogin function does not perform a redirect, this function can be safely ignored. + * + * @param {Event} event - Details about the user and the context in which they are logging in. + * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login. + */ +// exports.onContinuePostLogin = async (event, api) => { +// }; diff --git a/templates/add-minio-policy-open-id-claim-POST_LOGIN/manifest.yaml b/templates/add-minio-policy-open-id-claim-POST_LOGIN/manifest.yaml new file mode 100644 index 0000000..5e5c918 --- /dev/null +++ b/templates/add-minio-policy-open-id-claim-POST_LOGIN/manifest.yaml @@ -0,0 +1,30 @@ +id: "64887fc5-cbef-49e0-a4f9-9a352b4a9da8" +name: "Add MinIO Policy OpenID Claim" +description: "Add MinIO policy claim to white-listed users" +public: true +triggers: ["POST_LOGIN"] +runtime: "node18" +modules: [] +version: "1.0.0" +sourceUrl: "https://github.com/auth0/opensource-marketplace/tree/main/templates/add-minio-policy-open-id-claim-POST_LOGIN/manifest.yaml" +useCases: + - "ENRICH_PROFILE" +notes: | + **Secrets** + + * `POST_LOGIN_MINIO_CLAIM_PREFIX` - the JWT Claim prefix for ID and access tokens + * `POST_LOGIN_MINIO_CLAIM_DEFAULT_POLICY` - the default MinIO policy for any unmapped user (e.g. from a social connection) + * `POST_LOGIN_MINIO_CLAIM_USER_POLICY_MAP` - JSON map of users to their intended MinIO authorizations/policies by verified email + + **Notes** + + See MinIO [OpenID Identity Management Settings](https://min.io/docs/minio/linux/reference/minio-server/settings/iam/openid.html#) + for documentation on how the integration is implemented from the vendor side. + +secrets: + - label: "POST_LOGIN_MINIO_CLAIM_PREFIX" + defaultValue: https://play.min.io/ + - label: "POST_LOGIN_MINIO_CLAIM_DEFAULT_POLICY" + defaultValue: noaccess + - label: "POST_LOGIN_MINIO_CLAIM_USER_POLICY_MAP" + defaultValue: '{"you@example.com": "readwrite,diagnostics", "your_cat@example.com": "readonly"}'