-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtransportHelper.js
143 lines (128 loc) · 4.98 KB
/
transportHelper.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
const httpclient = require('@sap-cloud-sdk/http-client')
module.exports = class TransportHelper {
constructor (destinations) {
this.destinations = {
"source": destinations.source,
"target": destinations.target
}
this.suffix = {}
}
async initialize() {
return Promise.all([
this._loadSuffix("source"),
this._loadSuffix("target")
])
}
async transportRoleCollection (roleCollection) {
try {
let roleCollectionSource = await this._fetchRoleCollection(roleCollection)
let roleCollectionTarget = await this._replaceSuffix(roleCollectionSource)
await this._registerRoleCollection(roleCollectionTarget)
return {
roleCollection: roleCollection,
result: 'success'
}
} catch (err) {
return {
roleCollection: roleCollection,
result: 'error',
message: err.message
}
}
}
async _loadSuffix(target) {
let data = await SELECT .one .columns `suffix` .from `Suffix` .where `destination = ${this.destinations[target]}`
if (!data) {
throw new Error(`No suffix found for destination ${this.destinations[target]}`)
}
this.suffix[target] = data.suffix
}
async _fetchRoleCollection (roleCollection) {
const dest = {
destinationName : this.destinations["source"]
}
try {
const response = await httpclient.executeHttpRequest(dest, {
method: 'GET',
url: `/sap/rest/authorization/v2/rolecollections/${roleCollection}`
})
return response.data
} catch (err) {
if (err.response?.status === 404) {
throw new Error(`Role Collection ${roleCollection} not found`)
} else {
throw err
}
}
}
async _replaceSuffix (roleCollection) {
const sourceSuffix = this.suffix["source"]
const targetSuffix = this.suffix["target"]
const newRoleCollection = JSON.parse(JSON.stringify(roleCollection)); //deep copy
newRoleCollection.roleReferences.map(roleReference => {
roleReference.roleTemplateAppId = roleReference.roleTemplateAppId.replace(sourceSuffix, targetSuffix)
return roleReference
})
return newRoleCollection
}
async _registerRoleCollection(roleCollection) {
const dest = {
destinationName : this.destinations["target"]
}
//check if the role Collection already exists
try {
const response = await httpclient.executeHttpRequest(dest, {
method: 'GET',
url: `/sap/rest/authorization/v2/rolecollections/${roleCollection.name}`
})
return this._updateRoleCollection(roleCollection, response.data, dest)
} catch (err) {
if (err.response?.status === 404) {
//role collection does not exist, create it
return httpclient.executeHttpRequest(dest, {
method: 'POST',
url: `/sap/rest/authorization/v2/rolecollections`,
data: roleCollection
},{ fetchCsrfToken: false })
} else {
throw err
}
}
}
_updateRoleCollection(roleCollection, existingRoleCollection, dest) {
const sourceRoles = roleCollection.roleReferences
const targetRoles = existingRoleCollection.roleReferences
const rolesToAdd = this._getDiff(sourceRoles, targetRoles)
const rolesToRemove = this._getDiff(targetRoles, sourceRoles)
const addPromise = httpclient.executeHttpRequest(dest, {
method: 'PUT',
url: `/sap/rest/authorization/v2/rolecollections/${roleCollection.name}/roles`,
data: rolesToAdd
},{ fetchCsrfToken: false })
const removePromises = rolesToRemove.map(role => {
const roleName = role.roleName ? role.roleName : role.roleTemplateName
return httpclient.executeHttpRequest(dest, {
method: 'DELETE',
url: `/sap/rest/authorization/v2/rolecollections/${roleCollection.name}/roles/${role.roleTemplateAppId}/${roleName}/${role.roleTemplateName}`
},{ fetchCsrfToken: false })
})
return Promise.all([addPromise, ...removePromises])
}
_getDiff(source, target) {
if(!source) {
return []
}
return source.reduce((acc, role) => {
if (!this._roleExists(role, target)) {
acc.push(role)
}
return acc
}, [])
}
_roleExists(role, roles) {
if(!roles) {
return false
}
return roles.some(r => r.roleTemplateAppId === role.roleTemplateAppId && r.roleTemplateName === role.roleTemplateName)
}
}