rucio 32.8.6__py3-none-any.whl

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.

Potentially problematic release.


This version of rucio might be problematic. Click here for more details.

Files changed (481) hide show
  1. rucio/__init__.py +18 -0
  2. rucio/alembicrevision.py +16 -0
  3. rucio/api/__init__.py +14 -0
  4. rucio/api/account.py +266 -0
  5. rucio/api/account_limit.py +287 -0
  6. rucio/api/authentication.py +302 -0
  7. rucio/api/config.py +218 -0
  8. rucio/api/credential.py +60 -0
  9. rucio/api/did.py +726 -0
  10. rucio/api/dirac.py +71 -0
  11. rucio/api/exporter.py +60 -0
  12. rucio/api/heartbeat.py +62 -0
  13. rucio/api/identity.py +160 -0
  14. rucio/api/importer.py +46 -0
  15. rucio/api/lifetime_exception.py +95 -0
  16. rucio/api/lock.py +131 -0
  17. rucio/api/meta.py +85 -0
  18. rucio/api/permission.py +72 -0
  19. rucio/api/quarantined_replica.py +69 -0
  20. rucio/api/replica.py +528 -0
  21. rucio/api/request.py +220 -0
  22. rucio/api/rse.py +601 -0
  23. rucio/api/rule.py +335 -0
  24. rucio/api/scope.py +89 -0
  25. rucio/api/subscription.py +255 -0
  26. rucio/api/temporary_did.py +49 -0
  27. rucio/api/vo.py +112 -0
  28. rucio/client/__init__.py +16 -0
  29. rucio/client/accountclient.py +413 -0
  30. rucio/client/accountlimitclient.py +155 -0
  31. rucio/client/baseclient.py +929 -0
  32. rucio/client/client.py +77 -0
  33. rucio/client/configclient.py +113 -0
  34. rucio/client/credentialclient.py +54 -0
  35. rucio/client/didclient.py +691 -0
  36. rucio/client/diracclient.py +48 -0
  37. rucio/client/downloadclient.py +1674 -0
  38. rucio/client/exportclient.py +44 -0
  39. rucio/client/fileclient.py +51 -0
  40. rucio/client/importclient.py +42 -0
  41. rucio/client/lifetimeclient.py +74 -0
  42. rucio/client/lockclient.py +99 -0
  43. rucio/client/metaclient.py +137 -0
  44. rucio/client/pingclient.py +45 -0
  45. rucio/client/replicaclient.py +444 -0
  46. rucio/client/requestclient.py +109 -0
  47. rucio/client/rseclient.py +664 -0
  48. rucio/client/ruleclient.py +287 -0
  49. rucio/client/scopeclient.py +88 -0
  50. rucio/client/subscriptionclient.py +161 -0
  51. rucio/client/touchclient.py +78 -0
  52. rucio/client/uploadclient.py +871 -0
  53. rucio/common/__init__.py +14 -0
  54. rucio/common/cache.py +74 -0
  55. rucio/common/config.py +796 -0
  56. rucio/common/constants.py +92 -0
  57. rucio/common/constraints.py +18 -0
  58. rucio/common/didtype.py +187 -0
  59. rucio/common/dumper/__init__.py +306 -0
  60. rucio/common/dumper/consistency.py +449 -0
  61. rucio/common/dumper/data_models.py +325 -0
  62. rucio/common/dumper/path_parsing.py +65 -0
  63. rucio/common/exception.py +1092 -0
  64. rucio/common/extra.py +37 -0
  65. rucio/common/logging.py +404 -0
  66. rucio/common/pcache.py +1387 -0
  67. rucio/common/policy.py +84 -0
  68. rucio/common/schema/__init__.py +143 -0
  69. rucio/common/schema/atlas.py +411 -0
  70. rucio/common/schema/belleii.py +406 -0
  71. rucio/common/schema/cms.py +478 -0
  72. rucio/common/schema/domatpc.py +399 -0
  73. rucio/common/schema/escape.py +424 -0
  74. rucio/common/schema/generic.py +431 -0
  75. rucio/common/schema/generic_multi_vo.py +410 -0
  76. rucio/common/schema/icecube.py +404 -0
  77. rucio/common/schema/lsst.py +423 -0
  78. rucio/common/stomp_utils.py +160 -0
  79. rucio/common/stopwatch.py +56 -0
  80. rucio/common/test_rucio_server.py +148 -0
  81. rucio/common/types.py +158 -0
  82. rucio/common/utils.py +1946 -0
  83. rucio/core/__init__.py +14 -0
  84. rucio/core/account.py +426 -0
  85. rucio/core/account_counter.py +171 -0
  86. rucio/core/account_limit.py +357 -0
  87. rucio/core/authentication.py +563 -0
  88. rucio/core/config.py +386 -0
  89. rucio/core/credential.py +218 -0
  90. rucio/core/did.py +3102 -0
  91. rucio/core/did_meta_plugins/__init__.py +250 -0
  92. rucio/core/did_meta_plugins/did_column_meta.py +326 -0
  93. rucio/core/did_meta_plugins/did_meta_plugin_interface.py +116 -0
  94. rucio/core/did_meta_plugins/filter_engine.py +573 -0
  95. rucio/core/did_meta_plugins/json_meta.py +215 -0
  96. rucio/core/did_meta_plugins/mongo_meta.py +199 -0
  97. rucio/core/did_meta_plugins/postgres_meta.py +317 -0
  98. rucio/core/dirac.py +208 -0
  99. rucio/core/distance.py +164 -0
  100. rucio/core/exporter.py +59 -0
  101. rucio/core/heartbeat.py +263 -0
  102. rucio/core/identity.py +290 -0
  103. rucio/core/importer.py +248 -0
  104. rucio/core/lifetime_exception.py +377 -0
  105. rucio/core/lock.py +474 -0
  106. rucio/core/message.py +241 -0
  107. rucio/core/meta.py +190 -0
  108. rucio/core/monitor.py +441 -0
  109. rucio/core/naming_convention.py +154 -0
  110. rucio/core/nongrid_trace.py +124 -0
  111. rucio/core/oidc.py +1339 -0
  112. rucio/core/permission/__init__.py +107 -0
  113. rucio/core/permission/atlas.py +1333 -0
  114. rucio/core/permission/belleii.py +1076 -0
  115. rucio/core/permission/cms.py +1166 -0
  116. rucio/core/permission/escape.py +1076 -0
  117. rucio/core/permission/generic.py +1128 -0
  118. rucio/core/permission/generic_multi_vo.py +1148 -0
  119. rucio/core/quarantined_replica.py +190 -0
  120. rucio/core/replica.py +3627 -0
  121. rucio/core/replica_sorter.py +368 -0
  122. rucio/core/request.py +2241 -0
  123. rucio/core/rse.py +1835 -0
  124. rucio/core/rse_counter.py +155 -0
  125. rucio/core/rse_expression_parser.py +460 -0
  126. rucio/core/rse_selector.py +277 -0
  127. rucio/core/rule.py +3419 -0
  128. rucio/core/rule_grouping.py +1473 -0
  129. rucio/core/scope.py +152 -0
  130. rucio/core/subscription.py +316 -0
  131. rucio/core/temporary_did.py +188 -0
  132. rucio/core/topology.py +448 -0
  133. rucio/core/trace.py +361 -0
  134. rucio/core/transfer.py +1233 -0
  135. rucio/core/vo.py +151 -0
  136. rucio/core/volatile_replica.py +123 -0
  137. rucio/daemons/__init__.py +14 -0
  138. rucio/daemons/abacus/__init__.py +14 -0
  139. rucio/daemons/abacus/account.py +106 -0
  140. rucio/daemons/abacus/collection_replica.py +113 -0
  141. rucio/daemons/abacus/rse.py +107 -0
  142. rucio/daemons/atropos/__init__.py +14 -0
  143. rucio/daemons/atropos/atropos.py +243 -0
  144. rucio/daemons/auditor/__init__.py +261 -0
  145. rucio/daemons/auditor/hdfs.py +86 -0
  146. rucio/daemons/auditor/srmdumps.py +284 -0
  147. rucio/daemons/automatix/__init__.py +14 -0
  148. rucio/daemons/automatix/automatix.py +281 -0
  149. rucio/daemons/badreplicas/__init__.py +14 -0
  150. rucio/daemons/badreplicas/minos.py +311 -0
  151. rucio/daemons/badreplicas/minos_temporary_expiration.py +173 -0
  152. rucio/daemons/badreplicas/necromancer.py +200 -0
  153. rucio/daemons/bb8/__init__.py +14 -0
  154. rucio/daemons/bb8/bb8.py +356 -0
  155. rucio/daemons/bb8/common.py +762 -0
  156. rucio/daemons/bb8/nuclei_background_rebalance.py +147 -0
  157. rucio/daemons/bb8/t2_background_rebalance.py +146 -0
  158. rucio/daemons/c3po/__init__.py +14 -0
  159. rucio/daemons/c3po/algorithms/__init__.py +14 -0
  160. rucio/daemons/c3po/algorithms/simple.py +131 -0
  161. rucio/daemons/c3po/algorithms/t2_free_space.py +125 -0
  162. rucio/daemons/c3po/algorithms/t2_free_space_only_pop.py +127 -0
  163. rucio/daemons/c3po/algorithms/t2_free_space_only_pop_with_network.py +279 -0
  164. rucio/daemons/c3po/c3po.py +342 -0
  165. rucio/daemons/c3po/collectors/__init__.py +14 -0
  166. rucio/daemons/c3po/collectors/agis.py +108 -0
  167. rucio/daemons/c3po/collectors/free_space.py +62 -0
  168. rucio/daemons/c3po/collectors/jedi_did.py +48 -0
  169. rucio/daemons/c3po/collectors/mock_did.py +46 -0
  170. rucio/daemons/c3po/collectors/network_metrics.py +63 -0
  171. rucio/daemons/c3po/collectors/workload.py +110 -0
  172. rucio/daemons/c3po/utils/__init__.py +14 -0
  173. rucio/daemons/c3po/utils/dataset_cache.py +40 -0
  174. rucio/daemons/c3po/utils/expiring_dataset_cache.py +45 -0
  175. rucio/daemons/c3po/utils/expiring_list.py +63 -0
  176. rucio/daemons/c3po/utils/popularity.py +82 -0
  177. rucio/daemons/c3po/utils/timeseries.py +76 -0
  178. rucio/daemons/cache/__init__.py +14 -0
  179. rucio/daemons/cache/consumer.py +191 -0
  180. rucio/daemons/common.py +391 -0
  181. rucio/daemons/conveyor/__init__.py +14 -0
  182. rucio/daemons/conveyor/common.py +530 -0
  183. rucio/daemons/conveyor/finisher.py +492 -0
  184. rucio/daemons/conveyor/poller.py +372 -0
  185. rucio/daemons/conveyor/preparer.py +198 -0
  186. rucio/daemons/conveyor/receiver.py +206 -0
  187. rucio/daemons/conveyor/stager.py +127 -0
  188. rucio/daemons/conveyor/submitter.py +379 -0
  189. rucio/daemons/conveyor/throttler.py +468 -0
  190. rucio/daemons/follower/__init__.py +14 -0
  191. rucio/daemons/follower/follower.py +97 -0
  192. rucio/daemons/hermes/__init__.py +14 -0
  193. rucio/daemons/hermes/hermes.py +738 -0
  194. rucio/daemons/judge/__init__.py +14 -0
  195. rucio/daemons/judge/cleaner.py +149 -0
  196. rucio/daemons/judge/evaluator.py +172 -0
  197. rucio/daemons/judge/injector.py +154 -0
  198. rucio/daemons/judge/repairer.py +144 -0
  199. rucio/daemons/oauthmanager/__init__.py +14 -0
  200. rucio/daemons/oauthmanager/oauthmanager.py +199 -0
  201. rucio/daemons/reaper/__init__.py +14 -0
  202. rucio/daemons/reaper/dark_reaper.py +272 -0
  203. rucio/daemons/reaper/light_reaper.py +255 -0
  204. rucio/daemons/reaper/reaper.py +701 -0
  205. rucio/daemons/replicarecoverer/__init__.py +14 -0
  206. rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +487 -0
  207. rucio/daemons/storage/__init__.py +14 -0
  208. rucio/daemons/storage/consistency/__init__.py +14 -0
  209. rucio/daemons/storage/consistency/actions.py +753 -0
  210. rucio/daemons/tracer/__init__.py +14 -0
  211. rucio/daemons/tracer/kronos.py +513 -0
  212. rucio/daemons/transmogrifier/__init__.py +14 -0
  213. rucio/daemons/transmogrifier/transmogrifier.py +753 -0
  214. rucio/daemons/undertaker/__init__.py +14 -0
  215. rucio/daemons/undertaker/undertaker.py +137 -0
  216. rucio/db/__init__.py +14 -0
  217. rucio/db/sqla/__init__.py +38 -0
  218. rucio/db/sqla/constants.py +192 -0
  219. rucio/db/sqla/migrate_repo/__init__.py +14 -0
  220. rucio/db/sqla/migrate_repo/env.py +111 -0
  221. rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +71 -0
  222. rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +50 -0
  223. rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +61 -0
  224. rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +46 -0
  225. rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +93 -0
  226. rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +78 -0
  227. rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +46 -0
  228. rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +53 -0
  229. rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +69 -0
  230. rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +42 -0
  231. rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +46 -0
  232. rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +61 -0
  233. rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +42 -0
  234. rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +141 -0
  235. rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +75 -0
  236. rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +75 -0
  237. rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +46 -0
  238. rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +51 -0
  239. rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +135 -0
  240. rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +65 -0
  241. rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +42 -0
  242. rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +66 -0
  243. rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +54 -0
  244. rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +43 -0
  245. rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +46 -0
  246. rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +47 -0
  247. rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +54 -0
  248. rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +39 -0
  249. rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +48 -0
  250. rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +47 -0
  251. rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +48 -0
  252. rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +59 -0
  253. rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +47 -0
  254. rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +72 -0
  255. rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +46 -0
  256. rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +45 -0
  257. rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +48 -0
  258. rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +48 -0
  259. rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +42 -0
  260. rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +69 -0
  261. rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +46 -0
  262. rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +78 -0
  263. rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +62 -0
  264. rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +74 -0
  265. rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +44 -0
  266. rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +67 -0
  267. rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +134 -0
  268. rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +58 -0
  269. rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +79 -0
  270. rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +61 -0
  271. rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +45 -0
  272. rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +46 -0
  273. rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +65 -0
  274. rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +42 -0
  275. rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +46 -0
  276. rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +46 -0
  277. rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +80 -0
  278. rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +43 -0
  279. rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +61 -0
  280. rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +47 -0
  281. rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +46 -0
  282. rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +52 -0
  283. rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +42 -0
  284. rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +65 -0
  285. rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +46 -0
  286. rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +47 -0
  287. rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +45 -0
  288. rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +46 -0
  289. rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +48 -0
  290. rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +50 -0
  291. rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +59 -0
  292. rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +48 -0
  293. rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +108 -0
  294. rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +57 -0
  295. rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +51 -0
  296. rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +50 -0
  297. rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +46 -0
  298. rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +42 -0
  299. rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +93 -0
  300. rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +73 -0
  301. rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +52 -0
  302. rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +45 -0
  303. rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +46 -0
  304. rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +54 -0
  305. rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +48 -0
  306. rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +70 -0
  307. rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +48 -0
  308. rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +95 -0
  309. rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +55 -0
  310. rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +74 -0
  311. rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +78 -0
  312. rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +49 -0
  313. rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +124 -0
  314. rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +60 -0
  315. rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +53 -0
  316. rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +56 -0
  317. rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +67 -0
  318. rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +50 -0
  319. rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +46 -0
  320. rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +92 -0
  321. rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +42 -0
  322. rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +46 -0
  323. rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +147 -0
  324. rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +78 -0
  325. rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +53 -0
  326. rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +74 -0
  327. rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +56 -0
  328. rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +46 -0
  329. rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +68 -0
  330. rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +48 -0
  331. rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +149 -0
  332. rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +106 -0
  333. rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +47 -0
  334. rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +45 -0
  335. rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +105 -0
  336. rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +52 -0
  337. rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +106 -0
  338. rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +30 -0
  339. rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +75 -0
  340. rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +49 -0
  341. rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +45 -0
  342. rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +38 -0
  343. rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +44 -0
  344. rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +46 -0
  345. rucio/db/sqla/models.py +1834 -0
  346. rucio/db/sqla/sautils.py +48 -0
  347. rucio/db/sqla/session.py +470 -0
  348. rucio/db/sqla/types.py +207 -0
  349. rucio/db/sqla/util.py +521 -0
  350. rucio/rse/__init__.py +97 -0
  351. rucio/rse/protocols/__init__.py +14 -0
  352. rucio/rse/protocols/cache.py +123 -0
  353. rucio/rse/protocols/dummy.py +112 -0
  354. rucio/rse/protocols/gfal.py +701 -0
  355. rucio/rse/protocols/globus.py +243 -0
  356. rucio/rse/protocols/gsiftp.py +93 -0
  357. rucio/rse/protocols/http_cache.py +83 -0
  358. rucio/rse/protocols/mock.py +124 -0
  359. rucio/rse/protocols/ngarc.py +210 -0
  360. rucio/rse/protocols/posix.py +251 -0
  361. rucio/rse/protocols/protocol.py +530 -0
  362. rucio/rse/protocols/rclone.py +365 -0
  363. rucio/rse/protocols/rfio.py +137 -0
  364. rucio/rse/protocols/srm.py +339 -0
  365. rucio/rse/protocols/ssh.py +414 -0
  366. rucio/rse/protocols/storm.py +207 -0
  367. rucio/rse/protocols/webdav.py +547 -0
  368. rucio/rse/protocols/xrootd.py +295 -0
  369. rucio/rse/rsemanager.py +752 -0
  370. rucio/tests/__init__.py +14 -0
  371. rucio/tests/common.py +244 -0
  372. rucio/tests/common_server.py +132 -0
  373. rucio/transfertool/__init__.py +14 -0
  374. rucio/transfertool/fts3.py +1484 -0
  375. rucio/transfertool/globus.py +200 -0
  376. rucio/transfertool/globus_library.py +182 -0
  377. rucio/transfertool/mock.py +81 -0
  378. rucio/transfertool/transfertool.py +212 -0
  379. rucio/vcsversion.py +11 -0
  380. rucio/version.py +46 -0
  381. rucio/web/__init__.py +14 -0
  382. rucio/web/rest/__init__.py +14 -0
  383. rucio/web/rest/flaskapi/__init__.py +14 -0
  384. rucio/web/rest/flaskapi/authenticated_bp.py +28 -0
  385. rucio/web/rest/flaskapi/v1/__init__.py +14 -0
  386. rucio/web/rest/flaskapi/v1/accountlimits.py +234 -0
  387. rucio/web/rest/flaskapi/v1/accounts.py +1088 -0
  388. rucio/web/rest/flaskapi/v1/archives.py +100 -0
  389. rucio/web/rest/flaskapi/v1/auth.py +1642 -0
  390. rucio/web/rest/flaskapi/v1/common.py +385 -0
  391. rucio/web/rest/flaskapi/v1/config.py +305 -0
  392. rucio/web/rest/flaskapi/v1/credentials.py +213 -0
  393. rucio/web/rest/flaskapi/v1/dids.py +2204 -0
  394. rucio/web/rest/flaskapi/v1/dirac.py +116 -0
  395. rucio/web/rest/flaskapi/v1/export.py +77 -0
  396. rucio/web/rest/flaskapi/v1/heartbeats.py +129 -0
  397. rucio/web/rest/flaskapi/v1/identities.py +263 -0
  398. rucio/web/rest/flaskapi/v1/import.py +133 -0
  399. rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +315 -0
  400. rucio/web/rest/flaskapi/v1/locks.py +360 -0
  401. rucio/web/rest/flaskapi/v1/main.py +83 -0
  402. rucio/web/rest/flaskapi/v1/meta.py +226 -0
  403. rucio/web/rest/flaskapi/v1/metrics.py +37 -0
  404. rucio/web/rest/flaskapi/v1/nongrid_traces.py +97 -0
  405. rucio/web/rest/flaskapi/v1/ping.py +89 -0
  406. rucio/web/rest/flaskapi/v1/redirect.py +366 -0
  407. rucio/web/rest/flaskapi/v1/replicas.py +1866 -0
  408. rucio/web/rest/flaskapi/v1/requests.py +841 -0
  409. rucio/web/rest/flaskapi/v1/rses.py +2204 -0
  410. rucio/web/rest/flaskapi/v1/rules.py +824 -0
  411. rucio/web/rest/flaskapi/v1/scopes.py +161 -0
  412. rucio/web/rest/flaskapi/v1/subscriptions.py +646 -0
  413. rucio/web/rest/flaskapi/v1/templates/auth_crash.html +80 -0
  414. rucio/web/rest/flaskapi/v1/templates/auth_granted.html +82 -0
  415. rucio/web/rest/flaskapi/v1/tmp_dids.py +115 -0
  416. rucio/web/rest/flaskapi/v1/traces.py +100 -0
  417. rucio/web/rest/flaskapi/v1/vos.py +280 -0
  418. rucio/web/rest/main.py +19 -0
  419. rucio/web/rest/metrics.py +28 -0
  420. rucio-32.8.6.data/data/rucio/etc/alembic.ini.template +71 -0
  421. rucio-32.8.6.data/data/rucio/etc/alembic_offline.ini.template +74 -0
  422. rucio-32.8.6.data/data/rucio/etc/globus-config.yml.template +5 -0
  423. rucio-32.8.6.data/data/rucio/etc/ldap.cfg.template +30 -0
  424. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_approval_request.tmpl +38 -0
  425. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +4 -0
  426. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_approved_user.tmpl +17 -0
  427. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +6 -0
  428. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_denied_user.tmpl +17 -0
  429. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +19 -0
  430. rucio-32.8.6.data/data/rucio/etc/rse-accounts.cfg.template +25 -0
  431. rucio-32.8.6.data/data/rucio/etc/rucio.cfg.atlas.client.template +42 -0
  432. rucio-32.8.6.data/data/rucio/etc/rucio.cfg.template +257 -0
  433. rucio-32.8.6.data/data/rucio/etc/rucio_multi_vo.cfg.template +234 -0
  434. rucio-32.8.6.data/data/rucio/requirements.txt +55 -0
  435. rucio-32.8.6.data/data/rucio/tools/bootstrap.py +34 -0
  436. rucio-32.8.6.data/data/rucio/tools/merge_rucio_configs.py +147 -0
  437. rucio-32.8.6.data/data/rucio/tools/reset_database.py +40 -0
  438. rucio-32.8.6.data/scripts/rucio +2540 -0
  439. rucio-32.8.6.data/scripts/rucio-abacus-account +75 -0
  440. rucio-32.8.6.data/scripts/rucio-abacus-collection-replica +47 -0
  441. rucio-32.8.6.data/scripts/rucio-abacus-rse +79 -0
  442. rucio-32.8.6.data/scripts/rucio-admin +2434 -0
  443. rucio-32.8.6.data/scripts/rucio-atropos +61 -0
  444. rucio-32.8.6.data/scripts/rucio-auditor +199 -0
  445. rucio-32.8.6.data/scripts/rucio-automatix +51 -0
  446. rucio-32.8.6.data/scripts/rucio-bb8 +58 -0
  447. rucio-32.8.6.data/scripts/rucio-c3po +86 -0
  448. rucio-32.8.6.data/scripts/rucio-cache-client +135 -0
  449. rucio-32.8.6.data/scripts/rucio-cache-consumer +43 -0
  450. rucio-32.8.6.data/scripts/rucio-conveyor-finisher +59 -0
  451. rucio-32.8.6.data/scripts/rucio-conveyor-poller +67 -0
  452. rucio-32.8.6.data/scripts/rucio-conveyor-preparer +38 -0
  453. rucio-32.8.6.data/scripts/rucio-conveyor-receiver +44 -0
  454. rucio-32.8.6.data/scripts/rucio-conveyor-stager +77 -0
  455. rucio-32.8.6.data/scripts/rucio-conveyor-submitter +140 -0
  456. rucio-32.8.6.data/scripts/rucio-conveyor-throttler +105 -0
  457. rucio-32.8.6.data/scripts/rucio-dark-reaper +54 -0
  458. rucio-32.8.6.data/scripts/rucio-dumper +159 -0
  459. rucio-32.8.6.data/scripts/rucio-follower +45 -0
  460. rucio-32.8.6.data/scripts/rucio-hermes +55 -0
  461. rucio-32.8.6.data/scripts/rucio-judge-cleaner +90 -0
  462. rucio-32.8.6.data/scripts/rucio-judge-evaluator +138 -0
  463. rucio-32.8.6.data/scripts/rucio-judge-injector +45 -0
  464. rucio-32.8.6.data/scripts/rucio-judge-repairer +45 -0
  465. rucio-32.8.6.data/scripts/rucio-kronos +45 -0
  466. rucio-32.8.6.data/scripts/rucio-light-reaper +53 -0
  467. rucio-32.8.6.data/scripts/rucio-minos +54 -0
  468. rucio-32.8.6.data/scripts/rucio-minos-temporary-expiration +51 -0
  469. rucio-32.8.6.data/scripts/rucio-necromancer +121 -0
  470. rucio-32.8.6.data/scripts/rucio-oauth-manager +64 -0
  471. rucio-32.8.6.data/scripts/rucio-reaper +84 -0
  472. rucio-32.8.6.data/scripts/rucio-replica-recoverer +249 -0
  473. rucio-32.8.6.data/scripts/rucio-storage-consistency-actions +75 -0
  474. rucio-32.8.6.data/scripts/rucio-transmogrifier +78 -0
  475. rucio-32.8.6.data/scripts/rucio-undertaker +77 -0
  476. rucio-32.8.6.dist-info/METADATA +83 -0
  477. rucio-32.8.6.dist-info/RECORD +481 -0
  478. rucio-32.8.6.dist-info/WHEEL +5 -0
  479. rucio-32.8.6.dist-info/licenses/AUTHORS.rst +94 -0
  480. rucio-32.8.6.dist-info/licenses/LICENSE +201 -0
  481. rucio-32.8.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1333 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from typing import TYPE_CHECKING
17
+
18
+ import rucio.core.did
19
+ import rucio.core.scope
20
+ from rucio.core.account import list_account_attributes, has_account_attribute
21
+ from rucio.core.identity import exist_identity_account
22
+ from rucio.core.rse import list_rse_attributes
23
+ from rucio.core.rse_expression_parser import parse_expression
24
+ from rucio.core.rule import get_rule
25
+ from rucio.db.sqla.constants import IdentityType, BadPFNStatus
26
+
27
+ if TYPE_CHECKING:
28
+ from typing import Optional
29
+ from sqlalchemy.orm import Session
30
+ from rucio.common.types import InternalAccount
31
+
32
+
33
+ def has_permission(issuer, action, kwargs, *, session: "Optional[Session]" = None):
34
+ """
35
+ Checks if an account has the specified permission to
36
+ execute an action with parameters.
37
+
38
+ :param issuer: Account identifier which issues the command..
39
+ :param action: The action(API call) called by the account.
40
+ :param kwargs: List of arguments for the action.
41
+ :param session: The DB session to use
42
+ :returns: True if account is allowed, otherwise False
43
+ """
44
+ perm = {'add_account': perm_add_account,
45
+ 'del_account': perm_del_account,
46
+ 'update_account': perm_update_account,
47
+ 'add_rule': perm_add_rule,
48
+ 'add_subscription': perm_add_subscription,
49
+ 'add_scope': perm_add_scope,
50
+ 'add_rse': perm_add_rse,
51
+ 'update_rse': perm_update_rse,
52
+ 'add_protocol': perm_add_protocol,
53
+ 'del_protocol': perm_del_protocol,
54
+ 'update_protocol': perm_update_protocol,
55
+ 'add_qos_policy': perm_add_qos_policy,
56
+ 'delete_qos_policy': perm_delete_qos_policy,
57
+ 'declare_bad_file_replicas': perm_declare_bad_file_replicas,
58
+ 'declare_suspicious_file_replicas': perm_declare_suspicious_file_replicas,
59
+ 'add_replicas': perm_add_replicas,
60
+ 'delete_replicas': perm_delete_replicas,
61
+ 'skip_availability_check': perm_skip_availability_check,
62
+ 'update_replicas_states': perm_update_replicas_states,
63
+ 'add_rse_attribute': perm_add_rse_attribute,
64
+ 'del_rse_attribute': perm_del_rse_attribute,
65
+ 'del_rse': perm_del_rse,
66
+ 'del_rule': perm_del_rule,
67
+ 'update_rule': perm_update_rule,
68
+ 'approve_rule': perm_approve_rule,
69
+ 'update_subscription': perm_update_subscription,
70
+ 'reduce_rule': perm_reduce_rule,
71
+ 'move_rule': perm_move_rule,
72
+ 'get_auth_token_user_pass': perm_get_auth_token_user_pass,
73
+ 'get_auth_token_gss': perm_get_auth_token_gss,
74
+ 'get_auth_token_x509': perm_get_auth_token_x509,
75
+ 'get_auth_token_saml': perm_get_auth_token_saml,
76
+ 'add_account_identity': perm_add_account_identity,
77
+ 'add_did': perm_add_did,
78
+ 'add_dids': perm_add_dids,
79
+ 'attach_dids': perm_attach_dids,
80
+ 'detach_dids': perm_detach_dids,
81
+ 'attach_dids_to_dids': perm_attach_dids_to_dids,
82
+ 'create_did_sample': perm_create_did_sample,
83
+ 'set_metadata': perm_set_metadata,
84
+ 'set_metadata_bulk': perm_set_metadata_bulk,
85
+ 'set_status': perm_set_status,
86
+ 'queue_requests': perm_queue_requests,
87
+ 'set_rse_usage': perm_set_rse_usage,
88
+ 'set_rse_limits': perm_set_rse_limits,
89
+ 'get_request_by_did': perm_get_request_by_did,
90
+ 'cancel_request': perm_cancel_request,
91
+ 'get_next': perm_get_next,
92
+ 'set_local_account_limit': perm_set_local_account_limit,
93
+ 'set_global_account_limit': perm_set_global_account_limit,
94
+ 'delete_local_account_limit': perm_delete_local_account_limit,
95
+ 'delete_global_account_limit': perm_delete_global_account_limit,
96
+ 'config_sections': perm_config,
97
+ 'config_add_section': perm_config,
98
+ 'config_has_section': perm_config,
99
+ 'config_options': perm_config,
100
+ 'config_has_option': perm_config,
101
+ 'config_get': perm_config,
102
+ 'config_items': perm_config,
103
+ 'config_set': perm_config,
104
+ 'config_remove_section': perm_config,
105
+ 'config_remove_option': perm_config,
106
+ 'get_local_account_usage': perm_get_local_account_usage,
107
+ 'get_global_account_usage': perm_get_global_account_usage,
108
+ 'add_attribute': perm_add_account_attribute,
109
+ 'del_attribute': perm_del_account_attribute,
110
+ 'list_heartbeats': perm_list_heartbeats,
111
+ 'send_heartbeats': perm_send_heartbeats,
112
+ 'resurrect': perm_resurrect,
113
+ 'update_lifetime_exceptions': perm_update_lifetime_exceptions,
114
+ 'get_auth_token_ssh': perm_get_auth_token_ssh,
115
+ 'get_signed_url': perm_get_signed_url,
116
+ 'add_bad_pfns': perm_add_bad_pfns,
117
+ 'del_account_identity': perm_del_account_identity,
118
+ 'del_identity': perm_del_identity,
119
+ 'remove_did_from_followed': perm_remove_did_from_followed,
120
+ 'remove_dids_from_followed': perm_remove_dids_from_followed,
121
+ 'add_vo': perm_add_vo,
122
+ 'list_vos': perm_list_vos,
123
+ 'recover_vo_root_identity': perm_recover_vo_root_identity,
124
+ 'update_vo': perm_update_vo,
125
+ 'access_rule_vo': perm_access_rule_vo,
126
+ 'export': perm_export}
127
+
128
+ return perm.get(action, perm_default)(issuer=issuer, kwargs=kwargs, session=session)
129
+
130
+
131
+ def _is_root(issuer):
132
+ return issuer.external == 'root' or issuer.external == 'ddmadmin'
133
+
134
+
135
+ def perm_default(issuer, kwargs, *, session: "Optional[Session]" = None):
136
+ """
137
+ Default permission.
138
+
139
+ :param issuer: Account identifier which issues the command.
140
+ :param kwargs: List of arguments for the action.
141
+ :param session: The DB session to use
142
+ :returns: True if account is allowed, otherwise False
143
+ """
144
+ return _is_root(issuer)
145
+
146
+
147
+ def perm_add_rse(issuer, kwargs, *, session: "Optional[Session]" = None):
148
+ """
149
+ Checks if an account can add a RSE.
150
+
151
+ :param issuer: Account identifier which issues the command.
152
+ :param kwargs: List of arguments for the action.
153
+ :param session: The DB session to use
154
+ :returns: True if account is allowed, otherwise False
155
+ """
156
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
157
+
158
+
159
+ def perm_update_rse(issuer, kwargs, *, session: "Optional[Session]" = None):
160
+ """
161
+ Checks if an account can update a RSE.
162
+
163
+ :param issuer: Account identifier which issues the command.
164
+ :param kwargs: List of arguments for the action.
165
+ :param session: The DB session to use
166
+ :returns: True if account is allowed, otherwise False
167
+ """
168
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
169
+
170
+
171
+ def perm_add_rule(issuer, kwargs, *, session: "Optional[Session]" = None):
172
+ """
173
+ Checks if an account can add a replication rule.
174
+
175
+ :param issuer: Account identifier which issues the command.
176
+ :param kwargs: List of arguments for the action.
177
+ :param session: The DB session to use
178
+ :returns: True if account is allowed, otherwise False
179
+ """
180
+ if kwargs['account'] == issuer and not kwargs['locked']:
181
+ return True
182
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
183
+ return True
184
+
185
+ return False
186
+
187
+
188
+ def perm_add_subscription(issuer, kwargs, *, session: "Optional[Session]" = None):
189
+ """
190
+ Checks if an account can add a subscription.
191
+
192
+ :param issuer: Account identifier which issues the command.
193
+ :param kwargs: List of arguments for the action.
194
+ :param session: The DB session to use
195
+ :returns: True if account is allowed, otherwise False
196
+ """
197
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
198
+ return True
199
+
200
+ return False
201
+
202
+
203
+ def perm_add_rse_attribute(issuer, kwargs, *, session: "Optional[Session]" = None):
204
+ """
205
+ Checks if an account can add a RSE attribute.
206
+
207
+ :param issuer: Account identifier which issues the command.
208
+ :param kwargs: List of arguments for the action.
209
+ :param session: The DB session to use
210
+ :returns: True if account is allowed, otherwise False
211
+ """
212
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
213
+ return True
214
+ if kwargs['key'] in ['rule_deleters', 'auto_approve_bytes', 'auto_approve_files', 'rule_approvers', 'default_account_limit_bytes', 'default_limit_files', 'block_manual_approve']:
215
+ # Check if user is a country admin
216
+ admin_in_country = []
217
+ for kv in list_account_attributes(account=issuer, session=session):
218
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
219
+ admin_in_country.append(kv['key'].partition('-')[2])
220
+ if admin_in_country:
221
+ if list_rse_attributes(rse_id=kwargs['rse_id'], session=session).get('country') in admin_in_country:
222
+ return True
223
+ return False
224
+
225
+
226
+ def perm_del_rse_attribute(issuer, kwargs, *, session: "Optional[Session]" = None):
227
+ """
228
+ Checks if an account can delete a RSE attribute.
229
+
230
+ :param issuer: Account identifier which issues the command.
231
+ :param kwargs: List of arguments for the action.
232
+ :param session: The DB session to use
233
+ :returns: True if account is allowed, otherwise False
234
+ """
235
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
236
+ return True
237
+ if kwargs['key'] in ['rule_deleters', 'auto_approve_bytes', 'auto_approve_files', 'rule_approvers', 'default_account_limit_bytes', 'default_limit_files', 'block_manual_approve']:
238
+ # Check if user is a country admin
239
+ admin_in_country = []
240
+ for kv in list_account_attributes(account=issuer, session=session):
241
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
242
+ admin_in_country.append(kv['key'].partition('-')[2])
243
+ if admin_in_country:
244
+ if list_rse_attributes(rse_id=kwargs['rse_id'], session=session).get('country') in admin_in_country:
245
+ return True
246
+ return False
247
+
248
+
249
+ def perm_del_rse(issuer, kwargs, *, session: "Optional[Session]" = None):
250
+ """
251
+ Checks if an account can delete a RSE.
252
+
253
+ :param issuer: Account identifier which issues the command.
254
+ :param kwargs: List of arguments for the action.
255
+ :param session: The DB session to use
256
+ :returns: True if account is allowed, otherwise False
257
+ """
258
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
259
+
260
+
261
+ def perm_add_account(issuer, kwargs, *, session: "Optional[Session]" = None):
262
+ """
263
+ Checks if an account can add an account.
264
+
265
+ :param issuer: Account identifier which issues the command.
266
+ :param kwargs: List of arguments for the action.
267
+ :param session: The DB session to use
268
+ :returns: True if account is allowed, otherwise False
269
+ """
270
+ return _is_root(issuer)
271
+
272
+
273
+ def perm_del_account(issuer, kwargs, *, session: "Optional[Session]" = None):
274
+ """
275
+ Checks if an account can del an account.
276
+
277
+ :param issuer: Account identifier which issues the command.
278
+ :param kwargs: List of arguments for the action.
279
+ :param session: The DB session to use
280
+ :returns: True if account is allowed, otherwise False
281
+ """
282
+ return _is_root(issuer)
283
+
284
+
285
+ def perm_update_account(issuer, kwargs, *, session: "Optional[Session]" = None):
286
+ """
287
+ Checks if an account can update an account.
288
+
289
+ :param issuer: Account identifier which issues the command.
290
+ :param kwargs: List of arguments for the action.
291
+ :param session: The DB session to use
292
+ :returns: True if account is allowed, otherwise False
293
+ """
294
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
295
+
296
+
297
+ def perm_add_scope(issuer, kwargs, *, session: "Optional[Session]" = None):
298
+ """
299
+ Checks if an account can add a scop to a account.
300
+
301
+ :param issuer: Account identifier which issues the command.
302
+ :param kwargs: List of arguments for the action.
303
+ :param session: The DB session to use
304
+ :returns: True if account is allowed, otherwise False
305
+ """
306
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
307
+
308
+
309
+ def perm_get_auth_token_user_pass(issuer, kwargs, *, session: "Optional[Session]" = None):
310
+ """
311
+ Checks if a user can request a token with user_pass for an account.
312
+
313
+ :param issuer: Account identifier which issues the command.
314
+ :param kwargs: List of arguments for the action.
315
+ :param session: The DB session to use
316
+ :returns: True if account is allowed, otherwise False
317
+ """
318
+ if exist_identity_account(identity=kwargs['username'], type_=IdentityType.USERPASS, account=kwargs['account'], session=session):
319
+ return True
320
+ return False
321
+
322
+
323
+ def perm_get_auth_token_gss(issuer, kwargs, *, session: "Optional[Session]" = None):
324
+ """
325
+ Checks if a user can request a token with user_pass for an account.
326
+
327
+ :param issuer: Account identifier which issues the command.
328
+ :param kwargs: List of arguments for the action.
329
+ :param session: The DB session to use
330
+ :returns: True if account is allowed, otherwise False
331
+ """
332
+ if exist_identity_account(identity=kwargs['gsscred'], type_=IdentityType.GSS, account=kwargs['account'], session=session):
333
+ return True
334
+ return False
335
+
336
+
337
+ def perm_get_auth_token_x509(issuer, kwargs, *, session: "Optional[Session]" = None):
338
+ """
339
+ Checks if a user can request a token with user_pass for an account.
340
+
341
+ :param issuer: Account identifier which issues the command.
342
+ :param kwargs: List of arguments for the action.
343
+ :param session: The DB session to use
344
+ :returns: True if account is allowed, otherwise False
345
+ """
346
+ if exist_identity_account(identity=kwargs['dn'], type_=IdentityType.X509, account=kwargs['account'], session=session):
347
+ return True
348
+ return False
349
+
350
+
351
+ def perm_get_auth_token_saml(issuer, kwargs, *, session: "Optional[Session]" = None):
352
+ """
353
+ Checks if a user can request a token with saml_nameid for an account.
354
+
355
+ :param issuer: Account identifier which issues the command.
356
+ :param kwargs: List of arguments for the action.
357
+ :param session: The DB session to use
358
+ :returns: True if account is allowed, otherwise False
359
+ """
360
+ if exist_identity_account(identity=kwargs['saml_nameid'], type_=IdentityType.SAML, account=kwargs['account'], session=session):
361
+ return True
362
+ return False
363
+
364
+
365
+ def perm_add_account_identity(issuer, kwargs, *, session: "Optional[Session]" = None):
366
+ """
367
+ Checks if an account can add an identity to an account.
368
+
369
+ :param issuer: Account identifier which issues the command.
370
+ :param kwargs: List of arguments for the action.
371
+ :param session: The DB session to use
372
+ :returns: True if account is allowed, otherwise False
373
+ """
374
+
375
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
376
+
377
+
378
+ def perm_del_account_identity(issuer, kwargs, *, session: "Optional[Session]" = None):
379
+ """
380
+ Checks if an account can delete an identity to an account.
381
+
382
+ :param issuer: Account identifier which issues the command.
383
+ :param kwargs: List of arguments for the action.
384
+ :param session: The DB session to use
385
+ :returns: True if account is allowed, otherwise False
386
+ """
387
+
388
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
389
+
390
+
391
+ def perm_del_identity(issuer, kwargs, *, session: "Optional[Session]" = None):
392
+ """
393
+ Checks if an account can delete an identity.
394
+
395
+ :param issuer: Account identifier which issues the command.
396
+ :param kwargs: List of arguments for the action.
397
+ :param session: The DB session to use
398
+ :returns: True if account is allowed, otherwise False
399
+ """
400
+
401
+ return _is_root(issuer) or issuer.external in kwargs.get('accounts')
402
+
403
+
404
+ def perm_add_did(issuer, kwargs, *, session: "Optional[Session]" = None):
405
+ """
406
+ Checks if an account can add an data identifier to a scope.
407
+
408
+ :param issuer: Account identifier which issues the command.
409
+ :param kwargs: List of arguments for the action.
410
+ :param session: The DB session to use
411
+ :returns: True if account is allowed, otherwise False
412
+ """
413
+ # Check the accounts of the issued rules
414
+ if not _is_root(issuer) and not has_account_attribute(account=issuer, key='admin', session=session):
415
+ for rule in kwargs.get('rules', []):
416
+ if rule['account'] != issuer:
417
+ return False
418
+
419
+ return _is_root(issuer)\
420
+ or has_account_attribute(account=issuer, key='admin', session=session)\
421
+ or rucio.core.scope.is_scope_owner(scope=kwargs['scope'], account=issuer, session=session)\
422
+ or kwargs['scope'].external == 'mock'
423
+
424
+
425
+ def perm_add_dids(issuer, kwargs, *, session: "Optional[Session]" = None):
426
+ """
427
+ Checks if an account can bulk add data identifiers.
428
+
429
+ :param issuer: Account identifier which issues the command.
430
+ :param kwargs: List of arguments for the action.
431
+ :param session: The DB session to use
432
+ :returns: True if account is allowed, otherwise False
433
+ """
434
+ # Check the accounts of the issued rules
435
+ if not _is_root(issuer) and not has_account_attribute(account=issuer, key='admin', session=session):
436
+ for did in kwargs['dids']:
437
+ for rule in did.get('rules', []):
438
+ if rule['account'] != issuer:
439
+ return False
440
+
441
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
442
+
443
+
444
+ def perm_attach_dids(issuer, kwargs, *, session: "Optional[Session]" = None):
445
+ """
446
+ Checks if an account can append an data identifier to the other data identifier.
447
+
448
+ :param issuer: Account identifier which issues the command.
449
+ :param kwargs: List of arguments for the action.
450
+ :param session: The DB session to use
451
+ :returns: True if account is allowed, otherwise False
452
+ """
453
+ return _is_root(issuer)\
454
+ or has_account_attribute(account=issuer, key='admin', session=session)\
455
+ or rucio.core.scope.is_scope_owner(scope=kwargs['scope'], account=issuer, session=session)\
456
+ or kwargs['scope'].external == 'mock'
457
+
458
+
459
+ def perm_attach_dids_to_dids(issuer, kwargs, *, session: "Optional[Session]" = None):
460
+ """
461
+ Checks if an account can append an data identifier to the other data identifier.
462
+
463
+ :param issuer: Account identifier which issues the command.
464
+ :param kwargs: List of arguments for the action.
465
+ :param session: The DB session to use
466
+ :returns: True if account is allowed, otherwise False
467
+ """
468
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
469
+ return True
470
+ attachments = kwargs['attachments']
471
+ scopes = [did['scope'] for did in attachments]
472
+ scopes = list(set(scopes))
473
+ for scope in scopes:
474
+ if not rucio.core.scope.is_scope_owner(scope, issuer, session=session):
475
+ return False
476
+ return True
477
+
478
+
479
+ def perm_create_did_sample(issuer, kwargs, *, session: "Optional[Session]" = None):
480
+ """
481
+ Checks if an account can create a sample of a data identifier collection.
482
+
483
+ :param issuer: Account identifier which issues the command.
484
+ :param kwargs: List of arguments for the action.
485
+ :param session: The DB session to use
486
+ :returns: True if account is allowed, otherwise False
487
+ """
488
+ return _is_root(issuer)\
489
+ or has_account_attribute(account=issuer, key='admin', session=session)\
490
+ or rucio.core.scope.is_scope_owner(scope=kwargs['scope'], account=issuer, session=session)\
491
+ or kwargs['scope'].external == 'mock'
492
+
493
+
494
+ def perm_del_rule(issuer, kwargs, *, session: "Optional[Session]" = None):
495
+ """
496
+ Checks if an issuer can delete a replication rule.
497
+
498
+ :param issuer: Account identifier which issues the command.
499
+ :param kwargs: List of arguments for the action.
500
+ :param session: The DB session to use
501
+ :returns: True if account is allowed to call the API call, otherwise False
502
+ """
503
+ if _is_root(issuer):
504
+ return True
505
+ if get_rule(rule_id=kwargs['rule_id'], session=session)['account'] == issuer:
506
+ return True
507
+
508
+ # Check if user is a country admin
509
+ admin_in_country = []
510
+ for kv in list_account_attributes(account=issuer, session=session):
511
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
512
+ admin_in_country.append(kv['key'].partition('-')[2])
513
+
514
+ rule = get_rule(rule_id=kwargs['rule_id'], session=session)
515
+ rses = parse_expression(rule['rse_expression'], filter_={'vo': issuer.vo}, session=session)
516
+ if admin_in_country:
517
+ for rse in rses:
518
+ if list_rse_attributes(rse_id=rse['id'], session=session).get('country') in admin_in_country:
519
+ return True
520
+
521
+ # DELETERS can approve the rule
522
+ for rse in rses:
523
+ rse_attr = list_rse_attributes(rse_id=rse['id'], session=session)
524
+ if rse_attr.get('rule_deleters'):
525
+ if issuer.external in rse_attr.get('rule_deleters').split(','):
526
+ return True
527
+
528
+ return False
529
+
530
+
531
+ def perm_update_rule(issuer, kwargs, *, session: "Optional[Session]" = None):
532
+ """
533
+ Checks if an issuer can update a replication rule.
534
+
535
+ :param issuer: Account identifier which issues the command.
536
+ :param kwargs: List of arguments for the action.
537
+ :param session: The DB session to use
538
+ :returns: True if account is allowed to call the API call, otherwise False
539
+ """
540
+ # Admin accounts can do everything
541
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
542
+ return True
543
+
544
+ admin_reserved = {'account', 'state', 'priority', 'child_rule_id', 'meta', 'boost_rule'}
545
+ if admin_reserved.intersection(kwargs['options'].keys()):
546
+ return False # Only priv accounts are allowed to change that
547
+
548
+ # Country admins are allowed to change the rest.
549
+ admin_in_country = []
550
+ for kv in list_account_attributes(account=issuer, session=session):
551
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
552
+ admin_in_country.append(kv['key'].partition('-')[2])
553
+
554
+ rule = get_rule(rule_id=kwargs['rule_id'], session=session)
555
+ rses = parse_expression(rule['rse_expression'], filter_={'vo': issuer.vo}, session=session)
556
+ if admin_in_country:
557
+ for rse in rses:
558
+ if list_rse_attributes(rse_id=rse['id'], session=session).get('country') in admin_in_country:
559
+ return True
560
+
561
+ # Only admin and country-admin are allowed to change locked state of rule
562
+ if 'locked' in kwargs['options']:
563
+ return False
564
+
565
+ # Owner can change the rest of a rule
566
+ if get_rule(kwargs['rule_id'], session=session)['account'] == issuer:
567
+ return True
568
+
569
+ return False
570
+
571
+
572
+ def perm_move_rule(issuer, kwargs, *, session: "Optional[Session]" = None):
573
+ """
574
+ Checks if an issuer can move a replication rule.
575
+
576
+ :param issuer: Account identifier which issues the command.
577
+ :param kwargs: List of arguments for the action.
578
+ :param session: The DB session to use
579
+ :returns: True if account is allowed to call the API call, otherwise False
580
+ """
581
+ # Admin accounts can do everything
582
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
583
+ return True
584
+
585
+ # Country admins are allowed to change the but need to be admin for the original, as well as future rule
586
+ admin_in_country = []
587
+ for kv in list_account_attributes(account=issuer, session=session):
588
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
589
+ admin_in_country.append(kv['key'].partition('-')[2])
590
+
591
+ admin_source = False
592
+ admin_destination = False
593
+
594
+ if admin_in_country:
595
+ rule = get_rule(rule_id=kwargs['rule_id'], session=session)
596
+ rses = parse_expression(rule['rse_expression'], filter_={'vo': issuer.vo}, session=session)
597
+ for rse in rses:
598
+ if list_rse_attributes(rse_id=rse['id'], session=session).get('country') in admin_in_country:
599
+ admin_source = True
600
+ break
601
+
602
+ rses = parse_expression(kwargs['rse_expression'], filter_={'vo': issuer.vo}, session=session)
603
+ for rse in rses:
604
+ if list_rse_attributes(rse_id=rse['id'], session=session).get('country') in admin_in_country:
605
+ admin_destination = True
606
+ break
607
+
608
+ if admin_source and admin_destination:
609
+ return True
610
+
611
+ return False
612
+
613
+
614
+ def perm_approve_rule(issuer, kwargs, *, session: "Optional[Session]" = None):
615
+ """
616
+ Checks if an issuer can approve a replication rule.
617
+
618
+ :param issuer: Account identifier which issues the command.
619
+ :param kwargs: List of arguments for the action.
620
+ :param session: The DB session to use
621
+ :returns: True if account is allowed to call the API call, otherwise False
622
+ """
623
+ # Admin accounts can do everything
624
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
625
+ return True
626
+
627
+ rule = get_rule(rule_id=kwargs['rule_id'], session=session)
628
+ rses = parse_expression(rule['rse_expression'], filter_={'vo': issuer.vo}, session=session)
629
+
630
+ # APPROVERS can approve the rule
631
+ for rse in rses:
632
+ rse_attr = list_rse_attributes(rse_id=rse['id'], session=session)
633
+ if rse_attr.get('rule_approvers'):
634
+ if issuer.external in rse_attr.get('rule_approvers').split(','):
635
+ return True
636
+
637
+ # LOCALGROUPDISK/LOCALGROUPTAPE admins can approve the rule
638
+ admin_in_country = []
639
+ for kv in list_account_attributes(account=issuer, session=session):
640
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
641
+ admin_in_country.append(kv['key'].partition('-')[2])
642
+ if admin_in_country:
643
+ for rse in rses:
644
+ rse_attr = list_rse_attributes(rse_id=rse['id'], session=session)
645
+ if rse_attr.get('type', '') in ('LOCALGROUPDISK', 'LOCALGROUPTAPE'):
646
+ if rse_attr.get('country', '') in admin_in_country:
647
+ return True
648
+
649
+ # GROUPDISK admins can approve the rule
650
+ admin_for_phys_group = []
651
+ for kv in list_account_attributes(account=issuer, session=session):
652
+ if kv['key'].startswith('group-') and kv['value'] == 'admin':
653
+ admin_for_phys_group.append(kv['key'].partition('-')[2])
654
+ if admin_for_phys_group:
655
+ for rse in rses:
656
+ rse_attr = list_rse_attributes(rse_id=rse['id'], session=session)
657
+ if rse_attr.get('type', '') == 'GROUPDISK':
658
+ if rse_attr.get('physgroup', '') in admin_for_phys_group:
659
+ return True
660
+
661
+ return False
662
+
663
+
664
+ def perm_reduce_rule(issuer, kwargs, *, session: "Optional[Session]" = None):
665
+ """
666
+ Checks if an issuer can reduce a replication rule.
667
+
668
+ :param issuer: Account identifier which issues the command.
669
+ :param kwargs: List of arguments for the action.
670
+ :param session: The DB session to use
671
+ :returns: True if account is allowed to call the API call, otherwise False
672
+ """
673
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
674
+ return True
675
+ return False
676
+
677
+
678
+ def perm_update_subscription(issuer, kwargs, *, session: "Optional[Session]" = None):
679
+ """
680
+ Checks if an account can update a subscription.
681
+
682
+ :param issuer: Account identifier which issues the command.
683
+ :param kwargs: List of arguments for the action.
684
+ :param session: The DB session to use
685
+ :returns: True if account is allowed, otherwise False
686
+ """
687
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
688
+ return True
689
+
690
+ return False
691
+
692
+
693
+ def perm_detach_dids(issuer, kwargs, *, session: "Optional[Session]" = None):
694
+ """
695
+ Checks if an account can detach an data identifier from the other data identifier.
696
+
697
+ :param issuer: Account identifier which issues the command.
698
+ :param kwargs: List of arguments for the action.
699
+ :param session: The DB session to use
700
+ :returns: True if account is allowed, otherwise False
701
+ """
702
+ return perm_attach_dids(issuer, kwargs, session=session)
703
+
704
+
705
+ def perm_set_metadata_bulk(issuer: "InternalAccount", kwargs: dict, *, session: "Optional[Session]" = None) -> bool:
706
+ """
707
+ Checks if an account can set a metadata on a data identifier.
708
+
709
+ :param issuer: Account identifier which issues the command.
710
+ :param kwargs: List of arguments for the action.
711
+ :param session: The DB session to use
712
+ :returns: True if account is allowed, otherwise False
713
+ """
714
+ return perm_set_metadata(issuer, kwargs, session=session)
715
+
716
+
717
+ def perm_set_metadata(issuer, kwargs, *, session: "Optional[Session]" = None):
718
+ """
719
+ Checks if an account can set a metadata on a data identifier.
720
+
721
+ :param issuer: Account identifier which issues the command.
722
+ :param kwargs: List of arguments for the action.
723
+ :param session: The DB session to use
724
+ :returns: True if account is allowed, otherwise False
725
+ """
726
+ cond = _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
727
+ if kwargs['scope'].external != 'archive':
728
+ return cond or rucio.core.scope.is_scope_owner(scope=kwargs['scope'], account=issuer, session=session)
729
+ meta = rucio.core.did.get_metadata(scope=kwargs['scope'], name=kwargs['name'], session=session)
730
+ return cond or meta.get('account', False) == issuer
731
+
732
+
733
+ def perm_set_status(issuer, kwargs, *, session: "Optional[Session]" = None):
734
+ """
735
+ Checks if an account can set status on an data identifier.
736
+
737
+ :param issuer: Account identifier which issues the command.
738
+ :param kwargs: List of arguments for the action.
739
+ :param session: The DB session to use
740
+ :returns: True if account is allowed, otherwise False
741
+ """
742
+ if kwargs.get('open', False):
743
+ if not _is_root(issuer) and not has_account_attribute(account=issuer, key='admin', session=session):
744
+ return False
745
+ cond = (_is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session))
746
+ if kwargs['scope'].external != 'archive':
747
+ return cond or rucio.core.scope.is_scope_owner(scope=kwargs['scope'], account=issuer, session=session)
748
+ meta = rucio.core.did.get_metadata(scope=kwargs['scope'], name=kwargs['name'], session=session)
749
+ return cond or meta.get('account', False) == issuer
750
+
751
+
752
+ def perm_add_protocol(issuer, kwargs, *, session: "Optional[Session]" = None):
753
+ """
754
+ Checks if an account can add a protocol to an RSE.
755
+
756
+ :param issuer: Account identifier which issues the command.
757
+ :param kwargs: List of arguments for the action.
758
+ :param session: The DB session to use
759
+ :returns: True if account is allowed, otherwise False
760
+ """
761
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
762
+
763
+
764
+ def perm_del_protocol(issuer, kwargs, *, session: "Optional[Session]" = None):
765
+ """
766
+ Checks if an account can delete protocols from an RSE.
767
+
768
+ :param issuer: Account identifier which issues the command.
769
+ :param kwargs: List of arguments for the action.
770
+ :param session: The DB session to use
771
+ :returns: True if account is allowed, otherwise False
772
+ """
773
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
774
+
775
+
776
+ def perm_update_protocol(issuer, kwargs, *, session: "Optional[Session]" = None):
777
+ """
778
+ Checks if an account can update protocols of an RSE.
779
+
780
+ :param issuer: Account identifier which issues the command.
781
+ :param kwargs: List of arguments for the action.
782
+ :param session: The DB session to use
783
+ :returns: True if account is allowed, otherwise False
784
+ """
785
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
786
+
787
+
788
+ def perm_add_qos_policy(issuer, kwargs, *, session: "Optional[Session]" = None):
789
+ """
790
+ Checks if an account can add QoS policies to an RSE.
791
+
792
+ :param issuer: Account identifier which issues the command.
793
+ :param kwargs: List of arguments for the action.
794
+ :param session: The DB session to use
795
+ :returns: True if account is allowed, otherwise False
796
+ """
797
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
798
+
799
+
800
+ def perm_delete_qos_policy(issuer, kwargs, *, session: "Optional[Session]" = None):
801
+ """
802
+ Checks if an account can delete QoS policies from an RSE.
803
+
804
+ :param issuer: Account identifier which issues the command.
805
+ :param kwargs: List of arguments for the action.
806
+ :param session: The DB session to use
807
+ :returns: True if account is allowed, otherwise False
808
+ """
809
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
810
+
811
+
812
+ def perm_declare_bad_file_replicas(issuer, kwargs, *, session: "Optional[Session]" = None):
813
+ """
814
+ Checks if an account can declare bad file replicas.
815
+
816
+ :param issuer: Account identifier which issues the command.
817
+ :param kwargs: List of arguments for the action.
818
+ :param session: The DB session to use
819
+ :returns: True if account is allowed, otherwise False
820
+ """
821
+ is_cloud_admin = bool([acc_attr for acc_attr in list_account_attributes(account=issuer, session=session) if (acc_attr['key'].startswith('cloud-')) and (acc_attr['value'] == 'admin')])
822
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session) or is_cloud_admin
823
+
824
+
825
+ def perm_declare_suspicious_file_replicas(issuer, kwargs, *, session: "Optional[Session]" = None):
826
+ """
827
+ Checks if an account can declare suspicious file replicas.
828
+
829
+ :param issuer: Account identifier which issues the command.
830
+ :param kwargs: List of arguments for the action.
831
+ :param session: The DB session to use
832
+ :returns: True if account is allowed, otherwise False
833
+ """
834
+ return True
835
+
836
+
837
+ def perm_add_replicas(issuer, kwargs, *, session: "Optional[Session]" = None):
838
+ """
839
+ Checks if an account can add replicas.
840
+
841
+ :param issuer: Account identifier which issues the command.
842
+ :param kwargs: List of arguments for the action.
843
+ :param session: The DB session to use
844
+ :returns: True if account is allowed, otherwise False
845
+ """
846
+ rse_id = str(kwargs.get('rse_id', ''))
847
+ group = []
848
+
849
+ for kv in list_account_attributes(account=issuer, session=session):
850
+ if (kv['key'].startswith('group-') or kv['key'].startswith('country-')) and kv['value'] in ['admin', 'user']:
851
+ group.append(kv['key'].partition('-')[2])
852
+ rse_attr = list_rse_attributes(rse_id=rse_id, session=session)
853
+ if group:
854
+ if rse_attr.get('type', '') == 'GROUPDISK':
855
+ if rse_attr.get('physgroup', '') in group:
856
+ return True
857
+ if rse_attr.get('type', '') == 'LOCALGROUPDISK':
858
+ if rse_attr.get('country', '') in group:
859
+ return True
860
+
861
+ return rse_attr.get('type', '') in ['SCRATCHDISK', 'MOCK', 'TEST']\
862
+ or _is_root(issuer)\
863
+ or has_account_attribute(account=issuer, key='admin', session=session)
864
+
865
+
866
+ def perm_skip_availability_check(issuer, kwargs, *, session: "Optional[Session]" = None):
867
+ """
868
+ Checks if an account can skip the availabity check to add/delete file replicas.
869
+
870
+ :param issuer: Account identifier which issues the command.
871
+ :param kwargs: List of arguments for the action.
872
+ :param session: The DB session to use
873
+ :returns: True if account is allowed, otherwise False
874
+ """
875
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
876
+
877
+
878
+ def perm_delete_replicas(issuer, kwargs, *, session: "Optional[Session]" = None):
879
+ """
880
+ Checks if an account can delete replicas.
881
+
882
+ :param issuer: Account identifier which issues the command.
883
+ :param kwargs: List of arguments for the action.
884
+ :param session: The DB session to use
885
+ :returns: True if account is allowed, otherwise False
886
+ """
887
+ return False
888
+
889
+
890
+ def perm_update_replicas_states(issuer, kwargs, *, session: "Optional[Session]" = None):
891
+ """
892
+ Checks if an account can delete replicas.
893
+
894
+ :param issuer: Account identifier which issues the command.
895
+ :param kwargs: List of arguments for the action.
896
+ :param session: The DB session to use
897
+ :returns: True if account is allowed, otherwise False
898
+ """
899
+ rse_id = str(kwargs.get('rse_id', ''))
900
+ group = []
901
+
902
+ for kv in list_account_attributes(account=issuer, session=session):
903
+ if (kv['key'].startswith('group-') or kv['key'].startswith('country-')) and kv['value'] in ['admin', 'user']:
904
+ group.append(kv['key'].partition('-')[2])
905
+ rse_attr = list_rse_attributes(rse_id=rse_id, session=session)
906
+ if group:
907
+ if rse_attr.get('type', '') == 'GROUPDISK':
908
+ if rse_attr.get('physgroup', '') in group:
909
+ return True
910
+ if rse_attr.get('type', '') == 'LOCALGROUPDISK':
911
+ if rse_attr.get('country', '') in group:
912
+ return True
913
+
914
+ return rse_attr.get('type', '') in ['SCRATCHDISK', 'MOCK', 'TEST']\
915
+ or _is_root(issuer)\
916
+ or has_account_attribute(account=issuer, key='admin', session=session)
917
+
918
+
919
+ def perm_queue_requests(issuer, kwargs, *, session: "Optional[Session]" = None):
920
+ """
921
+ Checks if an account can submit transfer or deletion requests on destination RSEs for data identifiers.
922
+
923
+ :param issuer: Account identifier which issues the command.
924
+ :param kwargs: List of arguments for the action.
925
+ :param session: The DB session to use
926
+ :returns: True if account is allowed, otherwise False
927
+ """
928
+ return _is_root(issuer)
929
+
930
+
931
+ def perm_get_request_by_did(issuer, kwargs, *, session: "Optional[Session]" = None):
932
+ """
933
+ Checks if an account can get a request by DID.
934
+
935
+ :param issuer: Account identifier which issues the command.
936
+ :param kwargs: List of arguments for the action.
937
+ :param session: The DB session to use
938
+ :returns: True if account is allowed, otherwise False
939
+ """
940
+ return True
941
+
942
+
943
+ def perm_cancel_request(issuer, kwargs, *, session: "Optional[Session]" = None):
944
+ """
945
+ Checks if an account can cancel a request.
946
+
947
+ :param issuer: Account identifier which issues the command.
948
+ :param kwargs: List of arguments for the action.
949
+ :param session: The DB session to use
950
+ :returns: True if account is allowed, otherwise False
951
+ """
952
+ return _is_root(issuer)
953
+
954
+
955
+ def perm_get_next(issuer, kwargs, *, session: "Optional[Session]" = None):
956
+ """
957
+ Checks if an account can retrieve the next request matching the request type and state.
958
+
959
+ :param issuer: Account identifier which issues the command.
960
+ :param kwargs: List of arguments for the action.
961
+ :param session: The DB session to use
962
+ :returns: True if account is allowed, otherwise False
963
+ """
964
+ return _is_root(issuer)
965
+
966
+
967
+ def perm_set_rse_usage(issuer, kwargs, *, session: "Optional[Session]" = None):
968
+ """
969
+ Checks if an account can set RSE usage information.
970
+
971
+ :param issuer: Account identifier which issues the command.
972
+ :param kwargs: List of arguments for the action.
973
+ :param session: The DB session to use
974
+ :returns: True if account is allowed to call the API call, otherwise False
975
+ """
976
+ return _is_root(issuer)
977
+
978
+
979
+ def perm_set_rse_limits(issuer, kwargs, *, session: "Optional[Session]" = None):
980
+ """
981
+ Checks if an account can set RSE limits.
982
+
983
+ :param issuer: Account identifier which issues the command.
984
+ :param kwargs: List of arguments for the action.
985
+ :param session: The DB session to use
986
+ :returns: True if account is allowed to call the API call, otherwise False
987
+ """
988
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
989
+
990
+
991
+ def perm_set_local_account_limit(issuer, kwargs, *, session: "Optional[Session]" = None):
992
+ """
993
+ Checks if an account can set an account limit.
994
+
995
+ :param account: Account identifier which issues the command.
996
+ :param kwargs: List of arguments for the action.
997
+ :param session: The DB session to use
998
+ :returns: True if account is allowed, otherwise False
999
+ """
1000
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
1001
+ return True
1002
+ # Check if user is a country admin
1003
+ admin_in_country = []
1004
+ for kv in list_account_attributes(account=issuer, session=session):
1005
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
1006
+ admin_in_country.append(kv['key'].partition('-')[2])
1007
+ rse_attr = list_rse_attributes(rse_id=kwargs['rse_id'], session=session)
1008
+ if admin_in_country and rse_attr.get('country') in admin_in_country:
1009
+ return True
1010
+ quota_approvers = rse_attr.get('quota_approvers', None)
1011
+ if quota_approvers and issuer.external in quota_approvers.split(','):
1012
+ return True
1013
+ return False
1014
+
1015
+
1016
+ def perm_set_global_account_limit(issuer, kwargs, *, session: "Optional[Session]" = None):
1017
+ """
1018
+ Checks if an account can set a global account limit.
1019
+
1020
+ :param account: Account identifier which issues the command.
1021
+ :param kwargs: List of arguments for the action.
1022
+ :param session: The DB session to use
1023
+ :returns: True if account is allowed, otherwise False
1024
+ """
1025
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
1026
+ return True
1027
+ # Check if user is a country admin
1028
+ admin_in_country = set()
1029
+ for kv in list_account_attributes(account=issuer, session=session):
1030
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
1031
+ admin_in_country.add(kv['key'].partition('-')[2])
1032
+ resolved_rse_countries = {list_rse_attributes(rse_id=rse['rse_id'], session=session).get('country')
1033
+ for rse in parse_expression(kwargs['rse_expression'], filter_={'vo': issuer.vo}, session=session)}
1034
+ if resolved_rse_countries.issubset(admin_in_country):
1035
+ return True
1036
+ return False
1037
+
1038
+
1039
+ def perm_delete_global_account_limit(issuer, kwargs, *, session: "Optional[Session]" = None):
1040
+ """
1041
+ Checks if an account can delete a global account limit.
1042
+
1043
+ :param issuer: Account identifier which issues the command.
1044
+ :param kwargs: List of arguments for the action.
1045
+ :param session: The DB session to use
1046
+ :returns: True if account is allowed, otherwise False
1047
+ """
1048
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
1049
+ return True
1050
+ # Check if user is a country admin
1051
+ admin_in_country = set()
1052
+ for kv in list_account_attributes(account=issuer, session=session):
1053
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
1054
+ admin_in_country.add(kv['key'].partition('-')[2])
1055
+ resolved_rse_countries = {list_rse_attributes(rse_id=rse['rse_id'], session=session).get('country')
1056
+ for rse in parse_expression(kwargs['rse_expression'], filter_={'vo': issuer.vo}, session=session)}
1057
+ if resolved_rse_countries.issubset(admin_in_country):
1058
+ return True
1059
+ return False
1060
+
1061
+
1062
+ def perm_delete_local_account_limit(issuer, kwargs, *, session: "Optional[Session]" = None):
1063
+ """
1064
+ Checks if an account can delete an account limit.
1065
+
1066
+ :param account: Account identifier which issues the command.
1067
+ :param kwargs: List of arguments for the action.
1068
+ :param session: The DB session to use
1069
+ :returns: True if account is allowed, otherwise False
1070
+ """
1071
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
1072
+ return True
1073
+ # Check if user is a country admin
1074
+ admin_in_country = []
1075
+ for kv in list_account_attributes(account=issuer, session=session):
1076
+ if kv['key'].startswith('country-') and kv['value'] == 'admin':
1077
+ admin_in_country.append(kv['key'].partition('-')[2])
1078
+ rse_attr = list_rse_attributes(rse_id=kwargs['rse_id'], session=session)
1079
+ if admin_in_country and rse_attr.get('country') in admin_in_country:
1080
+ return True
1081
+ quota_approvers = rse_attr.get('quota_approvers', None)
1082
+ if quota_approvers and issuer.external in quota_approvers.split(','):
1083
+ return True
1084
+ return False
1085
+
1086
+
1087
+ def perm_config(issuer, kwargs, *, session: "Optional[Session]" = None):
1088
+ """
1089
+ Checks if an account can read/write the configuration.
1090
+
1091
+ :param issuer: Account identifier which issues the command.
1092
+ :param kwargs: List of arguments for the action.
1093
+ :param session: The DB session to use
1094
+ :returns: True if account is allowed to call the API call, otherwise False
1095
+ """
1096
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
1097
+
1098
+
1099
+ def perm_get_local_account_usage(issuer, kwargs, *, session: "Optional[Session]" = None):
1100
+ """
1101
+ Checks if an account can get the account usage of an account.
1102
+
1103
+ :param issuer: Account identifier which issues the command.
1104
+ :param kwargs: List of arguments for the action.
1105
+ :param session: The DB session to use
1106
+ :returns: True if account is allowed, otherwise False
1107
+ """
1108
+ return True
1109
+
1110
+
1111
+ def perm_get_global_account_usage(issuer: str, kwargs: dict[str, str], *, session: "Optional[Session]" = None) -> bool:
1112
+ """
1113
+ Checks if an account can get the account usage of an account.
1114
+
1115
+ :param issuer: Account identifier which issues the command.
1116
+ :param kwargs: List of arguments for the action.
1117
+ :param session: The DB session to use
1118
+ :returns: True if account is allowed, otherwise False
1119
+ """
1120
+ return True
1121
+
1122
+
1123
+ def perm_add_account_attribute(issuer, kwargs, *, session: "Optional[Session]" = None):
1124
+ """
1125
+ Checks if an account can add attributes to accounts.
1126
+
1127
+ :param issuer: Account identifier which issues the command.
1128
+ :param kwargs: List of arguments for the action.
1129
+ :param session: The DB session to use
1130
+ :returns: True if account is allowed to call the API call, otherwise False
1131
+ """
1132
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
1133
+
1134
+
1135
+ def perm_del_account_attribute(issuer, kwargs, *, session: "Optional[Session]" = None):
1136
+ """
1137
+ Checks if an account can add attributes to accounts.
1138
+
1139
+ :param issuer: Account identifier which issues the command.
1140
+ :param kwargs: List of arguments for the action.
1141
+ :param session: The DB session to use
1142
+ :returns: True if account is allowed to call the API call, otherwise False
1143
+ """
1144
+ return perm_add_account_attribute(issuer, kwargs, session=session)
1145
+
1146
+
1147
+ def perm_list_heartbeats(issuer, kwargs, *, session: "Optional[Session]" = None):
1148
+ """
1149
+ Checks if an account can list heartbeats.
1150
+
1151
+ :param issuer: Account identifier which issues the command.
1152
+ :param kwargs: List of arguments for the action.
1153
+ :param session: The DB session to use
1154
+ :returns: True if account is allowed to call the API call, otherwise False
1155
+ """
1156
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='handle_heartbeats', session=session)
1157
+
1158
+
1159
+ def perm_send_heartbeats(issuer, kwargs, *, session: "Optional[Session]" = None):
1160
+ """
1161
+ Checks if an account can send heartbeats.
1162
+
1163
+ :param issuer: Account identifier which issues the command.
1164
+ :param kwargs: List of arguments for the action.
1165
+ :returns: True if account is allowed to call the API call, otherwise False
1166
+ """
1167
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session) or has_account_attribute(account=issuer, key='handle_heartbeats', session=session)
1168
+
1169
+
1170
+ def perm_resurrect(issuer, kwargs, *, session: "Optional[Session]" = None):
1171
+ """
1172
+ Checks if an account can resurrect DIDS.
1173
+
1174
+ :param issuer: Account identifier which issues the command.
1175
+ :param kwargs: List of arguments for the action.
1176
+ :param session: The DB session to use
1177
+ :returns: True if account is allowed to call the API call, otherwise False
1178
+ """
1179
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
1180
+
1181
+
1182
+ def perm_update_lifetime_exceptions(issuer, kwargs, *, session: "Optional[Session]" = None):
1183
+ """
1184
+ Checks if an account can approve/reject Lifetime Model exceptions.
1185
+
1186
+ :param issuer: Account identifier which issues the command.
1187
+ :param session: The DB session to use
1188
+ :returns: True if account is allowed to call the API call, otherwise False
1189
+ """
1190
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
1191
+
1192
+
1193
+ def perm_get_auth_token_ssh(issuer: "InternalAccount", kwargs: dict, *, session: "Optional[Session]" = None) -> bool:
1194
+ """
1195
+ Checks if an account can request an ssh token.
1196
+
1197
+ :param issuer: Account identifier which issues the command.
1198
+ :param session: The DB session to use
1199
+ :returns: True if account is allowed to call the API call, otherwise False
1200
+ """
1201
+ return True
1202
+
1203
+
1204
+ def perm_get_signed_url(issuer, kwargs, *, session: "Optional[Session]" = None):
1205
+ """
1206
+ Checks if an account can request a signed URL.
1207
+
1208
+ :param issuer: Account identifier which issues the command.
1209
+ :param session: The DB session to use
1210
+ :returns: True if account is allowed to call the API call, otherwise False
1211
+ """
1212
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='sign-gcs', session=session)
1213
+
1214
+
1215
+ def perm_add_bad_pfns(issuer, kwargs, *, session: "Optional[Session]" = None):
1216
+ """
1217
+ Checks if an account can declare bad PFNs.
1218
+
1219
+ :param issuer: Account identifier which issues the command.
1220
+ :param kwargs: List of arguments for the action.
1221
+ :param session: The DB session to use
1222
+ :returns: True if account is allowed, otherwise False
1223
+ """
1224
+ if kwargs['state'] in [BadPFNStatus.BAD.name, BadPFNStatus.TEMPORARY_UNAVAILABLE.name]:
1225
+ is_cloud_admin = bool([acc_attr for acc_attr in list_account_attributes(account=issuer, session=session) if (acc_attr['key'].startswith('cloud-')) and (acc_attr['value'] == 'admin')])
1226
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session) or is_cloud_admin
1227
+ elif kwargs['state'] == BadPFNStatus.SUSPICIOUS.name:
1228
+ return True
1229
+ return _is_root(issuer)
1230
+
1231
+
1232
+ def perm_remove_did_from_followed(issuer, kwargs, *, session: "Optional[Session]" = None):
1233
+ """
1234
+ Checks if an account can remove did from followed table.
1235
+
1236
+ :param issuer: Account identifier which issues the command.
1237
+ :param kwargs: List of arguments for the action.
1238
+ :param session: The DB session to use
1239
+ :returns: True if account is allowed, otherwise False
1240
+ """
1241
+ return _is_root(issuer)\
1242
+ or has_account_attribute(account=issuer, key='admin', session=session)\
1243
+ or kwargs['account'] == issuer\
1244
+ or kwargs['scope'].external == 'mock'
1245
+
1246
+
1247
+ def perm_remove_dids_from_followed(issuer, kwargs, *, session: "Optional[Session]" = None):
1248
+ """
1249
+ Checks if an account can bulk remove dids from followed table.
1250
+
1251
+ :param issuer: Account identifier which issues the command.
1252
+ :param kwargs: List of arguments for the action.
1253
+ :param session: The DB session to use
1254
+ :returns: True if account is allowed, otherwise False
1255
+ """
1256
+ if _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session):
1257
+ return True
1258
+ if not kwargs['account'] == issuer:
1259
+ return False
1260
+ return True
1261
+
1262
+
1263
+ def perm_add_vo(issuer, kwargs, *, session: "Optional[Session]" = None):
1264
+ """
1265
+ Checks if an account can add a VO.
1266
+
1267
+ :param issuer: Account identifier which issues the command.
1268
+ :param kwargs: List of arguments for the action.
1269
+ :param session: The DB session to use
1270
+ :returns: True if account is allowed, otherwise False
1271
+ """
1272
+ return (issuer.internal == 'super_root')
1273
+
1274
+
1275
+ def perm_list_vos(issuer, kwargs, *, session: "Optional[Session]" = None):
1276
+ """
1277
+ Checks if an account can list a VO.
1278
+
1279
+ :param issuer: Account identifier which issues the command.
1280
+ :param kwargs: List of arguments for the action.
1281
+ :param session: The DB session to use
1282
+ :returns: True if account is allowed, otherwise False
1283
+ """
1284
+ return (issuer.internal == 'super_root')
1285
+
1286
+
1287
+ def perm_recover_vo_root_identity(issuer, kwargs, *, session: "Optional[Session]" = None):
1288
+ """
1289
+ Checks if an account can recover identities for VOs.
1290
+
1291
+ :param issuer: Account identifier which issues the command.
1292
+ :param kwargs: List of arguments for the action.
1293
+ :param session: The DB session to use
1294
+ :returns: True if account is allowed, otherwise False
1295
+ """
1296
+ return (issuer.internal == 'super_root')
1297
+
1298
+
1299
+ def perm_update_vo(issuer, kwargs, *, session: "Optional[Session]" = None):
1300
+ """
1301
+ Checks if an account can update a VO.
1302
+
1303
+ :param issuer: Account identifier which issues the command.
1304
+ :param kwargs: List of arguments for the action.
1305
+ :param session: The DB session to use
1306
+ :returns: True if account is allowed, otherwise False
1307
+ """
1308
+ return (issuer.internal == 'super_root')
1309
+
1310
+
1311
+ def perm_access_rule_vo(issuer, kwargs, *, session: "Optional[Session]" = None):
1312
+ """
1313
+ Checks if we're at the same VO as the rule_id's
1314
+
1315
+ :param issuer: Account identifier which issues the command.
1316
+ :param kwargs: List of arguments for the action.
1317
+ :param session: The DB session to use
1318
+ :returns: True if account is allowed, otherwise False
1319
+ """
1320
+ return get_rule(kwargs['rule_id'], session=session)['scope'].vo == issuer.vo
1321
+
1322
+
1323
+ def perm_export(issuer, kwargs, *, session: "Optional[Session]" = None):
1324
+ """
1325
+ Checks if an account can export the RSE info.
1326
+
1327
+ :param issuer: Account identifier which issues the command.
1328
+ :param kwargs: List of arguments for the action.
1329
+ :param session: The DB session to use
1330
+ :returns: True if account is allowed, otherwise False
1331
+ """
1332
+ is_cloud_admin = bool([acc_attr for acc_attr in list_account_attributes(account=issuer, session=session) if (acc_attr['key'].startswith('cloud-')) and (acc_attr['value'] == 'admin')])
1333
+ return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session) or is_cloud_admin