From 6c40e5a7164d8c08d5d8f0f1da59eece4e914bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Mass=C3=A9?= Date: Fri, 7 Jul 2017 09:40:04 +0200 Subject: [PATCH] implement client removal + add safety check --- sso.js | 83 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/sso.js b/sso.js index 409b0b9..d7bf302 100644 --- a/sso.js +++ b/sso.js @@ -38,30 +38,65 @@ exports.init = sso_init; function handle_application(action, type, app, next) { + // Safety check: only create apps for OAuth enabled apps + // We know that an app is OAuth enabled if there is a redirect_url + // element in the webhooks payload. The element can be empty but it has to be there. + if (!("redirect_url" in app)) { + console.log("No redirect_url found in app description (not OAuth ?). Skipping client creation..."); + return next("No redirect_url found in app description (not OAuth ?)"); + } + + // Base Payload for app creation/update var client = { clientId: app.application_id, - clientAuthenticatorType: "client-secret", - secret: app.keys.key, - redirectUris: [ app.redirect_url ], - publicClient: false, name: app.name, description: app.description }; + // Add the client_secret to the client creation payload when found + if ('keys' in app && 'key' in app.keys && app.keys.key != null) { + console.log("Found a client_secret : '%s'", app.keys.key); + client.secret = app.keys.key; + client.clientAuthenticatorType = "client-secret"; + client.publicClient = false; + } + + // Add the redirect_url to the client creation payload when found + if (app.redirect_url != null && app.redirect_url != "") { + console.log("Found a redirect_url : '%s'", app.redirect_url); + client.redirectUris = [ app.redirect_url ]; + } + authenticate_to_sso(next, (access_token) => { get_sso_client(client.clientId, access_token, next, (sso_client) => { - if (sso_client == null) { - console.log("Could not find a client, creating it..."); - create_sso_client(access_token, client, (response) => { - console.log("OK, client created !") + if (action == "updated" || action == "created") { + if (sso_client == null) { + console.log("Could not find a client, creating it..."); + create_sso_client(access_token, client, (response) => { + console.log("OK, client created !") + next('SUCCESS'); + }); + } else { + console.log("Found an existing client with id = %s", sso_client.id); + update_sso_client(access_token, client, sso_client.id, next, (response) => { + console.log("OK, client updated !"); + next('SUCCESS'); + }); + } + } else if (action == "deleted") { + if (sso_client == null) { + console.log("Could not find a matching client..."); + return next('Nothing done, could not find a matching client.'); + } + + console.log("Deleting client with id = %s", sso_client.id); + delete_sso_client(access_token, sso_client.id, next, (response) => { + console.log("OK, client deleted !"); next('SUCCESS'); }); } else { - console.log("Found an existing client with id = %s", sso_client.id); - update_sso_client(access_token, client, sso_client.id, next, (response) => { - console.log("OK, client updated !"); - next('SUCCESS'); - }); + console.log("Unkown action '%s'", action); + next(util.format("Unknown action '%s'", action)); } }); }); @@ -152,6 +187,28 @@ function update_sso_client(access_token, client, id, error, next) { }); } +function delete_sso_client(access_token, id, error, next) { + req.delete(util.format("https://%s/auth/admin/realms/%s/clients/%s", config.SSO_HOSTNAME, config.SSO_REALM, id), { + headers: { + "Authorization": "Bearer " + access_token + } + }, (err, response, body) => { + if (err) { + return error(err); + } + console.log("Got a %d response from SSO", response.statusCode); + if (response.statusCode == 204) { + try { + next(); + } catch (err) { + return error(err); + } + } else { + return error(util.format("Got a %d response from SSO while updating client", response.statusCode)); + } + }); +} + function authenticate_to_sso(error, next) { console.log("Authenticating to SSO (realm = '%s') using the ROPC OAuth flow with %s/%s", config.SSO_REALM, config.SSO_SERVICE_USERNAME, config.SSO_SERVICE_PASSWORD); req.post(util.format("https://%s/auth/realms/%s/protocol/openid-connect/token", config.SSO_HOSTNAME, config.SSO_REALM), {