Integrate Microsoft AD Domain to Synchronize Organizational Structure and Members
Overview
Enterprises typically use Microsoft AD Domain for organizational structure management, user management, etc. The following are the steps to synchronize organizational structure and members to Informat.
Implementation Code
javascript
const syncOrg = () => {
let connection = null;
try {
connection = informat.ldap.connect({
providerURL: "LDAP://1.13.173.190:389",
securityPrincipal: "userName",
securityCredentials: "password",
});
// Query all departments in the ou=Group,dc=informat,dc=cn directory
const result = connection.search("ou=Group,dc=informat,dc=cn", "objectClass=group", {
searchScope: "SUBTREE", // Search scope, default is SUBTREE. SUBTREE returns all matching entries, ONELEVEL returns entries at the same level, OBJECT returns only the matching object
});
// Output all entry names and their attributes
result.forEach((r) => {
let id = null;
let name = null;
let description = null;
let parentId = null;
r.attributes.forEach((ra) => {
if (ra.id === "cn") {
id = ra.values[0];
}
if (ra.id === "name") {
name = ra.values[0];
}
if (ra.id === "description") {
description = ra.values[0];
}
if (ra.id === "memberOf") {
const cnMatch = ra.values[0].match(/CN=([^,]+)/);
parentId = cnMatch ? cnMatch[1] : null;
}
});
let dept = {
id: id,
name: name,
description: description,
parentId: parentId,
};
addDept(dept);
});
} catch (e) {
// Failed to connect to LDAP server or authentication failed
console.error("ldap login failure");
} finally {
if (connection != null) {
connection.close();
}
}
};
/**
* Add department
* @param dept
*/
const addDept = (dept) => {
let deptExist = informat.dept.getDept(dept.id);
if (deptExist) {
return;
}
informat.dept.addDept({
id: dept.id,
name: dept.name,
shortName: dept.name,
parentId: dept.parentId ? dept.parentId : "root",
ownerList: ["zhangsan"], // Department owner, modify according to actual situation
remark: dept.description,
});
};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
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
javascript
const syncAccount = () => {
let connection = null;
try {
connection = informat.ldap.connect({
providerURL: "LDAP://1.13.173.190:389",
securityPrincipal: "userName",
securityCredentials: "password",
});
// Query all users in the cn=Users,dc=informat,dc=cn directory
const result = connection.search("cn=Users,dc=informat,dc=cn", "objectClass=user", {
searchScope: "SUBTREE", // Search scope, default is SUBTREE. SUBTREE returns all matching entries, ONELEVEL returns entries at the same level, OBJECT returns only the matching object
});
// Output all entry names and their attributes
result.forEach((r) => {
let userName = null;
let name = null;
let userAccountControl = null;
let deptList = [];
r.attributes.forEach((ra) => {
if (ra.id === "userPrincipalName") {
userName = ra.values[0];
}
if (ra.id === "name") {
name = ra.values[0];
}
if (ra.id === "userAccountControl") {
userAccountControl = ra.values[0];
}
if (ra.id === "memberOf") {
deptList = ra.values
.filter((group) => group.includes("OU="))
.map((group) => {
// Extract CN
const cnMatch = group.match(/CN=([^,]+)/);
return cnMatch ? cnMatch[1] : null;
})
.filter((cn) => cn !== null);
}
});
// Generate Informat account object
let account = {
userName: userName,
name: name,
password: "informat1234", // Default password
deptList: deptList,
};
if (isDisableAccount(userAccountControl)) {
// Disable the Informat account if the AD account is disabled
disableAccount(account);
}
addAccount(account);
});
} catch (e) {
// Failed to connect to LDAP server or authentication failed
console.error("ldap login failure");
} finally {
if (connection != null) {
connection.close();
}
}
};
const addAccount = (account) => {
// Create system account
let accountList = informat.system.queryAccountList({
pageSize: -1,
filter: {
conditionList: [
{
fieldId: "userName",
opt: "eq",
value: account.userName,
},
],
},
});
if (accountList.length !== 0) {
let existAccount = accountList[0];
if (!existAccount.isValid) {
informat.system.setAccountValid(existAccount.id, true);
}
return;
}
let accountId = informat.system.addAccount({
name: account.name,
avatar: "pic1.png",
userName: account.userName,
password: account.password,
});
// Add departments and system roles to the account
informat.company.addCompanyMember(accountId, account.deptList, ["normal"]);
};
/**
* Disable account
* @param account
*/
const disableAccount = (account) => {
// Query existing account
let accountList = informat.system.queryAccountList({
pageSize: -1,
filter: {
conditionList: [
{
fieldId: "userName",
opt: "eq",
value: account.userName,
},
],
},
});
if (accountList.length !== 0) {
let existAccount = accountList[0];
if (existAccount.isValid) {
informat.system.setAccountValid(existAccount.id, false);
}
}
};
/**
* Check if account is disabled
* @param userAccContr
* @returns {boolean}
*/
const isDisableAccount = (userAccContr) => {
// TRUSTED_TO_AUTH_FOR_DELEGATION - Allow the account to delegate authentication
if (userAccContr >= 16777216) {
userAccContr = userAccContr - 16777216;
}
// PASSWORD_EXPIRED - (Windows 2000/Windows Server 2003) The user's password has expired
if (userAccContr >= 8388608) {
userAccContr = userAccContr - 8388608;
}
// DONT_REQ_PREAUTH - Does not require preauthentication
if (userAccContr >= 4194304) {
userAccContr = userAccContr - 4194304;
}
// USE_DES_KEY_ONLY - (Windows 2000/Windows Server 2003) Restrict this user to use only Data Encryption Standard (DES) encryption type keys
if (userAccContr >= 2097152) {
userAccContr = userAccContr - 2097152;
}
// NOT_DELEGATED - After setting this flag, the user's security context will not be delegated to the service even if the service account is set to be trusted for Kerberos delegation
if (userAccContr >= 1048576) {
userAccContr = userAccContr - 1048576;
}
// TRUSTED_FOR_DELEGATION - After setting this flag, the service account (user or computer account) running the service will be trusted for Kerberos delegation. Any such service can impersonate the client requesting the service. To allow a service to perform Kerberos delegation, this flag must be set on the userAccountControl property of the service account
if (userAccContr >= 524288) {
userAccContr = userAccContr - 524288;
}
// SMARTCARD_REQUIRED - After setting this flag, the user will be forced to log in using a smart card
if (userAccContr >= 262144) {
userAccContr = userAccContr - 262144;
}
// MNS_LOGON_ACCOUNT - This is an MNS logon account
if (userAccContr >= 131072) {
userAccContr = userAccContr - 131072;
}
// DONT_EXPIRE_PASSWORD - Password never expires
if (userAccContr >= 65536) {
userAccContr = userAccContr - 65536;
}
// MNS_LOGON_ACCOUNT - This is an MNS logon account
if (userAccContr >= 2097152) {
userAccContr = userAccContr - 2097152;
}
// SERVER_TRUST_ACCOUNT - This is a computer account for a domain controller that belongs to this domain
if (userAccContr >= 8192) {
userAccContr = userAccContr - 8192;
}
// WORKSTATION_TRUST_ACCOUNT - This is a computer account for a computer running Microsoft Windows NT 4.0 Workstation, Microsoft Windows NT 4.0 Server, Microsoft Windows 2000 Professional, or Windows 2000 Server and belongs to this domain
if (userAccContr >= 4096) {
userAccContr = userAccContr - 4096;
}
// INTERDOMAIN_TRUST_ACCOUNT - For a system domain that trusts other domains, this property allows accounts that trust the system domain
if (userAccContr >= 2048) {
userAccContr = userAccContr - 2048;
}
// NORMAL_ACCOUNT - This is the default account type representing a typical user
if (userAccContr >= 512) {
userAccContr = userAccContr - 512;
}
// TEMP_DUPLICATE_ACCOUNT - This account belongs to a user whose primary account is in another domain. This account provides the user with access to this domain, but not to any domain that trusts this domain. This type of account is sometimes called a "local user account"
if (userAccContr >= 256) {
userAccContr = userAccContr - 256;
}
// ENCRYPTED_TEXT_PASSWORD_ALLOWED - User can send encrypted passwords
if (userAccContr >= 128) {
userAccContr = userAccContr - 128;
}
// PASSWD_CANT_CHANGE - User cannot change password. This flag can be read, but cannot be set directly
if (userAccContr >= 64) {
userAccContr = userAccContr - 64;
}
// PASSWD_NOTREQD - Password not required
if (userAccContr >= 32) {
userAccContr = userAccContr - 32;
}
// LOCKOUT
if (userAccContr >= 16) {
userAccContr = userAccContr - 16;
}
// HOMEDIR_REQUIRED - Home folder required
if (userAccContr >= 8) {
userAccContr = userAccContr - 8;
}
return userAccContr >= 2;
};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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

