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