2
2
"""
3
3
from DIRAC import S_OK , S_ERROR
4
4
from DIRAC .Core .DISET .RequestHandler import RequestHandler
5
+ from DIRAC .Core .Security .Properties import SecurityProperty
5
6
from DIRAC .Core .Utilities .DEncode import ignoreEncodeWarning
6
7
from DIRAC .Core .Utilities .ObjectLoader import ObjectLoader
7
8
from DIRAC .ConfigurationSystem .Client .Helpers .Operations import Operations
@@ -33,6 +34,32 @@ def initializeHandler(cls, serviceInfoDict):
33
34
34
35
return S_OK ()
35
36
37
+ def checkPermissions (self , transName : str ):
38
+ """
39
+ checks if remote user has permission to access to a given transformation
40
+
41
+ :param str transName: Name of the transformation to check
42
+
43
+ :return: S_ERROR if user does not have permission or if transformation does not exist
44
+ S_OK otherwise
45
+ """
46
+ credDict = self .getRemoteCredentials ()
47
+ groupProperties = credDict .get ("properties" , [])
48
+ if SecurityProperty .PRODUCTION_MANAGEMENT in groupProperties :
49
+ return S_OK ()
50
+ tfDetails = self .transformationDB .getTransformation (transName )
51
+ if not tfDetails ["OK" ]:
52
+ return S_ERROR (f"Could not retrieve transformation { transName } details for permissions check." )
53
+ authorGroup = tfDetails ["Value" ]["AuthorGroup" ]
54
+ author = tfDetails ["Value" ]["Author" ]
55
+ if SecurityProperty .PRODUCTION_SHARING in groupProperties :
56
+ if authorGroup == credDict .get ("group" , None ):
57
+ return S_OK ()
58
+ if SecurityProperty .PRODUCTION_USER in groupProperties :
59
+ if author == credDict .get ("username" , None ):
60
+ return S_OK ()
61
+ return S_ERROR (f"You do not have permissions for transformation { transName } " )
62
+
36
63
types_getCounters = [str , list , dict ]
37
64
38
65
@classmethod
@@ -70,6 +97,13 @@ def export_addTransformation(
70
97
credDict = self .getRemoteCredentials ()
71
98
author = credDict .get ("username" )
72
99
authorGroup = credDict .get ("group" )
100
+ groupProperties = credDict .get ("properties" , [])
101
+ if (
102
+ SecurityProperty .PRODUCTION_MANAGEMENT not in groupProperties
103
+ and SecurityProperty .PRODUCTION_SHARING not in groupProperties
104
+ and SecurityProperty .PRODUCTION_USER not in groupProperties
105
+ ):
106
+ return S_ERROR ("You do not have permission to add a Transformation" )
73
107
res = self .transformationDB .addTransformation (
74
108
transName ,
75
109
description ,
@@ -97,36 +131,45 @@ def export_addTransformation(
97
131
types_deleteTransformation = [[int , str ]]
98
132
99
133
def export_deleteTransformation (self , transName ):
134
+ if not (result := self .checkPermissions (transName ))["OK" ]:
135
+ return result
100
136
credDict = self .getRemoteCredentials ()
101
137
author = credDict .get ("username" )
102
138
return self .transformationDB .deleteTransformation (transName , author = author )
103
139
104
140
types_completeTransformation = [[int , str ]]
105
141
106
142
def export_completeTransformation (self , transName ):
143
+ if not (result := self .checkPermissions (transName ))["OK" ]:
144
+ return result
107
145
credDict = self .getRemoteCredentials ()
108
146
author = credDict .get ("username" )
109
147
return self .transformationDB .setTransformationParameter (transName , "Status" , "Completed" , author = author )
110
148
111
149
types_cleanTransformation = [[int , str ]]
112
150
113
151
def export_cleanTransformation (self , transName ):
152
+ if not (result := self .checkPermissions (transName ))["OK" ]:
153
+ return result
114
154
credDict = self .getRemoteCredentials ()
115
155
author = credDict .get ("username" )
116
156
return self .transformationDB .cleanTransformation (transName , author = author )
117
157
118
158
types_setTransformationParameter = [[int , str ], str ]
119
159
120
160
def export_setTransformationParameter (self , transName , paramName , paramValue ):
161
+ if not (result := self .checkPermissions (transName ))["OK" ]:
162
+ return result
121
163
credDict = self .getRemoteCredentials ()
122
164
author = credDict .get ("username" )
123
165
return self .transformationDB .setTransformationParameter (transName , paramName , paramValue , author = author )
124
166
125
167
types_deleteTransformationParameter = [[int , str ], str ]
126
168
127
- @classmethod
128
- def export_deleteTransformationParameter (cls , transName , paramName ):
129
- return cls .transformationDB .deleteTransformationParameter (transName , paramName )
169
+ def export_deleteTransformationParameter (self , transName , paramName ):
170
+ if not (result := self .checkPermissions (transName ))["OK" ]:
171
+ return result
172
+ return self .transformationDB .deleteTransformationParameter (transName , paramName )
130
173
131
174
types_getTransformations = []
132
175
@@ -159,15 +202,21 @@ def export_getTransformations(
159
202
160
203
types_getTransformation = [[int , str ]]
161
204
162
- @classmethod
163
- def export_getTransformation (cls , transName , extraParams = False ):
164
- return cls .transformationDB .getTransformation (transName , extraParams = extraParams )
205
+ def export_getTransformation (self , transName , extraParams = False ):
206
+ # check first if transformation exists to avoid returning permissions error for non-existing transformation
207
+ tfDetails = self .transformationDB .getTransformation (transName , extraParams = extraParams )
208
+ if not tfDetails ["OK" ]:
209
+ return tfDetails
210
+ if not (result := self .checkPermissions (transName ))["OK" ]:
211
+ return result
212
+ return tfDetails
165
213
166
214
types_getTransformationParameters = [[int , str ], [str , list ]]
167
215
168
- @classmethod
169
- def export_getTransformationParameters (cls , transName , parameters ):
170
- return cls .transformationDB .getTransformationParameters (transName , parameters )
216
+ def export_getTransformationParameters (self , transName , parameters ):
217
+ if not (result := self .checkPermissions (transName ))["OK" ]:
218
+ return result
219
+ return self .transformationDB .getTransformationParameters (transName , parameters )
171
220
172
221
types_getTransformationWithStatus = [[str , list , tuple ]]
173
222
@@ -182,28 +231,30 @@ def export_getTransformationWithStatus(cls, status):
182
231
183
232
types_addFilesToTransformation = [[int , str ], [list , tuple ]]
184
233
185
- @classmethod
186
- def export_addFilesToTransformation (cls , transName , lfns ):
187
- return cls .transformationDB .addFilesToTransformation (transName , lfns )
234
+ def export_addFilesToTransformation (self , transName , lfns ):
235
+ if not (result := self .checkPermissions (transName ))["OK" ]:
236
+ return result
237
+ return self .transformationDB .addFilesToTransformation (transName , lfns )
188
238
189
239
types_addTaskForTransformation = [[int , str ]]
190
240
191
- @classmethod
192
- def export_addTaskForTransformation (cls , transName , lfns = [], se = "Unknown" ):
193
- return cls .transformationDB .addTaskForTransformation (transName , lfns = lfns , se = se )
241
+ def export_addTaskForTransformation (self , transName , lfns = [], se = "Unknown" ):
242
+ if not (result := self .checkPermissions (transName ))["OK" ]:
243
+ return result
244
+ return self .transformationDB .addTaskForTransformation (transName , lfns = lfns , se = se )
194
245
195
246
types_setFileStatusForTransformation = [[int , str ], dict ]
196
247
197
- @classmethod
198
248
@ignoreEncodeWarning
199
- def export_setFileStatusForTransformation (cls , transName , dictOfNewFilesStatus ):
249
+ def export_setFileStatusForTransformation (self , transName , dictOfNewFilesStatus ):
200
250
"""Sets the file status for the transformation.
201
251
202
252
The dictOfNewFilesStatus is a dictionary with the form:
203
253
{12345: ('StatusA', errorA), 6789: ('StatusB',errorB), ... } where the keys are fileIDs
204
254
The tuple may be a string with only the status if the client was from an older version
205
255
"""
206
-
256
+ if not (result := self .checkPermissions (transName ))["OK" ]:
257
+ return result
207
258
if not dictOfNewFilesStatus :
208
259
return S_OK ({})
209
260
@@ -213,35 +264,43 @@ def export_setFileStatusForTransformation(cls, transName, dictOfNewFilesStatus):
213
264
else :
214
265
return S_ERROR ("Status field should be two values" )
215
266
216
- res = cls .transformationDB ._getConnectionTransID (False , transName )
267
+ res = self .transformationDB ._getConnectionTransID (False , transName )
217
268
if not res ["OK" ]:
218
269
return res
219
270
connection = res ["Value" ]["Connection" ]
220
271
transID = res ["Value" ]["TransformationID" ]
221
272
222
- return cls .transformationDB .setFileStatusForTransformation (transID , newStatusForFileIDs , connection = connection )
273
+ return self .transformationDB .setFileStatusForTransformation (transID , newStatusForFileIDs , connection = connection )
223
274
224
275
types_getTransformationStats = [[int , str ]]
225
276
226
- @classmethod
227
- def export_getTransformationStats (cls , transName ):
228
- return cls .transformationDB .getTransformationStats (transName )
277
+ def export_getTransformationStats (self , transName ):
278
+ if not (result := self .checkPermissions (transName ))["OK" ]:
279
+ return result
280
+ return self .transformationDB .getTransformationStats (transName )
229
281
230
282
types_getTransformationFilesCount = [[int , str ], str ]
231
283
232
- @classmethod
233
- def export_getTransformationFilesCount (cls , transName , field , selection = {}):
234
- return cls .transformationDB .getTransformationFilesCount (transName , field , selection = selection )
284
+ def export_getTransformationFilesCount (self , transName , field , selection = {}):
285
+ if not (result := self .checkPermissions (transName ))["OK" ]:
286
+ return result
287
+ return self .transformationDB .getTransformationFilesCount (transName , field , selection = selection )
235
288
236
289
types_getTransformationFiles = []
237
290
238
- @classmethod
239
291
def export_getTransformationFiles (
240
- cls , condDict = None , older = None , newer = None , timeStamp = "LastUpdate" , orderAttribute = None , limit = None , offset = None
292
+ self ,
293
+ condDict = None ,
294
+ older = None ,
295
+ newer = None ,
296
+ timeStamp = "LastUpdate" ,
297
+ orderAttribute = None ,
298
+ limit = None ,
299
+ offset = None ,
241
300
):
242
301
if not condDict :
243
302
condDict = {}
244
- return cls .transformationDB .getTransformationFiles (
303
+ return self .transformationDB .getTransformationFiles (
245
304
condDict = condDict ,
246
305
older = older ,
247
306
newer = newer ,
@@ -286,32 +345,39 @@ def export_getTransformationTasks(
286
345
287
346
types_setTaskStatus = [[int , str ], [list , int ], str ]
288
347
289
- @classmethod
290
- def export_setTaskStatus (cls , transName , taskID , status ):
291
- return cls .transformationDB .setTaskStatus (transName , taskID , status )
348
+ def export_setTaskStatus (self , transName , taskID , status ):
349
+ if not (result := self .checkPermissions (transName ))["OK" ]:
350
+ return result
351
+ return self .transformationDB .setTaskStatus (transName , taskID , status )
292
352
293
353
types_setTaskStatusAndWmsID = [[int , str ], int , str , str ]
294
354
295
- @classmethod
296
- def export_setTaskStatusAndWmsID (cls , transName , taskID , status , taskWmsID ):
297
- return cls .transformationDB .setTaskStatusAndWmsID (transName , taskID , status , taskWmsID )
355
+ def export_setTaskStatusAndWmsID (self , transName , taskID , status , taskWmsID ):
356
+ if not (result := self .checkPermissions (transName ))["OK" ]:
357
+ return result
358
+ return self .transformationDB .setTaskStatusAndWmsID (transName , taskID , status , taskWmsID )
298
359
299
360
types_getTransformationTaskStats = [[int , str ]]
300
361
301
- @classmethod
302
- def export_getTransformationTaskStats (cls , transName ):
303
- return cls .transformationDB .getTransformationTaskStats (transName )
362
+ def export_getTransformationTaskStats (self , transName ):
363
+ if not (result := self .checkPermissions (transName ))["OK" ]:
364
+ return result
365
+ return self .transformationDB .getTransformationTaskStats (transName )
304
366
305
367
types_deleteTasks = [[int , str ], int , int ]
306
368
307
369
def export_deleteTasks (self , transName , taskMin , taskMax ):
370
+ if not (result := self .checkPermissions (transName ))["OK" ]:
371
+ return result
308
372
credDict = self .getRemoteCredentials ()
309
373
author = credDict .get ("username" )
310
374
return self .transformationDB .deleteTasks (transName , taskMin , taskMax , author = author )
311
375
312
376
types_extendTransformation = [[int , str ], int ]
313
377
314
378
def export_extendTransformation (self , transName , nTasks ):
379
+ if not (result := self .checkPermissions (transName ))["OK" ]:
380
+ return result
315
381
credDict = self .getRemoteCredentials ()
316
382
author = credDict .get ("username" )
317
383
return self .transformationDB .extendTransformation (transName , nTasks , author = author )
@@ -320,6 +386,8 @@ def export_extendTransformation(self, transName, nTasks):
320
386
321
387
def export_getTasksToSubmit (self , transName , numTasks , site = "" ):
322
388
"""Get information necessary for submission for a given number of tasks for a given transformation"""
389
+ if not (result := self .checkPermissions (transName ))["OK" ]:
390
+ return result
323
391
res = self .transformationDB .getTransformation (transName )
324
392
if not res ["OK" ]:
325
393
return res
@@ -349,20 +417,26 @@ def export_getTasksToSubmit(self, transName, numTasks, site=""):
349
417
types_createTransformationMetaQuery = [[int , str ], dict , str ]
350
418
351
419
def export_createTransformationMetaQuery (self , transName , queryDict , queryType ):
420
+ if not (result := self .checkPermissions (transName ))["OK" ]:
421
+ return result
352
422
credDict = self .getRemoteCredentials ()
353
423
author = credDict .get ("username" )
354
424
return self .transformationDB .createTransformationMetaQuery (transName , queryDict , queryType , author = author )
355
425
356
426
types_deleteTransformationMetaQuery = [[int , str ], str ]
357
427
358
428
def export_deleteTransformationMetaQuery (self , transName , queryType ):
429
+ if not (result := self .checkPermissions (transName ))["OK" ]:
430
+ return result
359
431
credDict = self .getRemoteCredentials ()
360
432
author = credDict .get ("username" )
361
433
return self .transformationDB .deleteTransformationMetaQuery (transName , queryType , author = author )
362
434
363
435
types_getTransformationMetaQuery = [[int , str ], str ]
364
436
365
437
def export_getTransformationMetaQuery (self , transName , queryType ):
438
+ if not (result := self .checkPermissions (transName ))["OK" ]:
439
+ return result
366
440
return self .transformationDB .getTransformationMetaQuery (transName , queryType )
367
441
368
442
####################################################################
@@ -373,6 +447,8 @@ def export_getTransformationMetaQuery(self, transName, queryType):
373
447
types_getTransformationLogging = [[int , str ]]
374
448
375
449
def export_getTransformationLogging (self , transName ):
450
+ if not (result := self .checkPermissions (transName ))["OK" ]:
451
+ return result
376
452
return self .transformationDB .getTransformationLogging (transName )
377
453
378
454
####################################################################
@@ -383,6 +459,8 @@ def export_getTransformationLogging(self, transName):
383
459
types_getAdditionalParameters = [[int , str ]]
384
460
385
461
def export_getAdditionalParameters (self , transName ):
462
+ if not (result := self .checkPermissions (transName ))["OK" ]:
463
+ return result
386
464
return self .transformationDB .getAdditionalParameters (transName )
387
465
388
466
####################################################################
0 commit comments