From 80da5c86587faf331a362302eebdc12a184adbf3 Mon Sep 17 00:00:00 2001 From: cache Date: Tue, 18 Apr 2017 09:01:48 -0400 Subject: [PATCH] obtain user-id from sso provider info --- initializers/helper.js | 35 ++++++++++++++++++++++++++- initializers/middleware.js | 39 ++++++++++++++++++++++++++++-- queries/get_user_by_sso_login | 5 ++++ queries/get_user_by_sso_login.json | 5 ++++ 4 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 queries/get_user_by_sso_login create mode 100644 queries/get_user_by_sso_login.json diff --git a/initializers/helper.js b/initializers/helper.js index 7170bd95d..e9961b888 100755 --- a/initializers/helper.js +++ b/initializers/helper.js @@ -1214,9 +1214,23 @@ helper.socialProviders = { "twitter": 3, "github": 4, "salesforce": 5, - "ad": 50 + "dribbble": 10, + "behance": 11, + "stackoverflow": 12, + "linkedin": 13, + "bitbucket": 14, + "ad": 50, + "samlp": 102 }; +helper.isTCADProvider = function (providerId) { + return providerId === helper.socialProviders.ad; +} + +helper.isSSOProvider = function (providerId) { + return providerId === helper.socialProviders.samlp; +} + /** * Retrieve provider information from the provider name. * @@ -1240,15 +1254,34 @@ helper.getProviderId = function (provider, callback) { if (provider.startsWith("salesforce")) { providerId = helper.socialProviders.salesforce; } + if (provider.startsWith("dribbble")) { + providerId = helper.socialProviders.dribbble; + } + if (provider.startsWith("behance")) { + providerId = helper.socialProviders.behance; + } + if (provider.startsWith("stackoverflow")) { + providerId = helper.socialProviders.stackoverflow; + } + if (provider.startsWith("linkedin")) { + providerId = helper.socialProviders.linkedin; + } + if (provider.startsWith("bitbucket")) { + providerId = helper.socialProviders.bitbucket; + } if (provider.startsWith("ad") || provider.startsWith("auth0")) { providerId = helper.socialProviders.ad; } + if (provider.startsWith("samlp")) { + providerId = helper.socialProviders.samlp; + } if (providerId) { callback(null, providerId); } else { callback(new Error('Social provider: ' + provider + ' is not defined in config')); } }; + /* Encrypt the password using the specified key. After being * encrypted with a Blowfish key, the encrypted byte array is * then encoded with a base 64 encoding, resulting in the String diff --git a/initializers/middleware.js b/initializers/middleware.js index e41ad3b63..cf370e589 100644 --- a/initializers/middleware.js +++ b/initializers/middleware.js @@ -76,12 +76,14 @@ exports.middleware = function (api, next) { var authHeader = connection.rawConnection.req.headers.authorization, connectionMap = { "common_oltp": api.dataAccess.createConnection("common_oltp") }, isTopcoderAD, + isSSO, cachePrefix = "authorizationPreProcessor::", decoded, isCachedReturned, cacheKey, socialUserId, socialProvider, + authConnection, cookieToken = api.utils.parseCookies(connection.rawConnection.req)[process.env.JWT_TOKEN_COOKIE_KEY]; if (_.isUndefined(authHeader) && _.isUndefined(cookieToken)) { @@ -113,8 +115,10 @@ exports.middleware = function (api, next) { cb(new IllegalArgumentError('Malformed Auth header. No sub in token!')); return; } + // connection name + authConnection = getAuth0Connection(decoded); var split = decoded.sub.split("|"); - if (split.length === 1) { + if (split.length === 1) { // token.sub should contain "|" cb(new IllegalArgumentError('Malformed Auth header. token.sub is in bad format!')); return; @@ -136,7 +140,8 @@ exports.middleware = function (api, next) { } api.helper.getProviderId(socialProvider, cb); }, function (providerId, cb) { - isTopcoderAD = providerId === api.helper.socialProviders.ad; + isTopcoderAD = api.helper.isTCADProvider(providerId); + isSSO = api.helper.isSSOProvider(providerId); cacheKey = cachePrefix + decoded.sub; api.cache.load(cacheKey, function (err, value) { var userId; @@ -155,6 +160,16 @@ exports.middleware = function (api, next) { cbx(api.helper.checkPositiveInteger(userId, "userId")); return; } + if (isSSO) { + api.dataAccess.executeQuery("get_user_by_sso_login", + { + sso_user_id: socialUserId, + auth_connection: authConnection, + }, + connectionMap, + cbx); + return; + } api.dataAccess.executeQuery("get_user_by_social_login", { social_user_id: socialUserId, @@ -251,6 +266,26 @@ exports.middleware = function (api, next) { } /*jslint */ + /** + * Extract Auth0 connection name from JWT token. + * JWT Example: + * .... + * "identities": [ + * { + * "connection": "sfdc-aspdev", + * "isSocial": false, + * "provider": "samlp", + * "user_id": "user1@asp.appirio.com.dev" + * } + * ] + * sfdc-aspdev is returned. + * + * @param {Object} decoded JWT token issued by Auth0 (v2 token) + */ + function getAuth0Connection(jwt) { + return (jwt && jwt.identities && Array.isArray(jwt.identities) && jwt.identities.length>0 ) ? jwt.identities[0].connection : null; + } + /** * The pre-processor that checks if user is slamming. * diff --git a/queries/get_user_by_sso_login b/queries/get_user_by_sso_login new file mode 100644 index 000000000..1f2257a3e --- /dev/null +++ b/queries/get_user_by_sso_login @@ -0,0 +1,5 @@ +SELECT s.user_id +FROM user_sso_login s +JOIN sso_login_provider p ON s.provider_id = p.sso_login_provider_id +WHERE p.name = '@auth_connection@' +AND s.sso_user_id = '@sso_user_id@' diff --git a/queries/get_user_by_sso_login.json b/queries/get_user_by_sso_login.json new file mode 100644 index 000000000..c73c00aec --- /dev/null +++ b/queries/get_user_by_sso_login.json @@ -0,0 +1,5 @@ +{ + "name" : "get_user_by_sso_login", + "db" : "common_oltp", + "sqlfile" : "get_user_by_sso_login" +}