From 9897bd505e23b3e3b2eb6a4a7ce3d768e1154fee Mon Sep 17 00:00:00 2001 From: Afrisal Yodi Purnama Date: Fri, 9 Jul 2021 20:10:13 +0700 Subject: [PATCH 1/3] Split usermapping table. --- package.json | 1 + scripts/migrate-user-mapping.js | 45 ++++++++++++++++++++++++++++ src/common/db-helper.js | 2 +- src/common/helper.js | 3 +- src/controllers/GithubController.js | 9 +++--- src/controllers/GitlabController.js | 8 ++--- src/models/GithubUserMapping.js | 46 +++++++++++++++++++++++++++++ src/models/GitlabUserMapping.js | 46 +++++++++++++++++++++++++++++ src/models/UserMapping.js | 30 ------------------- src/services/GithubService.js | 8 ++--- src/services/GitlabService.js | 8 ++--- src/services/TCUserService.js | 10 +++++-- src/services/UserService.js | 23 ++++++++------- 13 files changed, 179 insertions(+), 60 deletions(-) create mode 100644 scripts/migrate-user-mapping.js create mode 100644 src/models/GithubUserMapping.js create mode 100644 src/models/GitlabUserMapping.js delete mode 100644 src/models/UserMapping.js diff --git a/package.json b/package.json index d9efd45..6ed6fa0 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "lint": "gulp lint", "heroku-postbuild": "gulp build", "create-tables": "CREATE_DB=true node scripts/create-update-tables.js", + "migrate-user-mapping": "node scripts/migrate-user-mapping.js", "log-repository-collisions": "node scripts/log-repository-collisions.js" }, "dependencies": { diff --git a/scripts/migrate-user-mapping.js b/scripts/migrate-user-mapping.js new file mode 100644 index 0000000..2b15616 --- /dev/null +++ b/scripts/migrate-user-mapping.js @@ -0,0 +1,45 @@ +const AWS = require('aws-sdk'); +const helper = require('../src/common/helper'); +const dbHelper = require('../src/common/db-helper'); +const GithubUserMapping = require('../src/models').GithubUserMapping; +const GitlabUserMapping = require('../src/models').GitlabUserMapping; + +console.log(process.env.IS_LOCAL); +if (process.env.IS_LOCAL) { + AWS.config.update({ + endpoint: 'http://localhost:8000' + }); +} +var documentClient = new AWS.DynamoDB.DocumentClient(); + +(async () => { + console.log('Migrating...'); + const params = { + TableName: 'Topcoder_X.UserMapping' + }; + + let items; + do { + items = await documentClient.scan(params).promise(); + items.Items.forEach(async (item) => { + console.log(item); + if (item.githubUserId && item.githubUsername) { + await dbHelper.create(GithubUserMapping, { + id: helper.generateIdentifier(), + topcoderUsername: item.topcoderUsername, + githubUserId: item.githubUserId, + githubUsername: item.githubUsername, + }); + } + if (item.gitlabUsername && item.gitlabUserId) { + await dbHelper.create(GitlabUserMapping, { + id: helper.generateIdentifier(), + topcoderUsername: item.topcoderUsername, + gitlabUsername: item.gitlabUsername, + gitlabUserId: item.gitlabUserId, + }); + } + }); + params.ExclusiveStartKey = items.LastEvaluatedKey; + } while(typeof items.LastEvaluatedKey !== 'undefined'); +})(); \ No newline at end of file diff --git a/src/common/db-helper.js b/src/common/db-helper.js index 3ae537b..f32c765 100644 --- a/src/common/db-helper.js +++ b/src/common/db-helper.js @@ -154,7 +154,7 @@ async function queryOneUserMappingByTCUsername(model, tcusername) { model.queryOne('topcoderUsername').eq(tcusername) .all() .exec((err, result) => { - if (err || !result) { + if (err) { logger.debug(`queryOneUserMappingByTCUsername. Error. ${err}`); return reject(err); } diff --git a/src/common/helper.js b/src/common/helper.js index 5dae1d2..e80dc1d 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -216,7 +216,8 @@ async function getProviderType(repoUrl) { * @returns {Object} the owner/copilot for the project */ async function getProjectCopilotOrOwner(models, project, provider, isCopilot) { - const userMapping = await dbHelper.queryOneUserMappingByTCUsername(models.UserMapping, + const userMapping = await dbHelper.queryOneUserMappingByTCUsername( + provider === 'github' ? models.GithubUserMapping : models.GitlabUserMapping, isCopilot ? project.copilot : project.owner); if (!userMapping || diff --git a/src/controllers/GithubController.js b/src/controllers/GithubController.js index d72fc9a..965ad62 100644 --- a/src/controllers/GithubController.js +++ b/src/controllers/GithubController.js @@ -20,7 +20,7 @@ const GithubService = require('../services/GithubService'); const UserService = require('../services/UserService'); const OwnerUserTeam = require('../models').OwnerUserTeam; const UserTeamMapping = require('../models').UserTeamMapping; -const UserMapping = require('../models').UserMapping; +const GithubUserMapping = require('../models').GithubUserMapping; const constants = require('../common/constants'); const request = superagentPromise(superagent, Promise); @@ -160,18 +160,19 @@ async function addUserToTeamCallback(req, res) { console.log(`adding ${token} to ${team.teamId} with ${team.ownerToken}`); /* eslint-disable-line no-console */ const githubUser = await GithubService.addTeamMember(team.teamId, team.ownerToken, token, team.accessLevel); // associate github username with TC username - const mapping = await dbHelper.queryOneUserMappingByTCUsername(UserMapping, req.session.tcUsername); + const mapping = await dbHelper.queryOneUserMappingByTCUsername(GithubUserMapping, req.session.tcUsername); // get team details const teamDetails = await GithubService.getTeamDetails(team.ownerToken, team.teamId); if (mapping) { - await dbHelper.update(UserMapping, mapping.id, { + await dbHelper.update(GithubUserMapping, mapping.id, { githubUsername: githubUser.username, githubUserId: githubUser.id, }); } else { - await dbHelper.create(UserMapping, { + console.log('User mapping not found. Create new mapping.'); /* eslint-disable-line no-console */ + await dbHelper.create(GithubUserMapping, { id: helper.generateIdentifier(), topcoderUsername: req.session.tcUsername, githubUsername: githubUser.username, diff --git a/src/controllers/GitlabController.js b/src/controllers/GitlabController.js index 7ff6477..8eba050 100644 --- a/src/controllers/GitlabController.js +++ b/src/controllers/GitlabController.js @@ -20,7 +20,7 @@ const GitlabService = require('../services/GitlabService'); const UserService = require('../services/UserService'); const User = require('../models').User; const OwnerUserGroup = require('../models').OwnerUserGroup; -const UserMapping = require('../models').UserMapping; +const GitlabUserMapping = require('../models').GitlabUserMapping; const UserGroupMapping = require('../models').UserGroupMapping; const request = superagentPromise(superagent, Promise); @@ -209,14 +209,14 @@ async function addUserToGroupCallback(req, res) { group.expiredAt); // associate gitlab username with TC username - const mapping = await dbHelper.queryOneUserMappingByTCUsername(UserMapping, req.session.tcUsername); + const mapping = await dbHelper.queryOneUserMappingByTCUsername(GitlabUserMapping, req.session.tcUsername); if (mapping) { - await dbHelper.update(UserMapping, mapping.id, { + await dbHelper.update(GitlabUserMapping, mapping.id, { gitlabUsername: gitlabUser.username, gitlabUserId: gitlabUser.id, }); } else { - await dbHelper.create(UserMapping, { + await dbHelper.create(GitlabUserMapping, { id: helper.generateIdentifier(), topcoderUsername: req.session.tcUsername, gitlabUsername: gitlabUser.username, diff --git a/src/models/GithubUserMapping.js b/src/models/GithubUserMapping.js new file mode 100644 index 0000000..6cd5d23 --- /dev/null +++ b/src/models/GithubUserMapping.js @@ -0,0 +1,46 @@ +/** + * This defines github user mapping model. + */ +'use strict'; + +const dynamoose = require('dynamoose'); + +const Schema = dynamoose.Schema; + +const schema = new Schema({ + id: { + type: String, + required: true, + hashKey: true + }, + topcoderUsername: { + type: String, + required: true, + index: { + global: true, + project: true, + rangKey: 'id', + name: 'TopcoderUsernameIndex' + } + }, + githubUsername: { + type: String, + index: { + global: true, + project: true, + rangKey: 'id', + name: 'GithubUsernameIndex' + } + }, + githubUserId: { + type: Number, + index: { + global: true, + project: true, + rangKey: 'id', + name: 'GithubUserIdIndex' + } + } +}); + +module.exports = schema; diff --git a/src/models/GitlabUserMapping.js b/src/models/GitlabUserMapping.js new file mode 100644 index 0000000..f87f1d9 --- /dev/null +++ b/src/models/GitlabUserMapping.js @@ -0,0 +1,46 @@ +/** + * This defines gitlab user mapping model. + */ +'use strict'; + +const dynamoose = require('dynamoose'); + +const Schema = dynamoose.Schema; + +const schema = new Schema({ + id: { + type: String, + required: true, + hashKey: true + }, + topcoderUsername: { + type: String, + required: true, + index: { + global: true, + project: true, + rangKey: 'id', + name: 'TopcoderUsernameIndex' + } + }, + gitlabUsername: { + type: String, + index: { + global: true, + project: true, + rangKey: 'id', + name: 'GitlabUsernameIndex' + } + }, + gitlabUserId: { + type: Number, + index: { + global: true, + project: true, + rangKey: 'id', + name: 'GitlabUserIdIndex' + } + } +}); + +module.exports = schema; diff --git a/src/models/UserMapping.js b/src/models/UserMapping.js deleted file mode 100644 index 7ab8a86..0000000 --- a/src/models/UserMapping.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * This defines user mapping model. - */ -const dynamoose = require('dynamoose'); - -const Schema = dynamoose.Schema; - -const schema = new Schema({ - id: { - type: String, - required: true, - hashKey: true, - }, - topcoderUsername: { - type: String, - required: true, - index: { - global: true, - project: true, - rangeKey: 'id', - name: 'TopcoderUsernameIndex', - }, - }, - githubUsername: String, - gitlabUsername: String, - githubUserId: Number, - gitlabUserId: Number -}); - -module.exports = schema; diff --git a/src/services/GithubService.js b/src/services/GithubService.js index dbd1d5e..2013478 100644 --- a/src/services/GithubService.js +++ b/src/services/GithubService.js @@ -17,7 +17,7 @@ const constants = require('../common/constants'); const helper = require('../common/helper'); const dbHelper = require('../common/db-helper'); const User = require('../models').User; -const UserMapping = require('../models').UserMapping; +const GithubUserMapping = require('../models').GithubUserMapping; const OwnerUserTeam = require('../models').OwnerUserTeam; const errors = require('../common/errors'); @@ -41,16 +41,16 @@ async function ensureOwnerUser(token, topcoderUsername) { constants.USER_TYPES.GITHUB, constants.USER_ROLES.OWNER); - const userMapping = await dbHelper.queryOneUserMappingByTCUsername(UserMapping, topcoderUsername); + const userMapping = await dbHelper.queryOneUserMappingByTCUsername(GithubUserMapping, topcoderUsername); if (!userMapping) { - await dbHelper.create(UserMapping, { + await dbHelper.create(GithubUserMapping, { id: helper.generateIdentifier(), topcoderUsername, githubUserId: userProfile.id, githubUsername: userProfile.login, }); } else { - await dbHelper.update(UserMapping, userMapping.id, { + await dbHelper.update(GithubUserMapping, userMapping.id, { githubUserId: userProfile.id, githubUsername: userProfile.login, }); diff --git a/src/services/GitlabService.js b/src/services/GitlabService.js index c7d3c7d..06ede47 100644 --- a/src/services/GitlabService.js +++ b/src/services/GitlabService.js @@ -19,7 +19,7 @@ const helper = require('../common/helper'); const dbHelper = require('../common/db-helper'); const errors = require('../common/errors'); const User = require('../models').User; -const UserMapping = require('../models').UserMapping; +const GitlabUserMapping = require('../models').GitlabUserMapping; const OwnerUserGroup = require('../models').OwnerUserGroup; const request = superagentPromise(superagent, Promise); @@ -52,16 +52,16 @@ async function ensureOwnerUser(token, topcoderUsername) { constants.USER_TYPES.GITLAB, constants.USER_ROLES.OWNER); - const userMapping = await dbHelper.queryOneUserMappingByTCUsername(UserMapping, topcoderUsername); + const userMapping = await dbHelper.queryOneUserMappingByTCUsername(GitlabUserMapping, topcoderUsername); if (!userMapping) { - await dbHelper.create(UserMapping, { + await dbHelper.create(GitlabUserMapping, { id: helper.generateIdentifier(), topcoderUsername, gitlabUserId: userProfile.id, gitlabUsername: userProfile.username, }); } else { - await dbHelper.update(UserMapping, userMapping.id, { + await dbHelper.update(GitlabUserMapping, userMapping.id, { gitlabUserId: userProfile.id, gitlabUsername: userProfile.username, }); diff --git a/src/services/TCUserService.js b/src/services/TCUserService.js index 023b7a8..9dee9bf 100644 --- a/src/services/TCUserService.js +++ b/src/services/TCUserService.js @@ -12,7 +12,8 @@ const Joi = require('joi'); const decodeToken = require('tc-auth-lib').decodeToken; const errors = require('../common/errors'); const helper = require('../common/helper'); -const UserMapping = require('../models').UserMapping; +const GithubUserMapping = require('../models').GithubUserMapping; +const GitlabUserMapping = require('../models').GitlabUserMapping; /** * gets the handle of tc user. @@ -40,7 +41,12 @@ async function getUserMapping(query) { 'At least one of topcoderUsername/gitlabUsername/githubUsername should be provided.'); } - return await helper.ensureExists(UserMapping, query, 'UserMapping'); + if (query.githubUsername) { + return await helper.ensureExists(GithubUserMapping, query, 'GithubUserMapping'); + } + else { + return await helper.ensureExists(GitlabUserMapping, query, 'GitlabUserMapping'); + } } getUserMapping.schema = Joi.object().keys({ diff --git a/src/services/UserService.js b/src/services/UserService.js index 61e32f7..d04a0d0 100644 --- a/src/services/UserService.js +++ b/src/services/UserService.js @@ -15,7 +15,8 @@ const dbHelper = require('../common/db-helper'); const errors = require('../common/errors'); const constants = require('../common/constants'); const User = require('../models').User; -const UserMapping = require('../models').UserMapping; +const GithubUserMapping = require('../models').GithubUserMapping; +const GitlabUserMapping = require('../models').GitlabUserMapping; /** * gets user setting @@ -23,30 +24,32 @@ const UserMapping = require('../models').UserMapping; * @returns {Object} the user setting */ async function getUserSetting(handle) { - const mapping = await dbHelper.queryOneUserMappingByTCUsername( - UserMapping, handle.toLowerCase()); + const githubMapping = await dbHelper.queryOneUserMappingByTCUsername( + GithubUserMapping, handle.toLowerCase()); + const gitlabMapping = await dbHelper.queryOneUserMappingByTCUsername( + GitlabUserMapping, handle.toLowerCase()); const setting = { github: false, gitlab: false, expired: {} }; - if (!mapping) { + if (!githubMapping && !gitlabMapping) { return setting; } const users = []; - if (mapping.githubUsername) { + if (githubMapping && githubMapping.githubUsername) { const github = await dbHelper.queryOneUserByType( - User, mapping.githubUsername, constants.USER_TYPES.GITHUB); + User, githubMapping.githubUsername, constants.USER_TYPES.GITHUB); if (!_.isNil(github)) { users.push(github); } } - if (mapping.gitlabUsername) { + if (gitlabMapping && gitlabMapping.gitlabUsername) { const gitlab = await dbHelper.queryOneUserByType( - User, mapping.gitlabUsername, constants.USER_TYPES.GITLAB); + User, gitlabMapping.gitlabUsername, constants.USER_TYPES.GITLAB); if (!_.isNil(gitlab)) { users.push(gitlab); } @@ -76,7 +79,7 @@ getUserSetting.schema = Joi.object().keys({ */ async function revokeUserSetting(handle, provider) { const mapping = await dbHelper.queryOneUserMappingByTCUsername( - UserMapping, handle.toLowerCase()); + provider === 'github' ? GithubUserMapping : GitlabUserMapping, handle.toLowerCase()); if (!mapping) { return false; @@ -127,7 +130,7 @@ async function getUserToken(username, tokenType) { */ async function getAccessTokenByHandle(handle, provider) { const mapping = await dbHelper.queryOneUserMappingByTCUsername( - UserMapping, handle.toLowerCase()); + provider === 'github' ? GithubUserMapping : GitlabUserMapping, handle.toLowerCase()); let gitUserName; if (mapping) { gitUserName = provider === constants.USER_TYPES.GITHUB ? 'githubUsername' : //eslint-disable-line no-nested-ternary From 894f30f328ea85d46b14d72b3ec71d44b133bd10 Mon Sep 17 00:00:00 2001 From: Afrisal Yodi Purnama Date: Sun, 11 Jul 2021 17:46:26 +0700 Subject: [PATCH 2/3] Github team access: Add member into organisation before add to team. --- package.json | 1 + scripts/add-organisation.js | 33 +++++++++++ scripts/migrate-user-mapping.js | 1 - src/common/db-helper.js | 20 +++++++ src/controllers/GithubController.js | 18 +++++- src/models/Organisation.js | 36 ++++++++++++ src/services/GithubService.js | 90 +++++++++++++++++++++++++++++ 7 files changed, 195 insertions(+), 4 deletions(-) create mode 100644 scripts/add-organisation.js create mode 100644 src/models/Organisation.js diff --git a/package.json b/package.json index 6ed6fa0..9791e86 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "heroku-postbuild": "gulp build", "create-tables": "CREATE_DB=true node scripts/create-update-tables.js", "migrate-user-mapping": "node scripts/migrate-user-mapping.js", + "add-organisation": "node scripts/add-organisation.js", "log-repository-collisions": "node scripts/log-repository-collisions.js" }, "dependencies": { diff --git a/scripts/add-organisation.js b/scripts/add-organisation.js new file mode 100644 index 0000000..8524a36 --- /dev/null +++ b/scripts/add-organisation.js @@ -0,0 +1,33 @@ +const dbHelper = require('../src/common/db-helper'); +const helper = require('../src/common/helper'); +const Organisation = require('../src/models').Organisation; + +const args = process.argv; +if (args.length < 5) { + console.log('Please provide data. Example: npm run add-organisation MyOrganisation ownername PAT-Token'); + return; +} +const organisationName = args[2]; +const owner = args[3]; +const pat = args[4]; + +(async () => { + const dbOrganisation = await dbHelper.queryOneOrganisation(Organisation, organisationName); + if (dbOrganisation) { + console.log(`Updating Organisation = ${organisationName} Owner = ${owner} PAT = ${pat}.`); + await dbHelper.update(Organisation, dbOrganisation.id, { + name: organisationName, + owner, + personalAccessToken: pat + }); + } + else { + console.log(`Adding Organisation = ${organisationName} Owner = ${owner} PAT = ${pat}.`); + await dbHelper.create(Organisation, { + id: helper.generateIdentifier(), + name: organisationName, + owner, + personalAccessToken: pat + }); + } +})(); \ No newline at end of file diff --git a/scripts/migrate-user-mapping.js b/scripts/migrate-user-mapping.js index 2b15616..31c5f02 100644 --- a/scripts/migrate-user-mapping.js +++ b/scripts/migrate-user-mapping.js @@ -4,7 +4,6 @@ const dbHelper = require('../src/common/db-helper'); const GithubUserMapping = require('../src/models').GithubUserMapping; const GitlabUserMapping = require('../src/models').GitlabUserMapping; -console.log(process.env.IS_LOCAL); if (process.env.IS_LOCAL) { AWS.config.update({ endpoint: 'http://localhost:8000' diff --git a/src/common/db-helper.js b/src/common/db-helper.js index f32c765..45b66f3 100644 --- a/src/common/db-helper.js +++ b/src/common/db-helper.js @@ -367,6 +367,25 @@ async function removeUser(Model, username, type) { }); } +/** + * Get single data by query parameters + * @param {Object} model The dynamoose model to query + * @param {String} organisation The organisation name + * @returns {Promise} + */ +async function queryOneOrganisation(model, organisation) { + return await new Promise((resolve, reject) => { + model.queryOne('name').eq(organisation) + .all() + .exec((err, result) => { + if (err) { + logger.debug(`queryOneOrganisation. Error. ${err}`); + return reject(err); + } + return resolve(result); + }); + }); +} module.exports = { getById, @@ -379,6 +398,7 @@ module.exports = { queryOneActiveCopilotPayment, queryOneActiveProject, queryOneActiveProjectWithFilter, + queryOneOrganisation, queryOneIssue, queryOneUserByType, queryOneUserByTypeAndRole, diff --git a/src/controllers/GithubController.js b/src/controllers/GithubController.js index 965ad62..2794131 100644 --- a/src/controllers/GithubController.js +++ b/src/controllers/GithubController.js @@ -127,6 +127,8 @@ async function addUserToTeam(req, res) { config.GITHUB_CLIENT_ID }&redirect_uri=${ encodeURIComponent(callbackUri) + }&scope=${ + encodeURIComponent('admin:org') }&state=${identifier}`); } @@ -156,15 +158,25 @@ async function addUserToTeamCallback(req, res) { throw new errors.UnauthorizedError('Github authorization failed.', result.body.error_description); } const token = result.body.access_token; + + // get team details + const teamDetails = await GithubService.getTeamDetails(team.ownerToken, team.teamId); + const organisation = teamDetails.organization.login; + + // Add member to organisation + const addOrganisationResult = await GithubService.addOrganisationMember(organisation, token); + console.log(`Add organisation member, state = ${addOrganisationResult.state}`); /* eslint-disable-line no-console */ + if (addOrganisationResult.state === 'pending') { + const acceptInvitation = await GithubService.acceptOrganisationInvitation(organisation, token); + console.log(`Accept organisation invitation by member, state = ${acceptInvitation.state}`); /* eslint-disable-line no-console */ + } + // add user to team console.log(`adding ${token} to ${team.teamId} with ${team.ownerToken}`); /* eslint-disable-line no-console */ const githubUser = await GithubService.addTeamMember(team.teamId, team.ownerToken, token, team.accessLevel); // associate github username with TC username const mapping = await dbHelper.queryOneUserMappingByTCUsername(GithubUserMapping, req.session.tcUsername); - // get team details - const teamDetails = await GithubService.getTeamDetails(team.ownerToken, team.teamId); - if (mapping) { await dbHelper.update(GithubUserMapping, mapping.id, { githubUsername: githubUser.username, diff --git a/src/models/Organisation.js b/src/models/Organisation.js new file mode 100644 index 0000000..dca4453 --- /dev/null +++ b/src/models/Organisation.js @@ -0,0 +1,36 @@ +/** + * This defines organisation model. + */ +'use strict'; + +const dynamoose = require('dynamoose'); + +const Schema = dynamoose.Schema; + +const schema = new Schema({ + id: { + type: String, + required: true, + hashKey: true + }, + name: { + type: String, + required: true, + index: { + global: true, + project: true, + rangKey: 'id', + name: 'NameIndex' + } + }, + owner: { + type: String, + required: true + }, + personalAccessToken: { + type: String, + required: true + } +}); + +module.exports = schema; diff --git a/src/services/GithubService.js b/src/services/GithubService.js index 2013478..fb8d2f5 100644 --- a/src/services/GithubService.js +++ b/src/services/GithubService.js @@ -19,7 +19,12 @@ const dbHelper = require('../common/db-helper'); const User = require('../models').User; const GithubUserMapping = require('../models').GithubUserMapping; const OwnerUserTeam = require('../models').OwnerUserTeam; +const Organisation = require('../models').Organisation; const errors = require('../common/errors'); +const superagent = require('superagent'); +const superagentPromise = require('superagent-promise'); + +const request = superagentPromise(superagent, Promise); /** * Ensure the owner user is in database. @@ -229,6 +234,89 @@ addTeamMember.schema = Joi.object().keys({ accessLevel: Joi.string().required(), }); +/** + * Add organisation member. + * @param {String} organisation the organisation name + * @param {String} normalUserToken the normal user token + * @returns {Promise} the promise result + */ +async function addOrganisationMember(organisation, normalUserToken) { + let state; + try { + const dbOrganisation = await dbHelper.queryOneOrganisation(Organisation, organisation); + if (!dbOrganisation) { + console.log(`Personal access token not found for organisation ${organisation}.`); /* eslint-disable-line no-console */ + return {}; + } + const githubNormalUser = new GitHub({ + token: normalUserToken, + }); + const normalUser = await githubNormalUser.getUser().getProfile(); + const username = normalUser.data.login; + const base64PAT = Buffer.from(`${dbOrganisation.owner}:${dbOrganisation.personalAccessToken}`).toString('base64'); + const result = await request + .put(`https://api.github.com/orgs/${organisation}/memberships/${username}`) + .send({role: 'member'}) + .set('User-Agent', 'superagent') + .set('Accept', 'application/vnd.github.v3+json') + .set('Authorization', `Basic ${base64PAT}`) + .end(); + state = _.get(result, 'body.state'); + } catch (err) { + // if error is already exists discard + if (_.chain(err).get('body.errors').countBy({ + code: 'already_exists', + }).get('true') + .isUndefined() + .value()) { + throw helper.convertGitHubError(err, 'Failed to add organisation member'); + } + } + // return its state + return {state}; +} + +addOrganisationMember.schema = Joi.object().keys({ + organisation: Joi.string().required(), + normalUserToken: Joi.string().required() +}); + +/** + * Accept organisation invitation by member. + * @param {String} organisation the organisation name + * @param {String} normalUserToken the normal user token + * @returns {Promise} the promise result + */ +async function acceptOrganisationInvitation(organisation, normalUserToken) { + let state; + try { + const result = await request + .patch(`https://api.github.com/user/memberships/orgs/${organisation}`) + .send({state: 'active'}) + .set('User-Agent', 'superagent') + .set('Accept', 'application/vnd.github.v3+json') + .set('Authorization', `token ${normalUserToken}`) + .end(); + state = _.get(result, 'body.state'); + } catch (err) { + // if error is already exists discard + if (_.chain(err).get('body.errors').countBy({ + code: 'already_exists', + }).get('true') + .isUndefined() + .value()) { + throw helper.convertGitHubError(err, 'Failed to accept organisation invitation'); + } + } + // return its state + return {state}; +} + +acceptOrganisationInvitation.schema = Joi.object().keys({ + organisation: Joi.string().required(), + normalUserToken: Joi.string().required() +}); + /** * Gets the user id by username * @param {string} username the username @@ -320,6 +408,8 @@ module.exports = { getUserIdByUsername, getTeamDetails, deleteUserFromGithubTeam, + addOrganisationMember, + acceptOrganisationInvitation }; helper.buildService(module.exports); From b35ef6b7fb803281582f2633e28a8a693b6ab488 Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Mon, 12 Jul 2021 11:20:39 +1000 Subject: [PATCH 3/3] Bug in IS_LOCAL check --- scripts/migrate-user-mapping.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/migrate-user-mapping.js b/scripts/migrate-user-mapping.js index 31c5f02..bd93eca 100644 --- a/scripts/migrate-user-mapping.js +++ b/scripts/migrate-user-mapping.js @@ -4,7 +4,8 @@ const dbHelper = require('../src/common/db-helper'); const GithubUserMapping = require('../src/models').GithubUserMapping; const GitlabUserMapping = require('../src/models').GitlabUserMapping; -if (process.env.IS_LOCAL) { +if (process.env.IS_LOCAL=="true") { + console.log("IS LOCAL") AWS.config.update({ endpoint: 'http://localhost:8000' }); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy