-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathgitlabLdapGroupSync.js
174 lines (145 loc) · 5.27 KB
/
gitlabLdapGroupSync.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
var co = require('co');
var every = require('schedule').every;
var ActiveDirectory = require('activedirectory');
var NodeGitlab = require('node-gitlab');
var ACCESS_LEVEL_OWNER = 50;
var ACCESS_LEVEL_NORMAL = 30;
module.exports = GitlabLdapGroupSync;
var isRunning = false;
var gitlab = undefined;
var ldap = undefined;
function GitlabLdapGroupSync(config) {
if (!(this instanceof GitlabLdapGroupSync))
return new GitlabLdapGroupSync(config)
gitlab = NodeGitlab.createThunk(config.gitlab);
ldap = new ActiveDirectory(config.ldap);
this.config = config
}
GitlabLdapGroupSync.prototype.sync = function () {
if (isRunning) {
console.log('ignore trigger, a sync is already running');
return;
}
isRunning = true;
co(function* () {
// find all users with a ldap identiy
var gitlabUsers = [];
var pagedUsers = [];
var i=0;
do {
i++;
pagedUsers = yield gitlab.users.list({ per_page: 100, page: i });
gitlabUsers.push.apply(gitlabUsers, pagedUsers);
}
while(pagedUsers.length == 100);
var gitlabUserMap = {};
var gitlabLocalUserIds = [];
for (var user of gitlabUsers) {
if (user.identities.length > 0) {
gitlabUserMap[user.username.toLowerCase()] = user.id;
} else {
gitlabLocalUserIds.push(user.id);
}
}
console.log(gitlabUserMap);
//set the gitlab group members based on ldap group
var gitlabGroups = [];
var pagedGroups = [];
var i=0;
do {
i++;
pagedGroups = yield gitlab.groups.list({ per_page: 100, page: i });
gitlabGroups.push.apply(gitlabGroups, pagedGroups);
}
while(pagedGroups.length == 100);
var membersOwner = yield this.resolveLdapGroupMembers(ldap, this.config['ownersGroup'] || 'admins', gitlabUserMap);
var membersDefault = yield this.resolveLdapGroupMembers(ldap, 'default', gitlabUserMap);
for (var gitlabGroup of gitlabGroups) {
console.log('-------------------------');
console.log('group:', gitlabGroup.name);
var gitlabGroupMembers = [];
var pagedGroupMembers = [];
var i=0;
do {
i++;
pagedGroupMembers = yield gitlab.groupMembers.list({ id: gitlabGroup.id, per_page: 100, page: i });
gitlabGroupMembers.push.apply(gitlabGroupMembers, pagedGroupMembers);
}
while(pagedGroupMembers.length == 100);
var currentMemberIds = [];
for (var member of gitlabGroupMembers) {
if (gitlabLocalUserIds.indexOf(member.id) > -1) {
continue; //ignore local users
}
var access_level = this.accessLevel(member.id, membersOwner);
if (member.access_level !== access_level) {
console.log('update group member permission', { id: gitlabGroup.id, user_id: member.id, access_level: access_level });
gitlab.groupMembers.update({ id: gitlabGroup.id, user_id: member.id, access_level: access_level });
}
currentMemberIds.push(member.id);
}
var members = yield this.resolveLdapGroupMembers(ldap, gitlabGroup.name, gitlabUserMap);
members = (members && members.length) ? members : membersDefault;
//remove unlisted users
var toDeleteIds = currentMemberIds.filter(x => members.indexOf(x) == -1);
for (var id of toDeleteIds) {
console.log('delete group member', { id: gitlabGroup.id, user_id: id });
gitlab.groupMembers.remove({ id: gitlabGroup.id, user_id: id });
}
//add new users
var toAddIds = members.filter(x => currentMemberIds.indexOf(x) == -1);
for (var id of toAddIds) {
var access_level = this.accessLevel(id, membersOwner);
console.log('add group member', { id: gitlabGroup.id, user_id: id, access_level: access_level });
gitlab.groupMembers.create({ id: gitlabGroup.id, user_id: id, access_level: access_level });
}
}
}.bind(this)).then(function (value) {
console.log('sync done');
isRunning = false;
}, function (err) {
console.error(err.stack);
isRunning = false;
});
}
var ins = undefined;
GitlabLdapGroupSync.prototype.accessLevel = function (id, membersOwner) {
var owner = membersOwner.indexOf(id) > -1
if(owner) {
return this.config['ownerAccessLevel'] || ACCESS_LEVEL_OWNER;
}
return this.config['defaultAccessLevel'] || ACCESS_LEVEL_NORMAL;
}
GitlabLdapGroupSync.prototype.startScheduler = function (interval) {
this.stopScheduler();
ins = every(interval).do(this.sync.bind(this));
}
GitlabLdapGroupSync.prototype.stopScheduler = function () {
if (ins) {
ins.stop();
}
ins = undefined;
}
GitlabLdapGroupSync.prototype.resolveLdapGroupMembers = function(ldap, group, gitlabUserMap) {
var groupName = (this.config.groupPrefix || 'gitlab-') + group
console.log('Loading users for group: ' + groupName)
return new Promise(function (resolve, reject) {
var ldapGroups = {};
ldap.getUsersForGroup(groupName, function (err, users) {
if (err) {
reject(err);
return;
}
groupMembers = [];
if(users) {
for (var user of users) {
if (gitlabUserMap[user.sAMAccountName.toLowerCase()]) {
groupMembers.push(gitlabUserMap[user.sAMAccountName.toLowerCase()]);
}
}
}
console.log('Members=' + groupMembers);
resolve(groupMembers);
});
});
}