-
Notifications
You must be signed in to change notification settings - Fork 12
/
sram.py
300 lines (211 loc) · 10.9 KB
/
sram.py
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
"""Functions for communicating with SRAM and some utilities."""
__copyright__ = 'Copyright (c) 2023-2024, Utrecht University'
__license__ = 'GPLv3, see LICENSE'
import datetime
import time
from typing import Dict, List
import requests
import session_vars
import mail
from util import *
def sram_post_collaboration(ctx: rule.Context, group_name: str, description: str) -> Dict:
"""Create SRAM Collaborative Organisation Identifier.
:param ctx: Combined type of a callback and rei struct
:param group_name: Name of the group to create
:param description: Description of the group to create
:returns: JSON object with new collaboration details
"""
url = "{}/api/collaborations/v1".format(config.sram_rest_api_url)
headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Authorization': 'bearer ' + config.sram_api_key}
group_type = ''
if group_name.split('-')[0] in ('research', 'datamanager', 'priv', 'deposit'):
group_type = group_name.split('-')[0]
disable_join_requests = True
if config.sram_flow == 'join_request':
disable_join_requests = False
# Build SRAM payload.
payload = {
"name": 'yoda-' + group_name,
"description": description,
"disable_join_requests": disable_join_requests,
"disclose_member_information": True,
"disclose_email_information": True,
"administrators": [session_vars.get_map(ctx.rei)["client_user"]["user_name"]],
"logo": config.sram_co_logo_url,
"tags": [config.sram_co_default_label, group_type]
}
if config.sram_verbose_logging:
log.write(ctx, "post {}: {}".format(url, payload))
response = requests.post(url, json=payload, headers=headers, timeout=30, verify=config.sram_tls_verify)
data = response.json()
if config.sram_verbose_logging:
log.write(ctx, "response: {}".format(data))
return data
def sram_get_uid(ctx: rule.Context, co_identifier: str, user_name: str) -> str:
"""Get SRAM Collaboration member uid.
:param ctx: Combined type of a callback and rei struct
:param co_identifier: SRAM CO identifier
:param user_name: Name of the user
:returns: Unique id of the user
"""
url = "{}/api/collaborations/v1/{}".format(config.sram_rest_api_url, co_identifier)
headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Authorization': 'bearer ' + config.sram_api_key}
if config.sram_verbose_logging:
log.write(ctx, "get {}".format(url))
response = requests.get(url, headers=headers, timeout=30, verify=config.sram_tls_verify)
data = response.json()
if config.sram_verbose_logging:
log.write(ctx, "response: {}".format(data))
uid = ''
for key in data['collaboration_memberships']:
yoda_name = user_name.split('#')[0]
sram_name = key['user']['email']
if yoda_name.lower() == sram_name.lower():
uid = key['user']['uid']
if config.sram_verbose_logging:
log.write(ctx, "user_name: {}, uuid: {}".format(user_name.split('#')[0], uid))
return uid
def sram_delete_collaboration(ctx: rule.Context, co_identifier: str) -> bool:
"""Delete SRAM Collaborative Organisation.
:param ctx: Combined type of a callback and rei struct
:param co_identifier: SRAM CO identifier
:returns: Boolean indicating of deletion of collaboration succeeded
"""
url = "{}/api/collaborations/v1/{}".format(config.sram_rest_api_url, co_identifier)
headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Authorization': 'bearer ' + config.sram_api_key}
if config.sram_verbose_logging:
log.write(ctx, "post {}".format(url))
response = requests.delete(url, headers=headers, timeout=30, verify=config.sram_tls_verify)
if config.sram_verbose_logging:
log.write(ctx, "response: {}".format(response.status_code))
return response.status_code == 204
def sram_delete_collaboration_membership(ctx: rule.Context, co_identifier: str, uuid: str) -> bool:
"""Delete SRAM Collaborative Organisation membership.
:param ctx: Combined type of a callback and rei struct
:param co_identifier: SRAM CO identifier
:param uuid: Unique id of the user
:returns: Boolean indicating of deletion of collaboration membership succeeded
"""
url = "{}/api/collaborations/v1/{}/members/{}".format(config.sram_rest_api_url, co_identifier, uuid)
headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Authorization': 'bearer ' + config.sram_api_key}
if config.sram_verbose_logging:
log.write(ctx, "post {}".format(url))
response = requests.delete(url, headers=headers, timeout=30, verify=config.sram_tls_verify)
if config.sram_verbose_logging:
log.write(ctx, "response: {}".format(response.status_code))
return response.status_code == 204
def sram_put_collaboration_invitation(ctx: rule.Context, group_name: str, username: str, co_identifier: str) -> bool:
"""Create SRAM Collaborative Organisation Identifier.
:param ctx: Combined type of a ctx and rei struct
:param group_name: Name of the group the user is to invited to join
:param username: Name of the user to be invited
:param co_identifier: SRAM identifier of the group the user is to invited to join
:returns: Boolean indicating if put of new collaboration invitation succeeded
"""
url = "{}/api/invitations/v1/collaboration_invites".format(config.sram_rest_api_url)
headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Authorization': 'bearer ' + config.sram_api_key}
# Now plus a year.
expiration_date = datetime.datetime.fromtimestamp(int(time.time() + 3600 * 24 * 365)).strftime('%Y-%m-%d')
# Get epoch expiry date.
date = datetime.datetime.strptime(expiration_date, "%Y-%m-%d")
epoch = datetime.datetime.utcfromtimestamp(0)
epoch_date = int((date - epoch).total_seconds()) * 1000
# Build SRAM payload.
payload = {
"collaboration_identifier": co_identifier,
"message": "Invitation to join Yoda group {}".format(group_name),
"intended_role": "member",
"invitation_expiry_date": epoch_date,
"invites": [
username
],
"groups": []
}
if config.sram_verbose_logging:
log.write(ctx, "put {}: {}".format(url, payload))
response = requests.put(url, json=payload, headers=headers, timeout=30, verify=config.sram_tls_verify)
if config.sram_verbose_logging:
log.write(ctx, "response: {}".format(response.status_code))
return response.status_code == 201
def sram_connect_service_collaboration(ctx: rule.Context, short_name: str) -> bool:
"""Connect a service to an existing SRAM collaboration.
:param ctx: Combined type of a ctx and rei struct
:param short_name: Short name of the group collaboration
:returns: Boolean indicating if connecting a service to an existing collaboration succeeded
"""
url = "{}/api/collaborations_services/v1/connect_collaboration_service".format(config.sram_rest_api_url)
headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Authorization': 'bearer ' + config.sram_api_key}
# Build SRAM payload.
payload = {
"short_name": short_name,
"service_entity_id": config.sram_service_entity_id
}
if config.sram_verbose_logging:
log.write(ctx, "put {}: {}".format(url, payload))
response = requests.put(url, json=payload, headers=headers, timeout=30, verify=config.sram_tls_verify)
if config.sram_verbose_logging:
log.write(ctx, "response: {}".format(response.status_code))
return response.status_code == 201
def invitation_mail_group_add_user(ctx: rule.Context, group_name: str, username: str, co_identifier: str) -> str:
"""Send invitation email to newly added user to the group.
:param ctx: Combined type of a ctx and rei struct
:param group_name: Name of the group the user is to invited to join
:param username: Name of the user to be invited
:param co_identifier: SRAM identifier of the group included in the invitation link
:returns: Sends the invitation mail to the user
"""
return mail.send(ctx,
to=username,
cc='',
actor=user.full_name(ctx),
subject=("Invitation to join collaboration {}".format(group_name)),
body="""Dear {},
You have been invited by {} to join a collaboration page.
The following link will take you directly to SRAM: {}/registration?collaboration={}
With kind regards,
Yoda
""".format(username.split('@')[0], session_vars.get_map(ctx.rei)["client_user"]["user_name"], config.sram_rest_api_url, co_identifier))
def sram_update_collaboration_membership(ctx: rule.Context, co_identifier: str, uuid: str, new_role: str) -> bool:
"""Update SRAM Collaborative Organisation membership.
:param ctx: Combined type of a callback and rei struct
:param co_identifier: SRAM CO identifier
:param uuid: Unique id of the user
:param new_role: New role of the user
:returns: Boolean indicating that updation of collaboration membership succeeded
"""
url = "{}/api/collaborations/v1/{}/members".format(config.sram_rest_api_url, co_identifier)
headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Authorization': 'bearer ' + config.sram_api_key}
if new_role == 'manager':
role = 'admin'
else:
role = 'member'
payload = {
"role": role,
"uid": uuid
}
if config.sram_verbose_logging:
log.write(ctx, "put {}".format(url))
response = requests.put(url, json=payload, headers=headers, timeout=30, verify=config.sram_tls_verify)
if config.sram_verbose_logging:
log.write(ctx, "response: {}".format(response.status_code))
return response.status_code == 201
def sram_get_co_members(ctx: rule.Context, co_identifier: str) -> List[str]:
"""Get SRAM Collaboration members.
:param ctx: Combined type of a callback and rei struct
:param co_identifier: SRAM CO identifier
:returns: List of emails of the SRAM Collaboration members
"""
url = "{}/api/collaborations/v1/{}".format(config.sram_rest_api_url, co_identifier)
headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Authorization': 'bearer ' + config.sram_api_key}
if config.sram_verbose_logging:
log.write(ctx, "get {}".format(url))
response = requests.get(url, headers=headers, timeout=30, verify=config.sram_tls_verify)
data = response.json()
if config.sram_verbose_logging:
log.write(ctx, "response: {}".format(data))
co_members = []
for key in data['collaboration_memberships']:
co_members.append(key['user']['email'])
if config.sram_verbose_logging:
log.write(ctx, "collaboration_members: {}".format(co_members))
return co_members