Last active
August 23, 2022 20:59
-
-
Save aslafy-z/4c4f73aa24bbeb4a59e8d6bc849cd1ba to your computer and use it in GitHub Desktop.
Auth0 rule to check organization of Github users
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Auth0 custom rule | |
// Add Github Organizations to the user metadata | |
// | |
// This rule need the following configurations values | |
// AUTH0_DOMAIN_NAME: your auth0 domain name | |
// MANAGEMENT_CLIENT_ID: your auth0 management api client id | |
// MANAGEMENT_CLIENT_SECRET: your auth0 management api client secret | |
// | |
// You have to create an Management API Application with proper | |
// scope to allow rule to fetch user organizations. | |
// Note: Youre Github social application must request the `read:org` scope! | |
// | |
// Auth0 UI workflow: | |
// - Go to Applications, create new application | |
// - Name: Auth0 Management API | |
// - Type: Machine to Machine App | |
// - Select API: Auth0 Management API | |
// - Add read:user_idp_tokens scope | |
// - Go to Application settings, you'll find your ID and SECRET | |
function (user, context, callback) { | |
// This rule below is specific to Github | |
if (context.connectionStrategy !== 'github') { | |
return callback(null, user, context); | |
} | |
function getManagementApiAccessToken(cb) { | |
const cacheKey = "apiv2TokenToReadUserIdpToken"; | |
const cachedToken = global[cacheKey]; | |
if (cachedToken) { | |
if (cachedToken.expirationDate > new Date()) { | |
console.log("Reusing cached token that expires in " + cachedToken.expirationDate); | |
return cb(null, cachedToken.token); | |
} | |
console.log('Cached token found but expired.'); | |
} else { | |
console.log('Cached token not found.'); | |
} | |
const AuthenticationClient = require('[email protected]').AuthenticationClient; | |
const authClient = new AuthenticationClient({ | |
domain: configuration.AUTH0_DOMAIN_NAME, | |
clientId: configuration.MANAGEMENT_CLIENT_ID, | |
clientSecret: configuration.MANAGEMENT_CLIENT_SECRET | |
}); | |
console.log("Getting new api v2 access token"); | |
authClient.clientCredentialsGrant({ | |
audience: 'https://' + configuration.AUTH0_DOMAIN_NAME + '/api/v2/' | |
}, function (err, response) { | |
if (err) { | |
return cb(err); | |
} | |
const expirationDate = new Date(); | |
expirationDate.setSeconds(expirationDate.getSeconds() + response.expires_in - 60); | |
// store token in cache | |
console.log("Storing token, expires in " + expirationDate); | |
global[cacheKey] = { | |
expirationDate: expirationDate, | |
token: response.access_token | |
}; | |
cb(null, response.access_token); | |
}); | |
} | |
function getGithubAccessToken(apiToken, cb) { | |
const ManagementClient = require('[email protected]').ManagementClient; | |
const management = new ManagementClient({ | |
token: apiToken, | |
domain: configuration.AUTH0_DOMAIN_NAME | |
}); | |
management.users.get({ | |
id: user.user_id | |
}) | |
.then(function (read_user) { | |
const githubIdentity = _.find(read_user.identities, { | |
connection: 'github' | |
}); | |
if (githubIdentity) { | |
if (githubIdentity.access_token) { | |
return cb(null, githubIdentity.access_token); | |
} else { | |
return cb(new Error("Could not find github access token.")); | |
} | |
} else { | |
return cb(new Error("Could not find github identity.")); | |
} | |
}) | |
.catch(function (err) { | |
return cb(err); | |
}); | |
} | |
function getGithubEndpoint(url, accessToken, callback) { | |
require('request').get(url, { | |
headers: { | |
'Authorization': 'Bearer ' + accessToken, | |
'User-Agent': 'Auth0-Custom-Rule' | |
}, | |
json: true | |
}, (err, resp, body) => { | |
if (resp.statusCode !== 200) { | |
return callback(new Error('Error retrieving data from github: ' + body || err)); | |
} | |
return callback(err, body); | |
}); | |
} | |
return getManagementApiAccessToken(function (err, token) { | |
if (err) { | |
return callback(err); | |
} | |
return getGithubAccessToken(token, function (err, githubToken) { | |
if (err) { | |
return callback(err); | |
} | |
const url = 'https://api.github.com/user/orgs'; | |
return getGithubEndpoint(url, githubToken, function (err, githubBody) { | |
if (err) { | |
return callback(err); | |
} | |
user.user_metadata = user.user_metadata || {}; | |
user.user_metadata.github_orgs = githubBody.map(i => i.login); | |
return auth0.users.updateUserMetadata(user.user_id, user.user_metadata) | |
.then(function(){ | |
return callback(null, user, context); | |
}) | |
.catch(function(err){ | |
return callback(err); | |
}); | |
}); | |
}); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Auth0 custom rule | |
// Check if the user is a member of all required Github organizations | |
// | |
// This rule need the following configurations values | |
// REQUIRED_GITHUB_ORGS: github organizations logins (coma separated) | |
// | |
// Note: This rule should be used in conjuction with `add-github-orgs-to-user-meta.js` | |
// Be sure to setup it to run after the first one. | |
function (user, context, callback) { | |
if ( | |
// pass if provider is not github | |
context.connectionStrategy !== 'github' || | |
// or if no org configured | |
!configuration.REQUIRED_GITHUB_ORGS | |
) { | |
return callback(null, user, context); | |
} | |
const requiredOrgs = configuration.REQUIRED_GITHUB_ORGS.split(','); | |
if ( | |
// pass if organizations are set | |
user.user_metadata && user.user_metadata.github_orgs && | |
// and user is a member of all required orgs | |
requiredOrgs.some(r => user.user_metadata.github_orgs.includes(r)) | |
) { | |
return callback(null, user, context); | |
} | |
return callback('Access denied'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment