Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Gitlab add user expiration feature. #302

Merged
merged 1 commit into from
Mar 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"angular-touch": "~1.7.4",
"angular-ui-bootstrap": "~2.5.0",
"angular-ui-router": "~1.0.23",
"angularjs-datepicker": "^2.1.23",
"auth0-angular": "~4.0.4",
"auth0-js": "^9.11.3",
"auth0-lock": "^11.17.2",
Expand Down
13 changes: 11 additions & 2 deletions src/controllers/GitlabController.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ async function getGroupRegistrationUrl(req) {
if (!user || !user.accessToken) {
throw new errors.UnauthorizedError('You have not setup for Gitlab.');
}
return await GitlabService.getGroupRegistrationUrl(user.username, req.params.id, req.params.accessLevel);
return await GitlabService.getGroupRegistrationUrl(
user.username,
req.params.id,
req.params.accessLevel,
req.params.expiredAt);
}

/**
Expand Down Expand Up @@ -193,7 +197,12 @@ async function addUserToGroupCallback(req, res) {
});

// add user to group
const gitlabUser = await GitlabService.addGroupMember(group.groupId, ownerUser.accessToken, token, group.accessLevel);
const gitlabUser = await GitlabService.addGroupMember(
group.groupId,
ownerUser.accessToken,
token,
group.accessLevel,
group.expiredAt);
// associate gitlab username with TC username
const mapping = await dbHelper.scanOne(UserMapping, {
topcoderUsername: {eq: req.session.tcUsername},
Expand Down
3 changes: 2 additions & 1 deletion src/front/src/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ angular.module('topcoderX', [
'ui.router',
'ui.bootstrap',
'angular-clipboard',
'angular-jwt'])
'angular-jwt',
'720kb.datepicker'])
// In the run phase of your Angular application
.run(['AuthService', function (AuthService) {
// init AuthService, it has to be done once, when app starts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ angular.module('topcoderX')
* get gitlab shareable link
*
*/
service.getGitlabShareableLink = function (groupId, accessLevel) {
service.getGitlabShareableLink = function (groupId, accessLevel, expiredAt) {
if (expiredAt) {
return $http.get(baseUrl + '/api/v1/gitlab/groups/' + groupId + '/registrationurl/' + accessLevel + '/' + expiredAt).then(function (response) {
return response;
});
}
return $http.get(baseUrl + '/api/v1/gitlab/groups/' + groupId + '/registrationurl/' + accessLevel).then(function (response) {
return response;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ angular.module('topcoderX').controller('GitAccessDialogController', [
) {
$scope.provider = provider;
$scope.accessLevel = '';
$scope.expiredAt = '';
if ($scope.provider === 'github') {
$scope.accessLevel = 'member';
} else {
$scope.accessLevel = '30';
$scope.dateLimit = new Date().toDateString();
}

/**
Expand All @@ -25,12 +27,20 @@ angular.module('topcoderX').controller('GitAccessDialogController', [
$scope.accessLevel = accessLevel;
};

/**
* Update the expired at params
*/
$scope.updateExpired = function (expiredAt) {
$scope.expiredAt = expiredAt;
};

/**
* Set changes to father controller
*/
$scope.setChanges = function () {
$uibModalInstance.close({
accessLevel: $scope.accessLevel,
expiredAt: $scope.expiredAt
});
};

Expand Down
11 changes: 9 additions & 2 deletions src/front/src/app/git-access-control/git-access-dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,21 @@ <h4 class="modal-title" id="reg-dialog-label">Configure Access Level and Valid P
<div class="row">
<label class="form-label">Access Level:</label>
<select class="form-control" ng-if="provider === 'gitlab'" ng-model="accessLevel" ng-change="updateAccessLevel(accessLevel)" required>
<option value ="30">Developer</option>
<option value ="10">Guest</option>
<option value ="20">Reporter</option>
<option value ="30">Developer</option>
<option value ="40">Maintainer</option>
<option value ="50">Owner</option>
</select>
<select class="form-control" ng-if="provider === 'github'" ng-model="accessLevel" ng-change="updateAccessLevel(accessLevel)" required>
<option value ="member">Member</option>
<option value ="maintainer">Maintainer</option>
</select>
<br />
<label ng-if="provider === 'gitlab'" class="form-label">Expired At:</label>
<datepicker ng-if="provider === 'gitlab'" date-format="yyyy-MM-dd" date-min-limit="{{dateLimit}}">
<input class="form-control" ng-model="expiredAt" type="text" ng-change="updateExpired(expiredAt)"/>
</datepicker>
</div>
</div>
<div class="modal-footer">
Expand All @@ -27,4 +34,4 @@ <h4 class="modal-title" id="reg-dialog-label">Configure Access Level and Valid P
Cancel
</button>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,13 @@ angular.module('topcoderX').controller('GitAccessController', ['currentUser', '$
function (data) {
if (data) {
const accessLevel = data.accessLevel;
const expiredAt = data.expiredAt;
var config = $scope.tableConfig[provider];
config.accessLinkMethod.apply(vm, [team.id, accessLevel]).then(function (response) {
var params = [team.id, accessLevel];
if (expiredAt) {
params.push(expiredAt);
}
config.accessLinkMethod.apply(vm, params).then(function (response) {
team.accessLink = response.data.url;
team.showLink = true;
team.gettingLink = false;
Expand Down
3 changes: 2 additions & 1 deletion src/front/src/index.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*add css dependencies in node_modules here*/

@import url("../../../node_modules/metismenu/dist/metisMenu.css");
@import url("../../../node_modules/footable/css/footable.core.css");
@import url("../../../node_modules/footable/css/footable.core.css");
@import url("../../../node_modules/angularjs-datepicker/dist/angular-datepicker.min.css");
1 change: 1 addition & 0 deletions src/front/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ require('metismenu');
require('pace-js');
require('footable');
require('jquery-ui-dist/jquery-ui');
require('angularjs-datepicker');
window.shortid = require('shortid')
4 changes: 4 additions & 0 deletions src/models/OwnerUserGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ const schema = new Schema({
name: 'AccessLevelIndex',
},
},
expiredAt: {
type: String,
required: false
}
});


Expand Down
6 changes: 6 additions & 0 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ module.exports = {
method: 'getGroupRegistrationUrl',
},
},
'/gitlab/groups/:id/registrationurl/:accessLevel/:expiredAt': {
get: {
controller: 'GitlabController',
method: 'getGroupRegistrationUrl',
},
},
'/gitlab/groups/:id/users': {
delete: {
controller: 'GitlabController',
Expand Down
15 changes: 12 additions & 3 deletions src/services/GitlabService.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,10 @@ listOwnerUserGroups.schema = Joi.object().keys({
* @param {String} ownerUsername the owner user name
* @param {String} groupId the group id
* @param {String} accessLevel the group access level
* @param {String} expiredAt the expired at params to define how long user joined teams. can be null
* @returns {Promise} the promise result
*/
async function getGroupRegistrationUrl(ownerUsername, groupId, accessLevel) {
async function getGroupRegistrationUrl(ownerUsername, groupId, accessLevel, expiredAt) {
// generate identifier
const identifier = helper.generateIdentifier();

Expand All @@ -159,6 +160,7 @@ async function getGroupRegistrationUrl(ownerUsername, groupId, accessLevel) {
groupId,
identifier,
accessLevel,
expiredAt
});

// construct URL
Expand All @@ -170,6 +172,7 @@ getGroupRegistrationUrl.schema = Joi.object().keys({
ownerUsername: Joi.string().required(),
groupId: Joi.string().required(),
accessLevel: Joi.string().required(),
expiredAt: Joi.string()
});

/**
Expand All @@ -178,9 +181,10 @@ getGroupRegistrationUrl.schema = Joi.object().keys({
* @param {String} ownerUserToken the owner user token
* @param {String} normalUserToken the normal user token
* @param {String} accessLevel the access level
* @param {String} expiredAt the expired at params to define how long user joined teams. can be null
* @returns {Promise} the promise result
*/
async function addGroupMember(groupId, ownerUserToken, normalUserToken, accessLevel) {
async function addGroupMember(groupId, ownerUserToken, normalUserToken, accessLevel, expiredAt) {
let username;
let userId;
try {
Expand All @@ -195,11 +199,15 @@ async function addGroupMember(groupId, ownerUserToken, normalUserToken, accessLe
throw new errors.UnauthorizedError('Can not get user id from the normal user access token.');
}

let body = `user_id=${userId}&access_level=${accessLevel}`;
if (expiredAt) {
body = body + `&expires_at=${expiredAt} `;
}
// add user to group
await request
.post(`${config.GITLAB_API_BASE_URL}/api/v4/groups/${groupId}/members`)
.set('Authorization', `Bearer ${ownerUserToken}`)
.send(`user_id=${userId}&access_level=${accessLevel}`)
.send(body)
.end();
// return gitlab username
return {
Expand All @@ -222,6 +230,7 @@ addGroupMember.schema = Joi.object().keys({
ownerUserToken: Joi.string().required(),
normalUserToken: Joi.string().required(),
accessLevel: Joi.string().required(),
expiredAt: Joi.string()
});

/**
Expand Down