-
Notifications
You must be signed in to change notification settings - Fork 13
/
uuDatarequests.r
248 lines (225 loc) · 11.3 KB
/
uuDatarequests.r
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
# \file uuDatarequest.py
# \brief Functions to handle data requests (only methods that have not been
# rewritten in Python yet).
# \copyright Copyright (c) 2019 Utrecht University. All rights reserved.
# \license GPLv3, see LICENSE.
# \brief Request data request metadata change
#
# \param[in] requestColl Path to collection of the data
# request
# \param[in] attributeName Name of attribute to change
# \param[in] newAttributeValue New value of attribute
# \param[in] newAttributeValueArrayLength If newAttributeValue is a JSON
# array, specify length. Needed for
# parsing
#
requestDatarequestMetadataChange(*requestColl, *attributeName,
*newAttributeValue, *newAttributeValueArrayLength,
*status, *statusInfo) {
# Set default status
*status = -1;
*statusInfo = "Internal server error";
# Get full name of user requesting the metadata change (i.e. the actor)
*actor = uuClientFullName;
# Retrieve collection id
foreach(*row in SELECT COLL_ID WHERE COLL_NAME = *requestColl
AND DATA_NAME = 'datarequest.json') {
*collId = *row.COLL_ID;
}
# Set the path of the user group to which the data request belongs.
# Hardcoded for now as all data requests are stored in the same user
# group
*actorGroupPath = "/$rodsZoneClient/home/datarequests-research";
# Construct key-value pair (the key specifies the collection on which
# the metadata change should be applied; the value is a JSON array
# consisting of the path to the data request collection, the attribute
# name, the new attribute value and the actor)
*json_str = "[]";
*size = 0;
msi_json_arrayops(*json_str, *requestColl, "add", *size);
msi_json_arrayops(*json_str, *attributeName, "add", *size);
msi_json_arrayops(*json_str, *newAttributeValue, "add", *size);
msi_json_arrayops(*json_str, *newAttributeValueArrayLength, "add", *size);
msi_json_arrayops(*json_str, *actor, "add", *size);
msiString2KeyValPair("", *kvp);
msiAddKeyVal(*kvp, UUORGMETADATAPREFIX ++ "datarequest_action_" ++
*collId, *json_str);
# Set the delayed rule on the actor group (to be picked up and
# processed when adminDatarequestActions is called)
*err = errormsg(msiSetKeyValuePairsToObj(*kvp, *actorGroupPath, "-C"),
*msg);
if (*err < 0) {
*status = "Unrecoverable";
*statusInfo = "*err - *msg";
succeed;
}
# Add data request action status to actor group
*requestStatus = UUORGMETADATAPREFIX ++
"datarequest_status_action_" ++ "*collId=PENDING";
msiString2KeyValPair(*requestStatus, *kvp);
*err = errormsg(msiSetKeyValuePairsToObj(*kvp, *actorGroupPath, "-C"),
*msg);
if (*err < 0) {
*status = "Unrecoverable";
*statusInfo = "*err - *msg";
succeed;
} else {
*status = "Success";
*statusInfo = "";
succeed;
}
}
# \brief Perform admin operations on the data request
#
adminDatarequestActions() {
msiExecCmd("admin-datarequestactions.sh", uuClientFullName, "", "", 0,
*out);
}
# \brief Grant or revoke temporary permissions on a file for the invoking user
adminTempWritePermission(*path, *permission) {
adminTempWritePermission(*path, *permission, uuClientFullName);
}
# \brief Grant or revoke temporary permissions on a file of a given user
adminTempWritePermission(*path, *permission, *user) {
*argv = uuClientFullName ++ " *path *permission *user";
msiExecCmd("admin-datarequest-temp-write-permission.sh", *argv, "", "", 0, *out);
}
# \brief Process request to change data request metadata
#
# \param[in] requestColl Collection of the data request whose
# metadata should be changed
# \param[in] attributeName Name of metadata attribute to change
# \param[in] newAttributeValue The new value of the metadata
# attribute
# \param[in] newAttributeValueArrayLength The length of the array in case
# newAttributeValue is a JSON array
# \param[in] actor The user that has requested the
# change
#
# \return Status and statusInfo (reports the
# success/failure of the processing)
#
uuDatarequestProcessMetadataChange(*datarequestColl, *attributeName,
*newAttributeValue,
*newAttributeValueArrayLength, *actor,
*status, *statusInfo) {
# Set default status
*status = "Unknown";
*statusInfo = "An internal error has occurred";
# Check if user is rodsadmin (this is required)
uuGetUserType(uuClientFullName, *userType);
if (*userType != "rodsadmin") {
writeLine("stdout", "uuDatarequestProcessMetadataChange: " ++
"Should only be called by a rodsadmin");
fail;
}
# Construct file path of file whose metadata should be changed
*filePath = *datarequestColl ++ "/datarequest.json";
# Grant temporary write ACL
msiSetACL("default", "admin:write", uuClientFullName, *filePath);
# Not so elegant way to handle the special case of assigning a data
# request for review to one or more DAC members
if (*attributeName == "assignedForReview") {
# Check if data request is already assigned. If so, remove
# the current assignees
*alreadyAssigned = false;
foreach(*row in SELECT META_DATA_ATTR_VALUE WHERE
COLL_NAME = *datarequestColl AND
DATA_NAME = "datarequest.json" AND
META_DATA_ATTR_NAME = *attributeName) {
*alreadyAssigned = true;
}
if (*alreadyAssigned) {
*err = msi_rmw_avu("-d", *filePath, "assignedForReview",
"%", "%");
}
# Convert JSON array of assignees to list
*assignees = list();
for (*i = 0;
*i < int(*newAttributeValueArrayLength);
*i = *i + 1) {
*assignee = "";
msi_json_arrayops(*newAttributeValue, *assignee,
"get", *i);
*assignees = cons(*assignee, *assignees);
}
# Set assignedForReview metadata on the data request
foreach(*assignee in *assignees) {
*AttrValStr = *attributeName ++ "=" ++ *assignee;
msiString2KeyValPair(*AttrValStr, *Kvp);
*err = errormsg(msiAssociateKeyValuePairsToObj(*Kvp,
*filePath, "-d"), *msg);
if (*err < 0) {
if (*err == -818000) {
*status = "PermissionDenied";
*statusInfo = "User is not " ++
"permitted to modify " ++
"this attribute";
} else {
*status = "Unrecoverable";
*statusInfo = "*err - *msg";
}
} else {
*status = "Success";
*statusInfo = "";
}
}
} else if (*attributeName == "reviewedBy") {
# Do not change existing reviewedBy KVPs if present; set new one instead
*AttrValStr = *attributeName ++ "=" ++ *newAttributeValue;
msiString2KeyValPair(*AttrValStr, *Kvp);
*err = errormsg(msiAssociateKeyValuePairsToObj(*Kvp,
*filePath, "-d"), *msg);
if (*err < 0) {
if (*err == -818000) {
*status = "PermissionDenied";
*statusInfo = "User is not " ++
"permitted to modify " ++
"this attribute";
} else {
*status = "Unrecoverable";
*statusInfo = "*err - *msg";
}
} else {
*status = "Success";
*statusInfo = "";
}
} else {
# Check if requested change isn't already present
*currentAttributeValue = "";
foreach(*row in SELECT META_DATA_ATTR_VALUE WHERE
COLL_NAME = *datarequestColl AND
DATA_NAME = "datarequest.json" AND
META_DATA_ATTR_NAME = *attributeName) {
*currentAttributeValue = *row.META_DATA_ATTR_VALUE;
}
# If it is, do not apply the requested change
if (*currentAttributeValue == *newAttributeValue) {
*status = "Success";
*statusInfo = "";
# If not, apply the request change
} else {
*AttrValStr = *attributeName ++ "=" ++
*newAttributeValue;
msiString2KeyValPair(*AttrValStr, *Kvp);
*err = errormsg(msiSetKeyValuePairsToObj(*Kvp,
*filePath, "-d"), *msg);
if (*err < 0) {
if (*err == -818000) {
*status = "PermissionDenied";
*statusInfo = "User is not " ++
"permitted to modify " ++
"this attribute";
} else {
*status = "Unrecoverable";
*statusInfo = "*err - *msg";
}
} else {
*status = "Success";
*statusInfo = "";
}
}
}
# Reset write ACL to "own"
msiSetACL("default", "admin:own", uuClientFullName, *filePath);
}