@nsshunt/stsdatamanagement 1.12.10 → 1.12.14
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/databaseutils.js +6 -138
- package/datagenerator.js +2 -1
- package/db-scripts/apis.json +12 -0
- package/dbaccess.js +1 -2
- package/package.json +1 -1
- package/setupdb.js +1 -1
- package/blcauth.js +0 -388
package/databaseutils.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
const prompts = require('prompts');
|
|
2
|
-
const fs = require('fs');
|
|
3
2
|
require('colors');
|
|
4
|
-
//let crypto = require('crypto');
|
|
5
3
|
const goptions = require('@nsshunt/stsconfig').$options;
|
|
6
4
|
|
|
7
5
|
const { PGPoolManager } = require('./pgpoolmanager');
|
|
8
6
|
const { PGAccessLayer } = require('./pgaccesslayer');
|
|
9
7
|
const { PGUtils } = require('./pgutils');
|
|
10
|
-
const { BLCAuth } = require('./blcauth');
|
|
11
8
|
const { DataGenerator } = require('./datagenerator.js');
|
|
12
9
|
|
|
13
10
|
class DatabaseUtils
|
|
@@ -21,108 +18,12 @@ class DatabaseUtils
|
|
|
21
18
|
this.#debug = require('debug')(this.#ns);
|
|
22
19
|
this.#accessLayer = accessLayer;
|
|
23
20
|
}
|
|
24
|
-
|
|
25
|
-
#_RegisterRolesAndPermissions = async(blcauth) => {
|
|
26
|
-
this.#debug(`Registering Roles and Role Permissions.`.yellow);
|
|
27
|
-
console.log(`Registering Roles and Role Permissions.`.yellow);
|
|
28
|
-
const rolePermissionFile = `${goptions.databasescriptfolder}/role-permission.json`;
|
|
29
|
-
const rawdata = fs.readFileSync(rolePermissionFile);
|
|
30
|
-
let rolePermissions = JSON.parse(rawdata);
|
|
31
|
-
for (const [, rolePermission] of Object.entries(rolePermissions)) {
|
|
32
|
-
let retVal = await blcauth.AddRolePermissions(rolePermission);
|
|
33
|
-
if (retVal.status !== 200) {
|
|
34
|
-
console.log(`Role Permission registered: ${JSON.stringify(retVal)}`.red);
|
|
35
|
-
return false;
|
|
36
|
-
} else {
|
|
37
|
-
console.log(`Role Permission registered: ${JSON.stringify(retVal)}`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
#_RegisterUsersAndRoles = async(blcauth) => {
|
|
44
|
-
this.#debug(`Registering Users and Roles.`.yellow);
|
|
45
|
-
console.log(`Registering Users and Roles.`.yellow);
|
|
46
|
-
const roleFile = `${goptions.databasescriptfolder}/user-role.json`;
|
|
47
|
-
let rawdata = fs.readFileSync(roleFile);
|
|
48
|
-
let userroles = JSON.parse(rawdata);
|
|
49
|
-
for (const [, user] of Object.entries(userroles)) {
|
|
50
|
-
let retVal = await blcauth.AddUser(user);
|
|
51
|
-
if (retVal.status !== 200) {
|
|
52
|
-
console.log(`Role registered: ${JSON.stringify(retVal)}`.red);
|
|
53
|
-
return false;
|
|
54
|
-
} else {
|
|
55
|
-
console.log(`Role registered: ${JSON.stringify(retVal)}`);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
#_RegisterTestingUsersAndRoles = async(blcauth) => {
|
|
62
|
-
this.#debug(`Registering Test Users and Roles.`.yellow);
|
|
63
|
-
console.log(`Registering Test Users and Roles.`.yellow);
|
|
64
|
-
for (let i=0; i < 10; i++) {
|
|
65
|
-
let userNoStr = i.toString().padStart(2, '0');
|
|
66
|
-
let user = {
|
|
67
|
-
name: `Test User ${userNoStr}`,
|
|
68
|
-
email: `user${userNoStr}@stsmda.com.au`,
|
|
69
|
-
password: `user${userNoStr}password`,
|
|
70
|
-
roles: [ ]
|
|
71
|
-
}
|
|
72
|
-
let retVal = await blcauth.AddUser(user);
|
|
73
|
-
if (retVal.status !== 200) {
|
|
74
|
-
console.log(`User NOT registered: ${JSON.stringify(retVal)}`.red);
|
|
75
|
-
return false;
|
|
76
|
-
} else {
|
|
77
|
-
console.log(`User registered: ${JSON.stringify(retVal)}`);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
#_RegisterApplications = async(blcauth) => {
|
|
84
|
-
this.#debug(`Registering Applications.`.yellow);
|
|
85
|
-
console.log(`Registering Applications.`.yellow);
|
|
86
|
-
const roleFile = `${goptions.databasescriptfolder}/applications.json`;
|
|
87
|
-
let rawdata = fs.readFileSync(roleFile);
|
|
88
|
-
let applications = JSON.parse(rawdata);
|
|
89
|
-
for (const [, application] of Object.entries(applications)) {
|
|
90
|
-
//application.clientSecret = crypto.randomBytes(32).toString('base64');
|
|
91
|
-
let retVal = await blcauth.AddApplication(application);
|
|
92
|
-
if (retVal.status !== 200) {
|
|
93
|
-
console.log(`Application registered: ${JSON.stringify(retVal)}`.red);
|
|
94
|
-
return false;
|
|
95
|
-
} else {
|
|
96
|
-
console.log(`Application registered: ${JSON.stringify(retVal)}`);
|
|
97
|
-
console.log(`Application secret : ${application.clientSecret}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return true;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
#_RegisterAPIs = async(blcauth) => {
|
|
104
|
-
this.#debug(`Registering APIs.`.yellow);
|
|
105
|
-
console.log(`Registering APIs.`.yellow);
|
|
106
|
-
const roleFile = `${goptions.databasescriptfolder}/apis.json`;
|
|
107
|
-
let rawdata = fs.readFileSync(roleFile);
|
|
108
|
-
let apis = JSON.parse(rawdata);
|
|
109
|
-
for (const [, api] of Object.entries(apis)) {
|
|
110
|
-
let retVal = await blcauth.AddAPI(api);
|
|
111
|
-
if (retVal.status !== 200) {
|
|
112
|
-
console.log(`API registered: ${JSON.stringify(retVal)}`.red);
|
|
113
|
-
return false;
|
|
114
|
-
} else {
|
|
115
|
-
console.log(`API registered: ${JSON.stringify(retVal)}`);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
21
|
|
|
121
22
|
// options ::= { start: <int>, entries: <int>, minextradata: <int>, maxextradata: <int>,
|
|
122
23
|
// user: { name: <string>, password: <string>, email: <string> } }
|
|
123
|
-
|
|
24
|
+
CreateDatabase = async (options) =>
|
|
124
25
|
{
|
|
125
|
-
let fname = '
|
|
26
|
+
let fname = 'CreateDatabase';
|
|
126
27
|
const { start, entries, minextradata, maxextradata } = options;
|
|
127
28
|
let builddbscript = `${goptions.databasescriptfolder}/builddb.sql`;
|
|
128
29
|
this.#debug(`Database Build Script: [${builddbscript}]`.yellow);
|
|
@@ -149,6 +50,7 @@ class DatabaseUtils
|
|
|
149
50
|
this.#debug(`Building database assets (tables, functions, etc.).`.yellow);
|
|
150
51
|
await localAccesslayer.executedbscript(builddbscript);
|
|
151
52
|
|
|
53
|
+
//@@ make optional or move
|
|
152
54
|
if (typeof entries !== 'undefined') {
|
|
153
55
|
// Add new faker entries
|
|
154
56
|
this.#debug(`Adding test data.`.yellow);
|
|
@@ -156,37 +58,11 @@ class DatabaseUtils
|
|
|
156
58
|
await dg.RunAddFakerBulkInsert(start, entries, minextradata, maxextradata);
|
|
157
59
|
}
|
|
158
60
|
|
|
159
|
-
const blcauth = new BLCAuth(localAccesslayer);
|
|
160
|
-
let status = true;
|
|
161
|
-
|
|
162
|
-
status = await this.#_RegisterUsersAndRoles(blcauth);
|
|
163
|
-
if (status) {
|
|
164
|
-
status = await this.#_RegisterRolesAndPermissions(blcauth);
|
|
165
|
-
}
|
|
166
|
-
if (status) {
|
|
167
|
-
status = await this.#_RegisterTestingUsersAndRoles(blcauth);
|
|
168
|
-
}
|
|
169
|
-
if (status) {
|
|
170
|
-
status = await this.#_RegisterApplications(blcauth);
|
|
171
|
-
}
|
|
172
|
-
if (status) {
|
|
173
|
-
status = await this.#_RegisterAPIs(blcauth);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (status) {
|
|
177
|
-
let retVal = await blcauth.GetUserPermissions('STSREST01ServiceUser@stsmda.com');
|
|
178
|
-
console.log(`User Permissions: ${JSON.stringify(retVal)}`);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
61
|
await localAccesslayer.enddatabase();
|
|
182
62
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
} else {
|
|
187
|
-
this.#debug(`Database did not initiailize correctly.`.red);
|
|
188
|
-
console.log(`Database did not initiailize correctly.`.red);
|
|
189
|
-
}
|
|
63
|
+
//@@ double logging
|
|
64
|
+
this.#debug(`Database successfully initiailized.`.green);
|
|
65
|
+
console.log(`Database successfully initiailized.`.green);
|
|
190
66
|
} catch (error)
|
|
191
67
|
{
|
|
192
68
|
console.error(`[${fname}]: Could not create fresh database: ${error}`);
|
|
@@ -200,14 +76,6 @@ class DatabaseUtils
|
|
|
200
76
|
return retVal;
|
|
201
77
|
};
|
|
202
78
|
|
|
203
|
-
// user ::= { name: <string>, password: <string>, email: <string> }
|
|
204
|
-
RegisterTestUser = async (user) =>
|
|
205
|
-
{
|
|
206
|
-
let retVal = await new BLCAuth(this.#accessLayer).registeruser(user);
|
|
207
|
-
console.log(`User registered: ${JSON.stringify(retVal)}`);
|
|
208
|
-
return retVal;
|
|
209
|
-
};
|
|
210
|
-
|
|
211
79
|
ExecuteDatabaseScript = async (scriptfile) =>
|
|
212
80
|
{
|
|
213
81
|
let retVal = await this.#accessLayer.executedbscript(scriptfile);
|
package/datagenerator.js
CHANGED
|
@@ -175,7 +175,8 @@ class DataGenerator
|
|
|
175
175
|
|
|
176
176
|
|
|
177
177
|
let pa = [ ];
|
|
178
|
-
let numCPUs =
|
|
178
|
+
let numCPUs = goptions.useCPUs;
|
|
179
|
+
//let numCPUs = require('os').cpus().length;
|
|
179
180
|
let blocksize = Math.floor(iterations / numCPUs);
|
|
180
181
|
let lastBlockSize = blocksize + (iterations % numCPUs);
|
|
181
182
|
|
package/db-scripts/apis.json
CHANGED
|
@@ -41,6 +41,18 @@
|
|
|
41
41
|
"res01.delete"
|
|
42
42
|
]
|
|
43
43
|
}
|
|
44
|
+
],
|
|
45
|
+
"SPA": [
|
|
46
|
+
{
|
|
47
|
+
"clientName": "STSAuthenticateSPA",
|
|
48
|
+
"clientId": "v4qBrds3Autl/i86xT+5z0K53kJ/2hHTfxNo0QO/0Jk=",
|
|
49
|
+
"permissions": [
|
|
50
|
+
"res01.create",
|
|
51
|
+
"res01.read",
|
|
52
|
+
"res01.update",
|
|
53
|
+
"res01.delete"
|
|
54
|
+
]
|
|
55
|
+
}
|
|
44
56
|
]
|
|
45
57
|
},
|
|
46
58
|
|
package/dbaccess.js
CHANGED
|
@@ -2,7 +2,6 @@ const { PGPoolManager } = require('./pgpoolmanager');
|
|
|
2
2
|
const { L1Cache } = require('./l1cache');
|
|
3
3
|
const { PGAccessLayer } = require('./pgaccesslayer');
|
|
4
4
|
const { PGUtils } = require('./pgutils');
|
|
5
|
-
const { BLCAuth } = require('./blcauth');
|
|
6
5
|
const { DatabaseUtils } = require('./databaseutils');
|
|
7
6
|
const { DataGenerator } = require('./datagenerator');
|
|
8
7
|
const { CreateDatabase } = require('./setupdb');
|
|
@@ -13,7 +12,7 @@ const {
|
|
|
13
12
|
|
|
14
13
|
module.exports = {
|
|
15
14
|
// Utilities and Helpers
|
|
16
|
-
PGPoolManager, L1Cache, PGAccessLayer, PGUtils,
|
|
15
|
+
PGPoolManager, L1Cache, PGAccessLayer, PGUtils, DatabaseUtils, DataGenerator,
|
|
17
16
|
// Errors
|
|
18
17
|
STSDataManagementError, STSResourceNotFoundError, STSResourceMalformedError,
|
|
19
18
|
STSDatabaseAccessError, STSInvalidCredentials, STSNotAuthorized,
|
package/package.json
CHANGED
package/setupdb.js
CHANGED
package/blcauth.js
DELETED
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
const { status: { status } } = require('@nsshunt/stsutils');
|
|
2
|
-
const bcrypt = require('bcryptjs');
|
|
3
|
-
const { STSResourceNotFoundError, STSDatabaseAccessError, STSResourceMalformedError,
|
|
4
|
-
STSNotAuthorized, STSInvalidCredentials } = require('./dberrors');
|
|
5
|
-
|
|
6
|
-
class BLCAuth
|
|
7
|
-
{
|
|
8
|
-
static SYSTEM_USER_ID = "STS_SYSTEM";
|
|
9
|
-
static USER_ID_PREFIX = "USR_";
|
|
10
|
-
static ROLE_ID_PREFIX = "ROLE_";
|
|
11
|
-
static APPLICATION_ID_PREFIX = "APP_";
|
|
12
|
-
static API_ID_PREFIX = "API_";
|
|
13
|
-
|
|
14
|
-
#accessLayer = null;
|
|
15
|
-
|
|
16
|
-
constructor(accessLayer)
|
|
17
|
-
{
|
|
18
|
-
this.#accessLayer = accessLayer;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Normally, register would be provided by a hardened dedicated authentication server.
|
|
22
|
-
async AddUser(user)
|
|
23
|
-
{
|
|
24
|
-
let { name, password, email, roles } = user;
|
|
25
|
-
const saltRounds = 10;
|
|
26
|
-
try
|
|
27
|
-
{
|
|
28
|
-
let userid = BLCAuth.USER_ID_PREFIX + email;
|
|
29
|
-
if (await this.#ResourceExists('User', userid)) {
|
|
30
|
-
return {
|
|
31
|
-
status: status.conflict,
|
|
32
|
-
error: 'User already exists.',
|
|
33
|
-
detail: { message: `User already exists: [${userid}]` }
|
|
34
|
-
};
|
|
35
|
-
} else {
|
|
36
|
-
const hashedPassword = await bcrypt.hash(password, saltRounds);
|
|
37
|
-
|
|
38
|
-
let user = {
|
|
39
|
-
id: userid
|
|
40
|
-
,name: name
|
|
41
|
-
,email: email
|
|
42
|
-
,hash: hashedPassword
|
|
43
|
-
,roles: roles
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
await this.#accessLayer.saveResource(BLCAuth.SYSTEM_USER_ID, user.id, user);
|
|
47
|
-
|
|
48
|
-
let payload =
|
|
49
|
-
{
|
|
50
|
-
id: userid
|
|
51
|
-
,name: name
|
|
52
|
-
,email: email
|
|
53
|
-
,roles: roles
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return { status: status.success, detail: payload };
|
|
57
|
-
}
|
|
58
|
-
} catch (error)
|
|
59
|
-
{
|
|
60
|
-
console.error(error);
|
|
61
|
-
throw new Error({ status: status.error, error: 'Operation was not successful', detail: error });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async AddRolePermissions(rolePermissions)
|
|
66
|
-
{
|
|
67
|
-
try
|
|
68
|
-
{
|
|
69
|
-
const { name, permissions } = rolePermissions;
|
|
70
|
-
let roleId = BLCAuth.ROLE_ID_PREFIX + name;
|
|
71
|
-
if (await this.#ResourceExists('Role', roleId)) {
|
|
72
|
-
return {
|
|
73
|
-
status: status.conflict,
|
|
74
|
-
error: 'Role already exists.',
|
|
75
|
-
detail: { message: `Role already exists: [${roleId}]` }
|
|
76
|
-
};
|
|
77
|
-
} else {
|
|
78
|
-
let roleResource = {
|
|
79
|
-
id: roleId,
|
|
80
|
-
name: name,
|
|
81
|
-
permissions: permissions
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
await this.#accessLayer.saveResource(BLCAuth.SYSTEM_USER_ID, roleId, roleResource);
|
|
85
|
-
|
|
86
|
-
return { status: status.success, detail: roleResource };
|
|
87
|
-
}
|
|
88
|
-
} catch (error)
|
|
89
|
-
{
|
|
90
|
-
console.error(error);
|
|
91
|
-
throw new Error({ status: status.error, error: 'Operation was not successful', detail: error });
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async #GetResource(resource, resourceId) {
|
|
96
|
-
let resourceRaw = null;
|
|
97
|
-
try {
|
|
98
|
-
resourceRaw = await this.#accessLayer.getLatestResource(resourceId);
|
|
99
|
-
} catch (error) {
|
|
100
|
-
throw new STSDatabaseAccessError(resource, resourceId, error);
|
|
101
|
-
}
|
|
102
|
-
if (resourceRaw.status !== 200) {
|
|
103
|
-
throw new STSResourceNotFoundError(resource, resourceId);
|
|
104
|
-
}
|
|
105
|
-
try {
|
|
106
|
-
return JSON.parse(resourceRaw.detail.resdesc);
|
|
107
|
-
} catch (error) {
|
|
108
|
-
throw new STSResourceMalformedError(resource, resourceId, resourceRaw.detail.resdesc, error);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async #ResourceExists(resource, resourceId) {
|
|
113
|
-
try {
|
|
114
|
-
await this.#GetResource(resource, resourceId);
|
|
115
|
-
return true;
|
|
116
|
-
} catch (error) {
|
|
117
|
-
if (error instanceof STSResourceNotFoundError) {
|
|
118
|
-
return false;
|
|
119
|
-
} else {
|
|
120
|
-
throw error;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
async GetUser(email) {
|
|
126
|
-
return this.#GetResource('User', BLCAuth.USER_ID_PREFIX + email);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
async GetRole(role) {
|
|
130
|
-
return this.#GetResource('Role', BLCAuth.ROLE_ID_PREFIX + role);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async GetApplication(application) {
|
|
134
|
-
return this.#GetResource('Application', BLCAuth.APPLICATION_ID_PREFIX + application);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
async GetAPI(identifier) {
|
|
138
|
-
return this.#GetResource('API', BLCAuth.API_ID_PREFIX + identifier);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
async GetUserPermissions(email)
|
|
142
|
-
{
|
|
143
|
-
try
|
|
144
|
-
{
|
|
145
|
-
let userResource = await this.GetUser(email);
|
|
146
|
-
let permissions = [ ];
|
|
147
|
-
|
|
148
|
-
for (let i=0; i < userResource.roles.length; i++) {
|
|
149
|
-
let role = userResource.roles[i];
|
|
150
|
-
let roleResource = await this.GetRole(role);
|
|
151
|
-
for (let j=0; j < roleResource.permissions.length; j++) {
|
|
152
|
-
let permission = roleResource.permissions[j];
|
|
153
|
-
if (!permissions.includes(permission)) {
|
|
154
|
-
permissions.push(permission);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return { status: status.success, detail: permissions };
|
|
160
|
-
} catch (error)
|
|
161
|
-
{
|
|
162
|
-
console.error(error);
|
|
163
|
-
throw new Error({ status: status.error, error: 'Operation was not successful', detail: error });
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
async AddApplication(application)
|
|
168
|
-
{
|
|
169
|
-
try
|
|
170
|
-
{
|
|
171
|
-
const { clientId } = application;
|
|
172
|
-
let applicationId = BLCAuth.APPLICATION_ID_PREFIX + clientId;
|
|
173
|
-
if (await this.#ResourceExists('Application', applicationId)) {
|
|
174
|
-
return {
|
|
175
|
-
status: status.conflict,
|
|
176
|
-
error: 'Application already exists.',
|
|
177
|
-
detail: { message: `Application already exists: [${applicationId}]` }
|
|
178
|
-
};
|
|
179
|
-
} else {
|
|
180
|
-
let payload = {
|
|
181
|
-
applicationId,
|
|
182
|
-
...application
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
await this.#accessLayer.saveResource(BLCAuth.SYSTEM_USER_ID, applicationId, payload);
|
|
186
|
-
|
|
187
|
-
// Client Secret is not returned. Seperate function used to display this field.
|
|
188
|
-
delete payload.clientSecret;
|
|
189
|
-
|
|
190
|
-
return { status: status.success, detail: payload };
|
|
191
|
-
}
|
|
192
|
-
} catch (error)
|
|
193
|
-
{
|
|
194
|
-
console.error(error);
|
|
195
|
-
throw new Error({ status: status.error, error: 'Operation was not successful', detail: error });
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
#ValidateApplication = async (apiPermissions, app) => {
|
|
200
|
-
const { clientId, clientName, permissions } = app;
|
|
201
|
-
|
|
202
|
-
let applicationResource = null;
|
|
203
|
-
try {
|
|
204
|
-
applicationResource = await this.GetApplication(clientId)
|
|
205
|
-
} catch (error) {
|
|
206
|
-
return { status: status.notfound , error: 'Cannot find client application.', detail: { message: error.message }};
|
|
207
|
-
}
|
|
208
|
-
if (applicationResource.clientName.localeCompare(clientName) !== 0) {
|
|
209
|
-
return { status: status.error, error: 'clientName mismatch.', detail: { message: `clientName mismatch: Value: [${clientName}], Expecting: [${applicationResource.clientName}]` }};
|
|
210
|
-
}
|
|
211
|
-
for (let j=0; j < permissions.length; j++) {
|
|
212
|
-
const permission = permissions[j];
|
|
213
|
-
if (!apiPermissions.includes(permission)) {
|
|
214
|
-
return { status: status.error, error: `M2M permission not found within API available permission list.`, detail: { message: `Permission not found within API: [${clientName}:${clientId}] available permission list: [${permission}]` }};
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
async AddAPI(api)
|
|
221
|
-
{
|
|
222
|
-
try
|
|
223
|
-
{
|
|
224
|
-
const { M2MApplications, permissions: apiPermissions, identifier, SPA } = api;
|
|
225
|
-
|
|
226
|
-
let APIidentifier = BLCAuth.API_ID_PREFIX + identifier;
|
|
227
|
-
|
|
228
|
-
if (await this.#ResourceExists('API', APIidentifier)) {
|
|
229
|
-
return {
|
|
230
|
-
status: status.conflict,
|
|
231
|
-
error: 'API already exists.',
|
|
232
|
-
detail: { message: `API already exists: [${APIidentifier}]` }
|
|
233
|
-
};
|
|
234
|
-
} else {
|
|
235
|
-
// Validate M2MApplications
|
|
236
|
-
if (M2MApplications) {
|
|
237
|
-
for (let i=0; i < M2MApplications.length; i++) {
|
|
238
|
-
let retVal = await this.#ValidateApplication(apiPermissions, M2MApplications[i]);
|
|
239
|
-
if (retVal !== null) {
|
|
240
|
-
return retVal;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Validate SPA
|
|
246
|
-
if (SPA) {
|
|
247
|
-
for (let i=0; i < SPA.length; i++) {
|
|
248
|
-
let retVal = await this.#ValidateApplication(apiPermissions, SPA[i]);
|
|
249
|
-
if (retVal !== null) {
|
|
250
|
-
return retVal;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// Client Secret is not returned. Separate function used to display this field.
|
|
256
|
-
let payload =
|
|
257
|
-
{
|
|
258
|
-
APIidentifier,
|
|
259
|
-
...api
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
await this.#accessLayer.saveResource(BLCAuth.SYSTEM_USER_ID, APIidentifier, payload);
|
|
263
|
-
|
|
264
|
-
return { status: status.success, detail: payload };
|
|
265
|
-
}
|
|
266
|
-
} catch (error)
|
|
267
|
-
{
|
|
268
|
-
console.error(error);
|
|
269
|
-
throw new Error({ status: status.error, error: 'Operation was not successful', detail: error });
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
GetResourcesFromPermissions = (permissions) => {
|
|
274
|
-
let sep = '';
|
|
275
|
-
let resource = '';
|
|
276
|
-
let resourcesArr = [ ];
|
|
277
|
-
let resources = '';
|
|
278
|
-
let scopes = '';
|
|
279
|
-
permissions.forEach(permission => {
|
|
280
|
-
scopes += sep + permission;
|
|
281
|
-
sep = ' ';
|
|
282
|
-
let resourceParts = permission.split('.');
|
|
283
|
-
if (resourceParts.length !== 2) {
|
|
284
|
-
throw new STSResourceMalformedError('permission', 'N/A', permission);
|
|
285
|
-
}
|
|
286
|
-
resource = resourceParts[0];
|
|
287
|
-
if (!resourcesArr.includes(resource)) {
|
|
288
|
-
resourcesArr.push(resource);
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
if (resourcesArr.length !== 0) {
|
|
292
|
-
resources = resourcesArr.join(' ');
|
|
293
|
-
}
|
|
294
|
-
return {
|
|
295
|
-
scopes,
|
|
296
|
-
resources
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
#GetResourcesForApplication = (clientId, audience, app) => {
|
|
301
|
-
const permissions = app.permissions;
|
|
302
|
-
let sep = '';
|
|
303
|
-
let resource = '';
|
|
304
|
-
let scopes = '';
|
|
305
|
-
let resourcesArr = [ ];
|
|
306
|
-
permissions.forEach(permission => {
|
|
307
|
-
scopes += sep + permission;
|
|
308
|
-
sep = ' ';
|
|
309
|
-
let resourceParts = permission.split('.');
|
|
310
|
-
if (resourceParts.length !== 2) {
|
|
311
|
-
throw new STSResourceMalformedError(app, app.clientId, permission, null, { clientId, audience });
|
|
312
|
-
}
|
|
313
|
-
resource = resourceParts[0];
|
|
314
|
-
if (!resourcesArr.includes(resource)) {
|
|
315
|
-
resourcesArr.push(resource);
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
if (resourcesArr.length === 0) {
|
|
319
|
-
throw new STSNotAuthorized(clientId, audience);
|
|
320
|
-
}
|
|
321
|
-
const resources = resourcesArr.join(' ');
|
|
322
|
-
return {
|
|
323
|
-
scopes,
|
|
324
|
-
resources
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
// Get all the scopes (permissions) defined for this application (client_id) using this API (audience).
|
|
329
|
-
// client_secret required for M2M applications. Not required for SPA.
|
|
330
|
-
GetScopes = async (clientId, clientSecret, audience) => {
|
|
331
|
-
let applicationResource = await this.GetApplication(clientId);
|
|
332
|
-
|
|
333
|
-
if (applicationResource.clientSecret.localeCompare(clientSecret) !== 0) {
|
|
334
|
-
throw new STSInvalidCredentials('Application', clientId);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Get all permissions that have been provided for this client (client_id) using the specified API (audience).
|
|
338
|
-
let apiResource = await this.GetAPI(audience);
|
|
339
|
-
const { M2MApplications, SPA } = apiResource;
|
|
340
|
-
|
|
341
|
-
// Check for M2M applications.
|
|
342
|
-
if (M2MApplications) {
|
|
343
|
-
for (let i=0; i < M2MApplications.length; i++) {
|
|
344
|
-
let m2mApplication = M2MApplications[i];
|
|
345
|
-
if (m2mApplication.clientId.localeCompare(clientId) === 0) {
|
|
346
|
-
return this.#GetResourcesForApplication(clientId, audience, m2mApplication);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Check for SPA (single page applications).
|
|
352
|
-
if (SPA) {
|
|
353
|
-
for (let i=0; i < SPA.length; i++) {
|
|
354
|
-
let spaApplication = SPA[i];
|
|
355
|
-
if (spaApplication.clientId.localeCompare(clientId) === 0) {
|
|
356
|
-
return this.#GetResourcesForApplication(clientId, audience, spaApplication);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// client id not authorized for this API (i.e. no permissions for this client app have been created to access this API).
|
|
362
|
-
throw new STSNotAuthorized(clientId, audience);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
GetAPIsForClientId = async (clientId) => {
|
|
366
|
-
console.log(clientId);
|
|
367
|
-
let result = await this.#accessLayer.getResources(`${BLCAuth.API_ID_PREFIX}%`);
|
|
368
|
-
console.log(result);
|
|
369
|
-
}
|
|
370
|
-
/*
|
|
371
|
-
|
|
372
|
-
// Get all the scopes that the user (user_id) has previously consented for this application (client_id) using this API (audience).
|
|
373
|
-
async GetConsentedScopes(user_id, client_id, audience) {
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// Update scopes that the user (user_id) has consented for this application (client_id) using this API (audience).
|
|
378
|
-
async UpdateConsentedScopes(user_id, client_id, audience, scopes) {
|
|
379
|
-
|
|
380
|
-
}
|
|
381
|
-
*/
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
module.exports = { BLCAuth };
|