ef-keycloak-connect 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/services/finesseService.js +113 -17
- package/services/keycloakService.js +333 -5
- package/services/teamsService.js +120 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ef-keycloak-connect",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Node JS keycloak adapter for authentication and authorization.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"express": "^4.17.1",
|
|
18
18
|
"express-session": "^1.17.2",
|
|
19
19
|
"joi": "^17.6.0",
|
|
20
|
-
"keycloak-connect": "^10.0.2"
|
|
20
|
+
"keycloak-connect": "^10.0.2",
|
|
21
|
+
"xml2js": "^0.5.0"
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
var requestController = require("../controller/requestController.js");
|
|
2
2
|
const https = require('https');
|
|
3
3
|
|
|
4
|
-
class FinesseService{
|
|
4
|
+
class FinesseService {
|
|
5
5
|
|
|
6
6
|
constructor() {
|
|
7
7
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
async authenticateUserViaFinesse(username,password,finesseUrl){
|
|
11
|
+
async authenticateUserViaFinesse(username, password, finesseUrl) {
|
|
12
12
|
|
|
13
13
|
return new Promise(async (resolve, reject) => {
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
var URL = finesseUrl + '/finesse/api/User/' + username;
|
|
16
|
-
|
|
17
|
-
let encodedCredentials = await this.maskCredentials(username,password);
|
|
16
|
+
|
|
17
|
+
let encodedCredentials = await this.maskCredentials(username, password);
|
|
18
18
|
|
|
19
19
|
let config = {
|
|
20
20
|
method: 'get',
|
|
@@ -23,13 +23,13 @@ class FinesseService{
|
|
|
23
23
|
'Authorization': `Basic ${encodedCredentials}`
|
|
24
24
|
},
|
|
25
25
|
//disable ssl
|
|
26
|
-
httpsAgent: new https.Agent({rejectUnauthorized: false})
|
|
26
|
+
httpsAgent: new https.Agent({ rejectUnauthorized: false })
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
try {
|
|
30
30
|
|
|
31
31
|
let tokenResponse = await requestController.httpRequest(config, true);
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
resolve({
|
|
34
34
|
'status': tokenResponse.status
|
|
35
35
|
});
|
|
@@ -37,14 +37,14 @@ class FinesseService{
|
|
|
37
37
|
}
|
|
38
38
|
catch (er) {
|
|
39
39
|
|
|
40
|
-
if(er.code == "ENOTFOUND"){
|
|
40
|
+
if (er.code == "ENOTFOUND") {
|
|
41
41
|
|
|
42
42
|
resolve({
|
|
43
43
|
'finesse login status': 408,
|
|
44
44
|
'finesse login message': `finesse server not accessible against URL: ${finesseUrl}`
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
}else if(er.response){
|
|
47
|
+
} else if (er.response) {
|
|
48
48
|
|
|
49
49
|
resolve({
|
|
50
50
|
'finesse login status': er.response.status,
|
|
@@ -52,16 +52,16 @@ class FinesseService{
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
async authenticateUserViaFinesseSSO(username,finesseToken,finesseUrl){
|
|
61
|
+
async authenticateUserViaFinesseSSO(username, finesseToken, finesseUrl) {
|
|
62
62
|
|
|
63
63
|
return new Promise(async (resolve, reject) => {
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
var URL = finesseUrl + '/finesse/api/User/' + username;
|
|
66
66
|
|
|
67
67
|
let config = {
|
|
@@ -71,13 +71,13 @@ class FinesseService{
|
|
|
71
71
|
'Authorization': `Bearer ${finesseToken}`
|
|
72
72
|
},
|
|
73
73
|
//disable ssl
|
|
74
|
-
httpsAgent: new https.Agent({rejectUnauthorized: false})
|
|
74
|
+
httpsAgent: new https.Agent({ rejectUnauthorized: false })
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
try {
|
|
78
78
|
|
|
79
79
|
let tokenResponse = await requestController.httpRequest(config, true);
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
resolve({
|
|
82
82
|
'status': tokenResponse.status
|
|
83
83
|
});
|
|
@@ -85,14 +85,109 @@ class FinesseService{
|
|
|
85
85
|
}
|
|
86
86
|
catch (er) {
|
|
87
87
|
|
|
88
|
-
if(er.code == "ENOTFOUND"){
|
|
88
|
+
if (er.code == "ENOTFOUND") {
|
|
89
|
+
|
|
90
|
+
resolve({
|
|
91
|
+
'finesse login status': 408,
|
|
92
|
+
'finesse login message': `finesse server not accessible against URL: ${finesseUrl}`
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
} else if (er.response) {
|
|
96
|
+
|
|
97
|
+
resolve({
|
|
98
|
+
'finesse login status': er.response.status,
|
|
99
|
+
'finesse login message': er.response.statusText
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async getCiscoTeams(username, password, finesseUrl) {
|
|
109
|
+
|
|
110
|
+
return new Promise(async (resolve, reject) => {
|
|
111
|
+
|
|
112
|
+
var URL = finesseUrl + '/finesse/api/Teams';
|
|
113
|
+
|
|
114
|
+
let encodedCredentials = await this.maskCredentials(username, password);
|
|
115
|
+
|
|
116
|
+
let config = {
|
|
117
|
+
method: 'get',
|
|
118
|
+
url: URL,
|
|
119
|
+
headers: {
|
|
120
|
+
'Authorization': `Basic ${encodedCredentials}`
|
|
121
|
+
},
|
|
122
|
+
//disable ssl
|
|
123
|
+
httpsAgent: new https.Agent({ rejectUnauthorized: false })
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
|
|
128
|
+
let tokenResponse = await requestController.httpRequest(config, true);
|
|
129
|
+
|
|
130
|
+
resolve(tokenResponse.data);
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
catch (er) {
|
|
134
|
+
|
|
135
|
+
if (er.code == "ENOTFOUND") {
|
|
136
|
+
|
|
137
|
+
resolve({
|
|
138
|
+
'finesse login status': 408,
|
|
139
|
+
'finesse login message': `finesse server not accessible against URL: ${finesseUrl}`
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
} else if (er.response) {
|
|
143
|
+
|
|
144
|
+
resolve({
|
|
145
|
+
'finesse login status': er.response.status,
|
|
146
|
+
'finesse login message': er.response.statusText
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async getCiscoUsers(username, password, finesseUrl) {
|
|
157
|
+
|
|
158
|
+
return new Promise(async (resolve, reject) => {
|
|
159
|
+
|
|
160
|
+
var URL = finesseUrl + '/finesse/api/Users';
|
|
161
|
+
|
|
162
|
+
let encodedCredentials = await this.maskCredentials(username, password);
|
|
163
|
+
|
|
164
|
+
let config = {
|
|
165
|
+
method: 'get',
|
|
166
|
+
url: URL,
|
|
167
|
+
headers: {
|
|
168
|
+
'Authorization': `Basic ${encodedCredentials}`
|
|
169
|
+
},
|
|
170
|
+
//disable ssl
|
|
171
|
+
httpsAgent: new https.Agent({ rejectUnauthorized: false })
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
|
|
176
|
+
let tokenResponse = await requestController.httpRequest(config, true);
|
|
177
|
+
|
|
178
|
+
resolve(tokenResponse.data);
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
catch (er) {
|
|
182
|
+
|
|
183
|
+
if (er.code == "ENOTFOUND") {
|
|
89
184
|
|
|
90
185
|
resolve({
|
|
91
186
|
'finesse login status': 408,
|
|
92
187
|
'finesse login message': `finesse server not accessible against URL: ${finesseUrl}`
|
|
93
188
|
});
|
|
94
189
|
|
|
95
|
-
}else if(er.response){
|
|
190
|
+
} else if (er.response) {
|
|
96
191
|
|
|
97
192
|
resolve({
|
|
98
193
|
'finesse login status': er.response.status,
|
|
@@ -100,12 +195,13 @@ class FinesseService{
|
|
|
100
195
|
});
|
|
101
196
|
|
|
102
197
|
}
|
|
198
|
+
|
|
103
199
|
}
|
|
104
200
|
|
|
105
201
|
});
|
|
106
202
|
}
|
|
107
203
|
|
|
108
|
-
async maskCredentials(username, password){
|
|
204
|
+
async maskCredentials(username, password) {
|
|
109
205
|
|
|
110
206
|
let token = Buffer.from(`${username}:${password}`, 'utf8').toString('base64');
|
|
111
207
|
return token;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
var session = require("express-session");
|
|
2
2
|
var Keycloak = require("keycloak-connect");
|
|
3
3
|
const Joi = require('joi');
|
|
4
|
+
const parseXMLString = require('xml2js').parseString;
|
|
4
5
|
var requestController = require("../controller/requestController.js");
|
|
5
6
|
var memory = new session.MemoryStore();
|
|
6
7
|
var keycloakConfig = null;
|
|
@@ -672,14 +673,16 @@ class KeycloakService extends Keycloak {
|
|
|
672
673
|
if (userGroup.data.length != 0) {
|
|
673
674
|
|
|
674
675
|
|
|
675
|
-
let
|
|
676
|
+
let groups = userGroup.data;
|
|
676
677
|
let userTeam = {};
|
|
677
678
|
let supervisedTeams = [];
|
|
678
679
|
|
|
680
|
+
let filteredTeams = groups.filter(group => !group.name.includes('_permission'));
|
|
681
|
+
|
|
679
682
|
|
|
680
683
|
userTeam = {
|
|
681
|
-
'teamId':
|
|
682
|
-
'teamName':
|
|
684
|
+
'teamId': filteredTeams[0].id,
|
|
685
|
+
'teamName': filteredTeams[0].name
|
|
683
686
|
}
|
|
684
687
|
|
|
685
688
|
team.userTeam = userTeam;
|
|
@@ -700,7 +703,7 @@ class KeycloakService extends Keycloak {
|
|
|
700
703
|
|
|
701
704
|
let result = await teamsService.getGroupByGroupID(group.id, username, token, keycloakConfig);
|
|
702
705
|
|
|
703
|
-
if (result) {
|
|
706
|
+
if (result && !result.teamName.includes('_permission')) {
|
|
704
707
|
supervisedTeams.push(result);
|
|
705
708
|
}
|
|
706
709
|
};
|
|
@@ -823,6 +826,7 @@ class KeycloakService extends Keycloak {
|
|
|
823
826
|
delete config.url
|
|
824
827
|
|
|
825
828
|
groupsData = groups.data;
|
|
829
|
+
groupsData = groupsData.filter(group => !group.name.includes('_permission'));
|
|
826
830
|
|
|
827
831
|
|
|
828
832
|
} catch (er) {
|
|
@@ -845,6 +849,7 @@ class KeycloakService extends Keycloak {
|
|
|
845
849
|
if (groupsIdsArr.length == 0) {
|
|
846
850
|
|
|
847
851
|
let supervisedGroups = keycloakObj.supervisedTeams;
|
|
852
|
+
supervisedGroups = supervisedGroups.filter(group => !group.teamName.includes('_permission'));
|
|
848
853
|
groupsData = supervisedGroups;
|
|
849
854
|
|
|
850
855
|
//only send the users of provided groups.
|
|
@@ -871,6 +876,7 @@ class KeycloakService extends Keycloak {
|
|
|
871
876
|
groupsArr.push(group);
|
|
872
877
|
});
|
|
873
878
|
|
|
879
|
+
groupsArr = groupsArr.filter(group => !group.teamName.includes('_permission'));
|
|
874
880
|
groupsData = groupsArr;
|
|
875
881
|
}
|
|
876
882
|
}
|
|
@@ -1067,9 +1073,42 @@ class KeycloakService extends Keycloak {
|
|
|
1067
1073
|
async createUser(username, password, token, userRoles) {
|
|
1068
1074
|
|
|
1069
1075
|
let assignRole = [];
|
|
1076
|
+
let assignGroups = ['agents', 'default'];
|
|
1070
1077
|
|
|
1071
1078
|
return new Promise(async (resolve, reject) => {
|
|
1072
1079
|
|
|
1080
|
+
|
|
1081
|
+
for (let group of assignGroups) {
|
|
1082
|
+
|
|
1083
|
+
let URL2 = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups?search=' + group;
|
|
1084
|
+
|
|
1085
|
+
let config1 = {
|
|
1086
|
+
method: 'get',
|
|
1087
|
+
url: URL2,
|
|
1088
|
+
headers: {
|
|
1089
|
+
'Content-Type': 'application/json',
|
|
1090
|
+
'Authorization': `Bearer ${token}`
|
|
1091
|
+
}
|
|
1092
|
+
};
|
|
1093
|
+
|
|
1094
|
+
try {
|
|
1095
|
+
let groupData = await requestController.httpRequest(config1, true);
|
|
1096
|
+
|
|
1097
|
+
if (groupData.data.length == 0) {
|
|
1098
|
+
|
|
1099
|
+
let createdGroup = await this.createGroup(token, group);
|
|
1100
|
+
|
|
1101
|
+
}
|
|
1102
|
+
} catch (err) {
|
|
1103
|
+
reject({
|
|
1104
|
+
"status": err.response.status,
|
|
1105
|
+
"message": err.response.data.error_description
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
|
|
1073
1112
|
let URL = `${keycloakConfig["auth-server-url"]}${keycloakConfig["USERNAME_ADMIN"]}/realms/${keycloakConfig["realm"]}/users`;
|
|
1074
1113
|
|
|
1075
1114
|
let data = {
|
|
@@ -1081,10 +1120,98 @@ class KeycloakService extends Keycloak {
|
|
|
1081
1120
|
value: password,
|
|
1082
1121
|
temporary: false
|
|
1083
1122
|
}
|
|
1084
|
-
]
|
|
1123
|
+
],
|
|
1124
|
+
groups: ["agents", "default"]
|
|
1085
1125
|
}
|
|
1086
1126
|
|
|
1127
|
+
let config = {
|
|
1128
|
+
method: 'post',
|
|
1129
|
+
url: URL,
|
|
1130
|
+
headers: {
|
|
1131
|
+
'Content-Type': 'application/json',
|
|
1132
|
+
'Authorization': `Bearer ${token}`
|
|
1133
|
+
},
|
|
1134
|
+
data: data
|
|
1135
|
+
};
|
|
1136
|
+
|
|
1137
|
+
try {
|
|
1138
|
+
|
|
1139
|
+
let tokenResponse = await requestController.httpRequest(config, false);
|
|
1140
|
+
|
|
1141
|
+
if (userRoles != []) {
|
|
1142
|
+
//Get the user id at time of creation
|
|
1143
|
+
let userLocation = tokenResponse.headers.location;
|
|
1144
|
+
let userLocationSplit = userLocation.split("/");
|
|
1145
|
+
let userId = userLocationSplit[(userLocationSplit.length) - 1];
|
|
1146
|
+
|
|
1087
1147
|
|
|
1148
|
+
//Get list of all the roles in keycloak realm
|
|
1149
|
+
let realmRoles = await this.getRealmRoles(token);
|
|
1150
|
+
|
|
1151
|
+
//checking whether role exist in realmRoles object array:
|
|
1152
|
+
for (let role of realmRoles.data) {
|
|
1153
|
+
|
|
1154
|
+
userRoles.forEach(userRole => {
|
|
1155
|
+
|
|
1156
|
+
if (role.name == userRole.toLocaleLowerCase()) {
|
|
1157
|
+
assignRole.push({
|
|
1158
|
+
id: role.id,
|
|
1159
|
+
name: role.name
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
//assigning role to user
|
|
1167
|
+
let roleAssigned = await this.assignRoleToUser(userId, assignRole, token);
|
|
1168
|
+
|
|
1169
|
+
//Role assigned with status
|
|
1170
|
+
if (roleAssigned.status == 204) {
|
|
1171
|
+
resolve(tokenResponse);
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
} else {
|
|
1175
|
+
|
|
1176
|
+
resolve(tokenResponse);
|
|
1177
|
+
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
}
|
|
1182
|
+
catch (err) {
|
|
1183
|
+
reject({
|
|
1184
|
+
"status": err.response.status,
|
|
1185
|
+
"message": err.response.data.error_description
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
async createFinesseUser(userObject, token) {
|
|
1193
|
+
|
|
1194
|
+
let assignRole = [];
|
|
1195
|
+
|
|
1196
|
+
return new Promise(async (resolve, reject) => {
|
|
1197
|
+
|
|
1198
|
+
|
|
1199
|
+
let URL = `${keycloakConfig["auth-server-url"]}${keycloakConfig["USERNAME_ADMIN"]}/realms/${keycloakConfig["realm"]}/users`;
|
|
1200
|
+
|
|
1201
|
+
let data = {
|
|
1202
|
+
username: userObject.username,
|
|
1203
|
+
firstName: userObject.firstName,
|
|
1204
|
+
lastName: userObject.lastName,
|
|
1205
|
+
enabled: true,
|
|
1206
|
+
credentials: [
|
|
1207
|
+
{
|
|
1208
|
+
type: 'password',
|
|
1209
|
+
value: '123456',
|
|
1210
|
+
temporary: false
|
|
1211
|
+
}
|
|
1212
|
+
],
|
|
1213
|
+
groups: userObject.group
|
|
1214
|
+
}
|
|
1088
1215
|
|
|
1089
1216
|
let config = {
|
|
1090
1217
|
method: 'post',
|
|
@@ -1099,6 +1226,7 @@ class KeycloakService extends Keycloak {
|
|
|
1099
1226
|
try {
|
|
1100
1227
|
|
|
1101
1228
|
let tokenResponse = await requestController.httpRequest(config, false);
|
|
1229
|
+
let userRoles = userObject.roles;
|
|
1102
1230
|
|
|
1103
1231
|
if (userRoles != []) {
|
|
1104
1232
|
//Get the user id at time of creation
|
|
@@ -1116,6 +1244,7 @@ class KeycloakService extends Keycloak {
|
|
|
1116
1244
|
userRoles.forEach(userRole => {
|
|
1117
1245
|
|
|
1118
1246
|
if (role.name == userRole.toLocaleLowerCase()) {
|
|
1247
|
+
|
|
1119
1248
|
assignRole.push({
|
|
1120
1249
|
id: role.id,
|
|
1121
1250
|
name: role.name
|
|
@@ -1151,6 +1280,205 @@ class KeycloakService extends Keycloak {
|
|
|
1151
1280
|
});
|
|
1152
1281
|
}
|
|
1153
1282
|
|
|
1283
|
+
async createGroup(adminToken, groupName) {
|
|
1284
|
+
|
|
1285
|
+
return new Promise(async (resolve, reject) => {
|
|
1286
|
+
|
|
1287
|
+
let URL = `${keycloakConfig["auth-server-url"]}${keycloakConfig["USERNAME_ADMIN"]}/realms/${keycloakConfig["realm"]}/groups`;
|
|
1288
|
+
|
|
1289
|
+
let data = {
|
|
1290
|
+
name: groupName
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
let config = {
|
|
1295
|
+
method: 'post',
|
|
1296
|
+
url: URL,
|
|
1297
|
+
headers: {
|
|
1298
|
+
'Authorization': `Bearer ${adminToken}`
|
|
1299
|
+
},
|
|
1300
|
+
data: data
|
|
1301
|
+
};
|
|
1302
|
+
|
|
1303
|
+
try {
|
|
1304
|
+
|
|
1305
|
+
let createdGroup = await requestController.httpRequest(config, false);
|
|
1306
|
+
resolve(createdGroup.data);
|
|
1307
|
+
|
|
1308
|
+
} catch (err) {
|
|
1309
|
+
reject({
|
|
1310
|
+
"status": err.response.status,
|
|
1311
|
+
"message": err.response.data.error_description
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
});
|
|
1316
|
+
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
async syncCiscoTeams(administratorUsername, administratorPassword, finesseUrl) {
|
|
1320
|
+
|
|
1321
|
+
return new Promise(async (resolve, reject) => {
|
|
1322
|
+
|
|
1323
|
+
//admin token url
|
|
1324
|
+
let token;
|
|
1325
|
+
let createdGroups;
|
|
1326
|
+
let groupSupervisors = [];
|
|
1327
|
+
var URL = keycloakConfig["auth-server-url"] + 'realms/' + keycloakConfig.realm + '/protocol/openid-connect/token';
|
|
1328
|
+
|
|
1329
|
+
//request config to fetch admin token
|
|
1330
|
+
var config = {
|
|
1331
|
+
method: 'post',
|
|
1332
|
+
url: URL,
|
|
1333
|
+
headers: {
|
|
1334
|
+
'Accept': 'application/json',
|
|
1335
|
+
'cache-control': 'no-cache',
|
|
1336
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
1337
|
+
},
|
|
1338
|
+
data: {
|
|
1339
|
+
client_id: keycloakConfig.CLIENT_ID,
|
|
1340
|
+
username: keycloakConfig.USERNAME_ADMIN,
|
|
1341
|
+
password: keycloakConfig.PASSWORD_ADMIN,
|
|
1342
|
+
grant_type: keycloakConfig.GRANT_TYPE,
|
|
1343
|
+
client_secret: keycloakConfig.credentials.secret
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
try {
|
|
1348
|
+
|
|
1349
|
+
//http request to fetch admin token
|
|
1350
|
+
let adminTokenResponse = await requestController.httpRequest(config, true);
|
|
1351
|
+
token = adminTokenResponse.data.access_token;
|
|
1352
|
+
|
|
1353
|
+
//Service to get all existing keycloak groups
|
|
1354
|
+
let groupsList = await teamsService.getGroupsList(token, keycloakConfig);
|
|
1355
|
+
let groupNames = null;
|
|
1356
|
+
|
|
1357
|
+
if (groupsList != null) {
|
|
1358
|
+
groupNames = groupsList.map(group => group.name);
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
//service to get all the teams from Cisco Finesse
|
|
1362
|
+
let teamsList = await finesseService.getCiscoTeams(administratorUsername, administratorPassword, finesseUrl);
|
|
1363
|
+
|
|
1364
|
+
//Converting the XML String returned from Finesse to JS Object
|
|
1365
|
+
parseXMLString(teamsList, async (err, result) => {
|
|
1366
|
+
if (err) {
|
|
1367
|
+
console.error(err);
|
|
1368
|
+
} else {
|
|
1369
|
+
|
|
1370
|
+
//iterating through the Cisco finesse teams
|
|
1371
|
+
for (let team of result.Teams.Team) {
|
|
1372
|
+
|
|
1373
|
+
//Converting both finesse teams and keycloak teams to lowercase for non case sensitive comparison
|
|
1374
|
+
let isExist = groupNames.map(group => group.toLowerCase()).includes((team.name[0]).toLowerCase());
|
|
1375
|
+
|
|
1376
|
+
//Creating new group on keycloak side against finesse team if doesn't exist already.
|
|
1377
|
+
if (!isExist) {
|
|
1378
|
+
let newGroup = await this.createGroup(token, team.name[0]);
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
//Get the list of newly created groups in keycloak. We use it later to add supervisor to group
|
|
1384
|
+
groupsList = await teamsService.getGroupsList(token, keycloakConfig);
|
|
1385
|
+
groupNames = null;
|
|
1386
|
+
|
|
1387
|
+
if (groupsList != null) {
|
|
1388
|
+
groupNames = groupsList.map(group => {
|
|
1389
|
+
return {
|
|
1390
|
+
id: group.id,
|
|
1391
|
+
name: group.name
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
//Service to get all existing keycloak users
|
|
1397
|
+
let usersList = await teamsService.getUsersList(token, keycloakConfig);
|
|
1398
|
+
let userNames = null;
|
|
1399
|
+
|
|
1400
|
+
if (usersList != null) {
|
|
1401
|
+
userNames = usersList.map(user => user.username);
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
//service to get existing users list from Cisco Finesse
|
|
1405
|
+
let ciscoUsersList = await finesseService.getCiscoUsers(administratorUsername, administratorPassword, finesseUrl);
|
|
1406
|
+
|
|
1407
|
+
parseXMLString(ciscoUsersList, async (err, result) => {
|
|
1408
|
+
|
|
1409
|
+
if (err) {
|
|
1410
|
+
console.error(err);
|
|
1411
|
+
} else {
|
|
1412
|
+
|
|
1413
|
+
for (let user of result.Users.User) {
|
|
1414
|
+
|
|
1415
|
+
//Converting both finesse user and keycloak user to lowercase for non case sensitive comparison
|
|
1416
|
+
let isExist = userNames.map(user => user.toLowerCase()).includes((user.loginName[0]).toLowerCase());
|
|
1417
|
+
|
|
1418
|
+
//Creating new user on keycloak side against finesse user if doesn't exist already.
|
|
1419
|
+
if (!isExist) {
|
|
1420
|
+
|
|
1421
|
+
let userObject = {
|
|
1422
|
+
username: user.loginName[0],
|
|
1423
|
+
firstName: user.firstName[0],
|
|
1424
|
+
lastName: user.lastName[0],
|
|
1425
|
+
roles: (user.roles[0].role).map(role => role.toLowerCase()),
|
|
1426
|
+
group: (user.teamName == '' || user.teamName == null) ? ['Default'] : user.teamName
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
if (user.teams) {
|
|
1430
|
+
if (user.teams[0].Team) {
|
|
1431
|
+
userObject.supervisedGroups = (user.teams[0].Team).map(team => team.name[0]);
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
userObject.supervisedGroups.forEach(groupName => {
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
let keycloakGroupToSupervise = groupNames.find(group => group.name == groupName);
|
|
1438
|
+
let isExistGroup = groupSupervisors.findIndex(group => group.name == groupName);
|
|
1439
|
+
|
|
1440
|
+
if (isExistGroup == -1) {
|
|
1441
|
+
groupSupervisors.push({
|
|
1442
|
+
id: keycloakGroupToSupervise.id,
|
|
1443
|
+
name: keycloakGroupToSupervise.name,
|
|
1444
|
+
supervisors: [`${userObject.username}`]
|
|
1445
|
+
})
|
|
1446
|
+
} else {
|
|
1447
|
+
groupSupervisors[isExistGroup].supervisors[0] += `,${userObject.username}`;
|
|
1448
|
+
}
|
|
1449
|
+
});
|
|
1450
|
+
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
let newUser = await this.createFinesseUser(userObject, token);
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
if (groupSupervisors.length != 0) {
|
|
1460
|
+
//Assigning Groups to Supervisors
|
|
1461
|
+
let assignedSupervisors = await teamsService.addSupervisorToGroup(groupSupervisors, token, keycloakConfig);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
});
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
resolve('All Groups Created');
|
|
1470
|
+
}
|
|
1471
|
+
});
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
} catch (er) {
|
|
1475
|
+
|
|
1476
|
+
let error = await this.checkErrorType(er);
|
|
1477
|
+
reject(error);
|
|
1478
|
+
}
|
|
1479
|
+
});
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1154
1482
|
//Authenticating Finesse User
|
|
1155
1483
|
async authenticateFinesse(username, password, finesseUrl, userRoles, finesseToken) {
|
|
1156
1484
|
|
package/services/teamsService.js
CHANGED
|
@@ -137,6 +137,126 @@ class TeamsService {
|
|
|
137
137
|
}
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
|
+
|
|
141
|
+
async getGroupsList(token, keycloakConfig) {
|
|
142
|
+
return new Promise(async (resolve, reject) => {
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
|
|
146
|
+
let URL = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups';
|
|
147
|
+
|
|
148
|
+
var config = {
|
|
149
|
+
method: 'get',
|
|
150
|
+
url: URL,
|
|
151
|
+
headers: {
|
|
152
|
+
'Accept': 'application/json',
|
|
153
|
+
'cache-control': 'no-cache',
|
|
154
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
155
|
+
},
|
|
156
|
+
headers: {
|
|
157
|
+
'Authorization': 'Bearer ' + token
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
|
|
163
|
+
let groups = await requestController.httpRequest(config, false);
|
|
164
|
+
let groupsList = groups.data;
|
|
165
|
+
|
|
166
|
+
resolve(groupsList);
|
|
167
|
+
|
|
168
|
+
} catch (error) {
|
|
169
|
+
reject(error);
|
|
170
|
+
}
|
|
171
|
+
} catch (er) {
|
|
172
|
+
reject("error" + er);
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async getUsersList(token, keycloakConfig) {
|
|
178
|
+
return new Promise(async (resolve, reject) => {
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
|
|
182
|
+
let URL = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/users?max=10000';
|
|
183
|
+
|
|
184
|
+
var config = {
|
|
185
|
+
method: 'get',
|
|
186
|
+
url: URL,
|
|
187
|
+
headers: {
|
|
188
|
+
'Accept': 'application/json',
|
|
189
|
+
'cache-control': 'no-cache',
|
|
190
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
191
|
+
},
|
|
192
|
+
headers: {
|
|
193
|
+
'Authorization': 'Bearer ' + token
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
|
|
199
|
+
let users = await requestController.httpRequest(config, false);
|
|
200
|
+
let usersList = users.data;
|
|
201
|
+
|
|
202
|
+
resolve(usersList);
|
|
203
|
+
|
|
204
|
+
} catch (error) {
|
|
205
|
+
reject(error);
|
|
206
|
+
}
|
|
207
|
+
} catch (er) {
|
|
208
|
+
reject("error" + er);
|
|
209
|
+
};
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async addSupervisorToGroup(supervisedGroups, token, keycloakConfig) {
|
|
214
|
+
|
|
215
|
+
let updatedGroups;
|
|
216
|
+
|
|
217
|
+
return new Promise(async (resolve, reject) => {
|
|
218
|
+
|
|
219
|
+
try {
|
|
220
|
+
|
|
221
|
+
supervisedGroups.forEach(async group => {
|
|
222
|
+
|
|
223
|
+
let URL = keycloakConfig["auth-server-url"] + 'admin/realms/' + keycloakConfig.realm + '/groups/' + group.id;
|
|
224
|
+
|
|
225
|
+
var config = {
|
|
226
|
+
method: 'put',
|
|
227
|
+
url: URL,
|
|
228
|
+
headers: {
|
|
229
|
+
'Accept': 'application/json',
|
|
230
|
+
'cache-control': 'no-cache',
|
|
231
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
232
|
+
},
|
|
233
|
+
headers: {
|
|
234
|
+
'Authorization': 'Bearer ' + token
|
|
235
|
+
},
|
|
236
|
+
data: {
|
|
237
|
+
name: group.name,
|
|
238
|
+
attributes: {
|
|
239
|
+
supervisor: group.supervisors
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
|
|
246
|
+
let groups = await requestController.httpRequest(config, false);
|
|
247
|
+
|
|
248
|
+
} catch (error) {
|
|
249
|
+
reject(error);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
resolve('Supervisors Added');
|
|
254
|
+
|
|
255
|
+
} catch (er) {
|
|
256
|
+
reject("error" + er);
|
|
257
|
+
};
|
|
258
|
+
});
|
|
259
|
+
}
|
|
140
260
|
}
|
|
141
261
|
|
|
142
262
|
module.exports = TeamsService;
|