rucio 37.0.0rc1__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.
- rucio/__init__.py +17 -0
- rucio/alembicrevision.py +15 -0
- rucio/cli/__init__.py +14 -0
- rucio/cli/account.py +216 -0
- rucio/cli/bin_legacy/__init__.py +13 -0
- rucio/cli/bin_legacy/rucio.py +2825 -0
- rucio/cli/bin_legacy/rucio_admin.py +2500 -0
- rucio/cli/command.py +272 -0
- rucio/cli/config.py +72 -0
- rucio/cli/did.py +191 -0
- rucio/cli/download.py +128 -0
- rucio/cli/lifetime_exception.py +33 -0
- rucio/cli/replica.py +162 -0
- rucio/cli/rse.py +293 -0
- rucio/cli/rule.py +158 -0
- rucio/cli/scope.py +40 -0
- rucio/cli/subscription.py +73 -0
- rucio/cli/upload.py +60 -0
- rucio/cli/utils.py +226 -0
- rucio/client/__init__.py +15 -0
- rucio/client/accountclient.py +432 -0
- rucio/client/accountlimitclient.py +183 -0
- rucio/client/baseclient.py +983 -0
- rucio/client/client.py +120 -0
- rucio/client/configclient.py +126 -0
- rucio/client/credentialclient.py +59 -0
- rucio/client/didclient.py +868 -0
- rucio/client/diracclient.py +56 -0
- rucio/client/downloadclient.py +1783 -0
- rucio/client/exportclient.py +44 -0
- rucio/client/fileclient.py +50 -0
- rucio/client/importclient.py +42 -0
- rucio/client/lifetimeclient.py +90 -0
- rucio/client/lockclient.py +109 -0
- rucio/client/metaconventionsclient.py +140 -0
- rucio/client/pingclient.py +44 -0
- rucio/client/replicaclient.py +452 -0
- rucio/client/requestclient.py +125 -0
- rucio/client/richclient.py +317 -0
- rucio/client/rseclient.py +746 -0
- rucio/client/ruleclient.py +294 -0
- rucio/client/scopeclient.py +90 -0
- rucio/client/subscriptionclient.py +173 -0
- rucio/client/touchclient.py +82 -0
- rucio/client/uploadclient.py +969 -0
- rucio/common/__init__.py +13 -0
- rucio/common/bittorrent.py +234 -0
- rucio/common/cache.py +111 -0
- rucio/common/checksum.py +168 -0
- rucio/common/client.py +122 -0
- rucio/common/config.py +788 -0
- rucio/common/constants.py +217 -0
- rucio/common/constraints.py +17 -0
- rucio/common/didtype.py +237 -0
- rucio/common/dumper/__init__.py +342 -0
- rucio/common/dumper/consistency.py +497 -0
- rucio/common/dumper/data_models.py +362 -0
- rucio/common/dumper/path_parsing.py +75 -0
- rucio/common/exception.py +1208 -0
- rucio/common/extra.py +31 -0
- rucio/common/logging.py +420 -0
- rucio/common/pcache.py +1409 -0
- rucio/common/plugins.py +185 -0
- rucio/common/policy.py +93 -0
- rucio/common/schema/__init__.py +200 -0
- rucio/common/schema/generic.py +416 -0
- rucio/common/schema/generic_multi_vo.py +395 -0
- rucio/common/stomp_utils.py +423 -0
- rucio/common/stopwatch.py +55 -0
- rucio/common/test_rucio_server.py +154 -0
- rucio/common/types.py +483 -0
- rucio/common/utils.py +1688 -0
- rucio/core/__init__.py +13 -0
- rucio/core/account.py +496 -0
- rucio/core/account_counter.py +236 -0
- rucio/core/account_limit.py +425 -0
- rucio/core/authentication.py +620 -0
- rucio/core/config.py +437 -0
- rucio/core/credential.py +224 -0
- rucio/core/did.py +3004 -0
- rucio/core/did_meta_plugins/__init__.py +252 -0
- rucio/core/did_meta_plugins/did_column_meta.py +331 -0
- rucio/core/did_meta_plugins/did_meta_plugin_interface.py +165 -0
- rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
- rucio/core/did_meta_plugins/filter_engine.py +672 -0
- rucio/core/did_meta_plugins/json_meta.py +240 -0
- rucio/core/did_meta_plugins/mongo_meta.py +229 -0
- rucio/core/did_meta_plugins/postgres_meta.py +352 -0
- rucio/core/dirac.py +237 -0
- rucio/core/distance.py +187 -0
- rucio/core/exporter.py +59 -0
- rucio/core/heartbeat.py +363 -0
- rucio/core/identity.py +301 -0
- rucio/core/importer.py +260 -0
- rucio/core/lifetime_exception.py +377 -0
- rucio/core/lock.py +577 -0
- rucio/core/message.py +288 -0
- rucio/core/meta_conventions.py +203 -0
- rucio/core/monitor.py +448 -0
- rucio/core/naming_convention.py +195 -0
- rucio/core/nongrid_trace.py +136 -0
- rucio/core/oidc.py +1463 -0
- rucio/core/permission/__init__.py +161 -0
- rucio/core/permission/generic.py +1124 -0
- rucio/core/permission/generic_multi_vo.py +1144 -0
- rucio/core/quarantined_replica.py +224 -0
- rucio/core/replica.py +4483 -0
- rucio/core/replica_sorter.py +362 -0
- rucio/core/request.py +3091 -0
- rucio/core/rse.py +2079 -0
- rucio/core/rse_counter.py +185 -0
- rucio/core/rse_expression_parser.py +459 -0
- rucio/core/rse_selector.py +304 -0
- rucio/core/rule.py +4484 -0
- rucio/core/rule_grouping.py +1620 -0
- rucio/core/scope.py +181 -0
- rucio/core/subscription.py +362 -0
- rucio/core/topology.py +490 -0
- rucio/core/trace.py +375 -0
- rucio/core/transfer.py +1531 -0
- rucio/core/vo.py +169 -0
- rucio/core/volatile_replica.py +151 -0
- rucio/daemons/__init__.py +13 -0
- rucio/daemons/abacus/__init__.py +13 -0
- rucio/daemons/abacus/account.py +116 -0
- rucio/daemons/abacus/collection_replica.py +124 -0
- rucio/daemons/abacus/rse.py +117 -0
- rucio/daemons/atropos/__init__.py +13 -0
- rucio/daemons/atropos/atropos.py +242 -0
- rucio/daemons/auditor/__init__.py +289 -0
- rucio/daemons/auditor/hdfs.py +97 -0
- rucio/daemons/auditor/srmdumps.py +355 -0
- rucio/daemons/automatix/__init__.py +13 -0
- rucio/daemons/automatix/automatix.py +304 -0
- rucio/daemons/badreplicas/__init__.py +13 -0
- rucio/daemons/badreplicas/minos.py +322 -0
- rucio/daemons/badreplicas/minos_temporary_expiration.py +171 -0
- rucio/daemons/badreplicas/necromancer.py +196 -0
- rucio/daemons/bb8/__init__.py +13 -0
- rucio/daemons/bb8/bb8.py +353 -0
- rucio/daemons/bb8/common.py +759 -0
- rucio/daemons/bb8/nuclei_background_rebalance.py +153 -0
- rucio/daemons/bb8/t2_background_rebalance.py +153 -0
- rucio/daemons/cache/__init__.py +13 -0
- rucio/daemons/cache/consumer.py +133 -0
- rucio/daemons/common.py +405 -0
- rucio/daemons/conveyor/__init__.py +13 -0
- rucio/daemons/conveyor/common.py +562 -0
- rucio/daemons/conveyor/finisher.py +529 -0
- rucio/daemons/conveyor/poller.py +394 -0
- rucio/daemons/conveyor/preparer.py +205 -0
- rucio/daemons/conveyor/receiver.py +179 -0
- rucio/daemons/conveyor/stager.py +133 -0
- rucio/daemons/conveyor/submitter.py +403 -0
- rucio/daemons/conveyor/throttler.py +532 -0
- rucio/daemons/follower/__init__.py +13 -0
- rucio/daemons/follower/follower.py +101 -0
- rucio/daemons/hermes/__init__.py +13 -0
- rucio/daemons/hermes/hermes.py +534 -0
- rucio/daemons/judge/__init__.py +13 -0
- rucio/daemons/judge/cleaner.py +159 -0
- rucio/daemons/judge/evaluator.py +185 -0
- rucio/daemons/judge/injector.py +162 -0
- rucio/daemons/judge/repairer.py +154 -0
- rucio/daemons/oauthmanager/__init__.py +13 -0
- rucio/daemons/oauthmanager/oauthmanager.py +198 -0
- rucio/daemons/reaper/__init__.py +13 -0
- rucio/daemons/reaper/dark_reaper.py +282 -0
- rucio/daemons/reaper/reaper.py +739 -0
- rucio/daemons/replicarecoverer/__init__.py +13 -0
- rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +626 -0
- rucio/daemons/rsedecommissioner/__init__.py +13 -0
- rucio/daemons/rsedecommissioner/config.py +81 -0
- rucio/daemons/rsedecommissioner/profiles/__init__.py +24 -0
- rucio/daemons/rsedecommissioner/profiles/atlas.py +60 -0
- rucio/daemons/rsedecommissioner/profiles/generic.py +452 -0
- rucio/daemons/rsedecommissioner/profiles/types.py +93 -0
- rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
- rucio/daemons/storage/__init__.py +13 -0
- rucio/daemons/storage/consistency/__init__.py +13 -0
- rucio/daemons/storage/consistency/actions.py +848 -0
- rucio/daemons/tracer/__init__.py +13 -0
- rucio/daemons/tracer/kronos.py +511 -0
- rucio/daemons/transmogrifier/__init__.py +13 -0
- rucio/daemons/transmogrifier/transmogrifier.py +762 -0
- rucio/daemons/undertaker/__init__.py +13 -0
- rucio/daemons/undertaker/undertaker.py +137 -0
- rucio/db/__init__.py +13 -0
- rucio/db/sqla/__init__.py +52 -0
- rucio/db/sqla/constants.py +206 -0
- rucio/db/sqla/migrate_repo/__init__.py +13 -0
- rucio/db/sqla/migrate_repo/env.py +110 -0
- rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +70 -0
- rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +47 -0
- rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +59 -0
- rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +43 -0
- rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +91 -0
- rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +76 -0
- rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +43 -0
- rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +50 -0
- rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +68 -0
- rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +40 -0
- rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +45 -0
- rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +60 -0
- rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +40 -0
- rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +140 -0
- rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +73 -0
- rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +74 -0
- rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +43 -0
- rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +50 -0
- rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +134 -0
- rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +64 -0
- rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +39 -0
- rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +64 -0
- rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +51 -0
- rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +41 -0
- rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +43 -0
- rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +44 -0
- rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +53 -0
- rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +38 -0
- rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +47 -0
- rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +57 -0
- rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +69 -0
- rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +42 -0
- rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +47 -0
- rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +46 -0
- rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +40 -0
- rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +67 -0
- rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
- rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +44 -0
- rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +77 -0
- rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +60 -0
- rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +72 -0
- rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +42 -0
- rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +65 -0
- rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +133 -0
- rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +76 -0
- rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +60 -0
- rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +44 -0
- rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +64 -0
- rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +40 -0
- rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +43 -0
- rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +44 -0
- rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +78 -0
- rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +41 -0
- rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +59 -0
- rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +44 -0
- rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +49 -0
- rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +40 -0
- rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +63 -0
- rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +55 -0
- rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +45 -0
- rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +43 -0
- rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +45 -0
- rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +47 -0
- rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +58 -0
- rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +45 -0
- rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +106 -0
- rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +55 -0
- rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +50 -0
- rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +47 -0
- rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +43 -0
- rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +41 -0
- rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +91 -0
- rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +72 -0
- rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +49 -0
- rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +43 -0
- rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +53 -0
- rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +45 -0
- rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +68 -0
- rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +45 -0
- rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +94 -0
- rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +54 -0
- rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +72 -0
- rucio/db/sqla/migrate_repo/versions/a08fa8de1545_transfer_stats_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +76 -0
- rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +47 -0
- rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +121 -0
- rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +59 -0
- rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +52 -0
- rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +54 -0
- rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +64 -0
- rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +49 -0
- rucio/db/sqla/migrate_repo/versions/b0070f3695c8_add_deletedidmeta_table.py +57 -0
- rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +43 -0
- rucio/db/sqla/migrate_repo/versions/b5493606bbf5_fix_primary_key_for_subscription_history.py +41 -0
- rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +91 -0
- rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +40 -0
- rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +143 -0
- rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +76 -0
- rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +50 -0
- rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +72 -0
- rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +43 -0
- rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +65 -0
- rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +47 -0
- rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +146 -0
- rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +104 -0
- rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +44 -0
- rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +43 -0
- rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +103 -0
- rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +49 -0
- rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +104 -0
- rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +29 -0
- rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +74 -0
- rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +47 -0
- rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +43 -0
- rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +37 -0
- rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +43 -0
- rucio/db/sqla/models.py +1743 -0
- rucio/db/sqla/sautils.py +55 -0
- rucio/db/sqla/session.py +529 -0
- rucio/db/sqla/types.py +206 -0
- rucio/db/sqla/util.py +543 -0
- rucio/gateway/__init__.py +13 -0
- rucio/gateway/account.py +345 -0
- rucio/gateway/account_limit.py +363 -0
- rucio/gateway/authentication.py +381 -0
- rucio/gateway/config.py +227 -0
- rucio/gateway/credential.py +70 -0
- rucio/gateway/did.py +987 -0
- rucio/gateway/dirac.py +83 -0
- rucio/gateway/exporter.py +60 -0
- rucio/gateway/heartbeat.py +76 -0
- rucio/gateway/identity.py +189 -0
- rucio/gateway/importer.py +46 -0
- rucio/gateway/lifetime_exception.py +121 -0
- rucio/gateway/lock.py +153 -0
- rucio/gateway/meta_conventions.py +98 -0
- rucio/gateway/permission.py +74 -0
- rucio/gateway/quarantined_replica.py +79 -0
- rucio/gateway/replica.py +538 -0
- rucio/gateway/request.py +330 -0
- rucio/gateway/rse.py +632 -0
- rucio/gateway/rule.py +437 -0
- rucio/gateway/scope.py +100 -0
- rucio/gateway/subscription.py +280 -0
- rucio/gateway/vo.py +126 -0
- rucio/rse/__init__.py +96 -0
- rucio/rse/protocols/__init__.py +13 -0
- rucio/rse/protocols/bittorrent.py +194 -0
- rucio/rse/protocols/cache.py +111 -0
- rucio/rse/protocols/dummy.py +100 -0
- rucio/rse/protocols/gfal.py +708 -0
- rucio/rse/protocols/globus.py +243 -0
- rucio/rse/protocols/http_cache.py +82 -0
- rucio/rse/protocols/mock.py +123 -0
- rucio/rse/protocols/ngarc.py +209 -0
- rucio/rse/protocols/posix.py +250 -0
- rucio/rse/protocols/protocol.py +361 -0
- rucio/rse/protocols/rclone.py +365 -0
- rucio/rse/protocols/rfio.py +145 -0
- rucio/rse/protocols/srm.py +338 -0
- rucio/rse/protocols/ssh.py +414 -0
- rucio/rse/protocols/storm.py +195 -0
- rucio/rse/protocols/webdav.py +594 -0
- rucio/rse/protocols/xrootd.py +302 -0
- rucio/rse/rsemanager.py +881 -0
- rucio/rse/translation.py +260 -0
- rucio/tests/__init__.py +13 -0
- rucio/tests/common.py +280 -0
- rucio/tests/common_server.py +149 -0
- rucio/transfertool/__init__.py +13 -0
- rucio/transfertool/bittorrent.py +200 -0
- rucio/transfertool/bittorrent_driver.py +50 -0
- rucio/transfertool/bittorrent_driver_qbittorrent.py +134 -0
- rucio/transfertool/fts3.py +1600 -0
- rucio/transfertool/fts3_plugins.py +152 -0
- rucio/transfertool/globus.py +201 -0
- rucio/transfertool/globus_library.py +181 -0
- rucio/transfertool/mock.py +89 -0
- rucio/transfertool/transfertool.py +221 -0
- rucio/vcsversion.py +11 -0
- rucio/version.py +45 -0
- rucio/web/__init__.py +13 -0
- rucio/web/rest/__init__.py +13 -0
- rucio/web/rest/flaskapi/__init__.py +13 -0
- rucio/web/rest/flaskapi/authenticated_bp.py +27 -0
- rucio/web/rest/flaskapi/v1/__init__.py +13 -0
- rucio/web/rest/flaskapi/v1/accountlimits.py +236 -0
- rucio/web/rest/flaskapi/v1/accounts.py +1103 -0
- rucio/web/rest/flaskapi/v1/archives.py +102 -0
- rucio/web/rest/flaskapi/v1/auth.py +1644 -0
- rucio/web/rest/flaskapi/v1/common.py +426 -0
- rucio/web/rest/flaskapi/v1/config.py +304 -0
- rucio/web/rest/flaskapi/v1/credentials.py +213 -0
- rucio/web/rest/flaskapi/v1/dids.py +2340 -0
- rucio/web/rest/flaskapi/v1/dirac.py +116 -0
- rucio/web/rest/flaskapi/v1/export.py +75 -0
- rucio/web/rest/flaskapi/v1/heartbeats.py +127 -0
- rucio/web/rest/flaskapi/v1/identities.py +285 -0
- rucio/web/rest/flaskapi/v1/import.py +132 -0
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +312 -0
- rucio/web/rest/flaskapi/v1/locks.py +358 -0
- rucio/web/rest/flaskapi/v1/main.py +91 -0
- rucio/web/rest/flaskapi/v1/meta_conventions.py +241 -0
- rucio/web/rest/flaskapi/v1/metrics.py +36 -0
- rucio/web/rest/flaskapi/v1/nongrid_traces.py +97 -0
- rucio/web/rest/flaskapi/v1/ping.py +88 -0
- rucio/web/rest/flaskapi/v1/redirect.py +366 -0
- rucio/web/rest/flaskapi/v1/replicas.py +1894 -0
- rucio/web/rest/flaskapi/v1/requests.py +998 -0
- rucio/web/rest/flaskapi/v1/rses.py +2250 -0
- rucio/web/rest/flaskapi/v1/rules.py +854 -0
- rucio/web/rest/flaskapi/v1/scopes.py +159 -0
- rucio/web/rest/flaskapi/v1/subscriptions.py +650 -0
- rucio/web/rest/flaskapi/v1/templates/auth_crash.html +80 -0
- rucio/web/rest/flaskapi/v1/templates/auth_granted.html +82 -0
- rucio/web/rest/flaskapi/v1/traces.py +137 -0
- rucio/web/rest/flaskapi/v1/types.py +20 -0
- rucio/web/rest/flaskapi/v1/vos.py +278 -0
- rucio/web/rest/main.py +18 -0
- rucio/web/rest/metrics.py +27 -0
- rucio/web/rest/ping.py +27 -0
- rucio-37.0.0rc1.data/data/rucio/etc/alembic.ini.template +71 -0
- rucio-37.0.0rc1.data/data/rucio/etc/alembic_offline.ini.template +74 -0
- rucio-37.0.0rc1.data/data/rucio/etc/globus-config.yml.template +5 -0
- rucio-37.0.0rc1.data/data/rucio/etc/ldap.cfg.template +30 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approval_request.tmpl +38 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +4 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_user.tmpl +17 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +6 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_user.tmpl +17 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +19 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rse-accounts.cfg.template +25 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.atlas.client.template +43 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.template +241 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio_multi_vo.cfg.template +217 -0
- rucio-37.0.0rc1.data/data/rucio/requirements.server.txt +297 -0
- rucio-37.0.0rc1.data/data/rucio/tools/bootstrap.py +34 -0
- rucio-37.0.0rc1.data/data/rucio/tools/merge_rucio_configs.py +144 -0
- rucio-37.0.0rc1.data/data/rucio/tools/reset_database.py +40 -0
- rucio-37.0.0rc1.data/scripts/rucio +133 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-account +74 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-collection-replica +46 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-rse +78 -0
- rucio-37.0.0rc1.data/scripts/rucio-admin +97 -0
- rucio-37.0.0rc1.data/scripts/rucio-atropos +60 -0
- rucio-37.0.0rc1.data/scripts/rucio-auditor +206 -0
- rucio-37.0.0rc1.data/scripts/rucio-automatix +50 -0
- rucio-37.0.0rc1.data/scripts/rucio-bb8 +57 -0
- rucio-37.0.0rc1.data/scripts/rucio-cache-client +141 -0
- rucio-37.0.0rc1.data/scripts/rucio-cache-consumer +42 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-finisher +58 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-poller +66 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-preparer +37 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-receiver +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-stager +76 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-submitter +139 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-throttler +104 -0
- rucio-37.0.0rc1.data/scripts/rucio-dark-reaper +53 -0
- rucio-37.0.0rc1.data/scripts/rucio-dumper +160 -0
- rucio-37.0.0rc1.data/scripts/rucio-follower +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-hermes +54 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-cleaner +89 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-evaluator +137 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-injector +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-repairer +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-kronos +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-minos +53 -0
- rucio-37.0.0rc1.data/scripts/rucio-minos-temporary-expiration +50 -0
- rucio-37.0.0rc1.data/scripts/rucio-necromancer +120 -0
- rucio-37.0.0rc1.data/scripts/rucio-oauth-manager +63 -0
- rucio-37.0.0rc1.data/scripts/rucio-reaper +83 -0
- rucio-37.0.0rc1.data/scripts/rucio-replica-recoverer +248 -0
- rucio-37.0.0rc1.data/scripts/rucio-rse-decommissioner +66 -0
- rucio-37.0.0rc1.data/scripts/rucio-storage-consistency-actions +74 -0
- rucio-37.0.0rc1.data/scripts/rucio-transmogrifier +77 -0
- rucio-37.0.0rc1.data/scripts/rucio-undertaker +76 -0
- rucio-37.0.0rc1.dist-info/METADATA +92 -0
- rucio-37.0.0rc1.dist-info/RECORD +487 -0
- rucio-37.0.0rc1.dist-info/WHEEL +5 -0
- rucio-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
- rucio-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
- rucio-37.0.0rc1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,381 @@
|
|
|
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, Optional, Union
|
|
16
|
+
|
|
17
|
+
from rucio.common import exception
|
|
18
|
+
from rucio.common.types import InternalAccount, TokenDict
|
|
19
|
+
from rucio.common.utils import gateway_update_return_dict
|
|
20
|
+
from rucio.core import authentication, identity, oidc
|
|
21
|
+
from rucio.db.sqla.constants import IdentityType
|
|
22
|
+
from rucio.db.sqla.session import transactional_session
|
|
23
|
+
from rucio.gateway import permission
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from sqlalchemy.orm import Session
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@transactional_session
|
|
30
|
+
def refresh_cli_auth_token(
|
|
31
|
+
token_string: str,
|
|
32
|
+
account: str,
|
|
33
|
+
vo: str = 'def',
|
|
34
|
+
*,
|
|
35
|
+
session: "Session"
|
|
36
|
+
) -> Optional[tuple[str, int]]:
|
|
37
|
+
"""
|
|
38
|
+
Checks if there is active refresh token and if so returns
|
|
39
|
+
either active token with expiration timestamp or requests a new
|
|
40
|
+
refresh and returns new access token.
|
|
41
|
+
:param token_string: token string
|
|
42
|
+
:param account: Rucio account for which token refresh should be considered
|
|
43
|
+
:param session: The database session in use.
|
|
44
|
+
|
|
45
|
+
:return: tuple of (access token, expiration epoch), None otherswise
|
|
46
|
+
"""
|
|
47
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
48
|
+
return oidc.refresh_cli_auth_token(token_string, internal_account, session=session)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@transactional_session
|
|
52
|
+
def redirect_auth_oidc(
|
|
53
|
+
authn_code: str,
|
|
54
|
+
fetchtoken: bool = False,
|
|
55
|
+
*,
|
|
56
|
+
session: "Session"
|
|
57
|
+
) -> Optional[str]:
|
|
58
|
+
"""
|
|
59
|
+
Finds the Authentication URL in the Rucio DB oauth_requests table
|
|
60
|
+
and redirects user's browser to this URL.
|
|
61
|
+
|
|
62
|
+
:param auth_code: Rucio assigned code to redirect
|
|
63
|
+
authorization securely to IdP via Rucio Auth server through a browser.
|
|
64
|
+
:param fetchtoken: If True, valid token temporarily saved in the oauth_requests table
|
|
65
|
+
will be returned. If False, redirection URL is returned.
|
|
66
|
+
:param session: The database session in use.
|
|
67
|
+
|
|
68
|
+
:returns: result of the query (authorization URL or a
|
|
69
|
+
token if a user asks with the correct code) or None.
|
|
70
|
+
Exception thrown in case of an unexpected crash.
|
|
71
|
+
"""
|
|
72
|
+
return authentication.redirect_auth_oidc(authn_code, fetchtoken, session=session)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@transactional_session
|
|
76
|
+
def get_auth_oidc(
|
|
77
|
+
account: str,
|
|
78
|
+
vo: str = 'def',
|
|
79
|
+
*,
|
|
80
|
+
session: "Session",
|
|
81
|
+
**kwargs
|
|
82
|
+
) -> str:
|
|
83
|
+
"""
|
|
84
|
+
Assembles the authorization request of the Rucio Client tailored to the Rucio user
|
|
85
|
+
& Identity Provider. Saves authentication session parameters in the oauth_requests
|
|
86
|
+
DB table (for later use-cases). This information is saved for the token lifetime
|
|
87
|
+
of a token to allow token exchange and refresh.
|
|
88
|
+
Returns authorization URL as a string or a redirection url to
|
|
89
|
+
be used in user's browser for authentication.
|
|
90
|
+
|
|
91
|
+
:param account: Rucio Account identifier as a string.
|
|
92
|
+
:param vo: The VO to act on.
|
|
93
|
+
:param auth_scope: space separated list of scope names. Scope parameter
|
|
94
|
+
defines which user's info the user allows to provide
|
|
95
|
+
to the Rucio Client.
|
|
96
|
+
:param audience: audience for which tokens are requested ('rucio' is the default)
|
|
97
|
+
:param auto: If True, the function will return authorization URL to the Rucio Client
|
|
98
|
+
which will log-in with user's IdP credentials automatically.
|
|
99
|
+
Also it will instruct the IdP to return an AuthZ code to another Rucio REST
|
|
100
|
+
endpoint /oidc_token. If False, the function will return a URL
|
|
101
|
+
to be used by the user in the browser in order to authenticate via IdP
|
|
102
|
+
(which will then return with AuthZ code to /oidc_code REST endpoint).
|
|
103
|
+
:param polling: If True, '_polling' string will be appended to the access_msg
|
|
104
|
+
in the DB oauth_requests table to inform the authorization stage
|
|
105
|
+
that the Rucio Client is polling the server for a token
|
|
106
|
+
(and no fetchcode needs to be returned at the end).
|
|
107
|
+
:param refresh_lifetime: specifies how long the OAuth daemon should
|
|
108
|
+
be refreshing this token. Default is 96 hours.
|
|
109
|
+
:param ip: IP address of the client as a string.
|
|
110
|
+
:param session: The database session in use.
|
|
111
|
+
|
|
112
|
+
:returns: User & Rucio OIDC Client specific Authorization or Redirection URL as a string
|
|
113
|
+
OR a redirection url to be used in user's browser for authentication.
|
|
114
|
+
"""
|
|
115
|
+
# no permission layer for the moment !
|
|
116
|
+
|
|
117
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
118
|
+
return oidc.get_auth_oidc(internal_account, session=session, **kwargs)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@transactional_session
|
|
122
|
+
def get_token_oidc(
|
|
123
|
+
auth_query_string: str,
|
|
124
|
+
ip: Optional[str] = None,
|
|
125
|
+
*,
|
|
126
|
+
session: "Session"
|
|
127
|
+
) -> Optional[dict[str, Optional[Union[str, bool]]]]:
|
|
128
|
+
"""
|
|
129
|
+
After Rucio User got redirected to Rucio /auth/oidc_token (or /auth/oidc_code)
|
|
130
|
+
REST endpoints with authz code and session state encoded within the URL.
|
|
131
|
+
These parameters are used to eventually gets user's info and tokens from IdP.
|
|
132
|
+
|
|
133
|
+
:param auth_query_string: IdP redirection URL query string (AuthZ code & user session state).
|
|
134
|
+
:param ip: IP address of the client as a string.
|
|
135
|
+
:param session: The database session in use.
|
|
136
|
+
|
|
137
|
+
:returns: One of the following tuples: ("fetchcode", <code>); ("token", <token>);
|
|
138
|
+
("polling", True); The result depends on the authentication strategy being used
|
|
139
|
+
(no auto, auto, polling).
|
|
140
|
+
"""
|
|
141
|
+
# no permission layer for the moment !
|
|
142
|
+
return oidc.get_token_oidc(auth_query_string, ip, session=session)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@transactional_session
|
|
146
|
+
def get_auth_token_user_pass(
|
|
147
|
+
account: str,
|
|
148
|
+
username: str,
|
|
149
|
+
password: str,
|
|
150
|
+
appid: str,
|
|
151
|
+
ip: Optional[str] = None,
|
|
152
|
+
vo: str = 'def',
|
|
153
|
+
*,
|
|
154
|
+
session: "Session"
|
|
155
|
+
) -> Optional[TokenDict]:
|
|
156
|
+
"""
|
|
157
|
+
Authenticate a Rucio account temporarily via username and password.
|
|
158
|
+
|
|
159
|
+
The token lifetime is 1 hour.
|
|
160
|
+
|
|
161
|
+
:param account: Account identifier as a string.
|
|
162
|
+
:param username: Username as a string.
|
|
163
|
+
:param password: SHA1 hash of the password as a string.
|
|
164
|
+
:param appid: The application identifier as a string.
|
|
165
|
+
:param ip: IP address of the client as a string.
|
|
166
|
+
:param vo: The VO to act on.
|
|
167
|
+
:param session: The database session in use.
|
|
168
|
+
|
|
169
|
+
:returns: A dict with token and expires_at entries.
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
kwargs = {'account': account, 'username': username, 'password': password}
|
|
173
|
+
auth_result = permission.has_permission(issuer=account, vo=vo, action='get_auth_token_user_pass', kwargs=kwargs, session=session)
|
|
174
|
+
if not auth_result.allowed:
|
|
175
|
+
raise exception.AccessDenied('User with identity %s can not log to account %s. %s' % (username, account, auth_result.message))
|
|
176
|
+
|
|
177
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
178
|
+
|
|
179
|
+
return authentication.get_auth_token_user_pass(internal_account, username, password, appid, ip, session=session)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@transactional_session
|
|
183
|
+
def get_auth_token_gss(
|
|
184
|
+
account: str,
|
|
185
|
+
gsscred: str,
|
|
186
|
+
appid: str,
|
|
187
|
+
ip: Optional[str] = None,
|
|
188
|
+
vo: str = 'def',
|
|
189
|
+
*,
|
|
190
|
+
session: "Session"
|
|
191
|
+
) -> Optional[TokenDict]:
|
|
192
|
+
"""
|
|
193
|
+
Authenticate a Rucio account temporarily via a GSS token.
|
|
194
|
+
|
|
195
|
+
The tokens lifetime is 1 hour.
|
|
196
|
+
|
|
197
|
+
:param account: Account identifier as a string.
|
|
198
|
+
:param gsscred: GSS principal@REALM as a string.
|
|
199
|
+
:param appid: The application identifier as a string.
|
|
200
|
+
:param ip: IP address of the client as a string.
|
|
201
|
+
:param vo: The VO to act on.
|
|
202
|
+
:param session: The database session in use.
|
|
203
|
+
|
|
204
|
+
:returns: A dict with token and expires_at entries.
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
kwargs = {'account': account, 'gsscred': gsscred}
|
|
208
|
+
auth_result = permission.has_permission(issuer=account, vo=vo, action='get_auth_token_gss', kwargs=kwargs, session=session)
|
|
209
|
+
if not auth_result.allowed:
|
|
210
|
+
raise exception.AccessDenied('User with identity %s can not log to account %s. %s' % (gsscred, account, auth_result.message))
|
|
211
|
+
|
|
212
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
213
|
+
|
|
214
|
+
return authentication.get_auth_token_gss(internal_account, gsscred, appid, ip, session=session)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@transactional_session
|
|
218
|
+
def get_auth_token_x509(
|
|
219
|
+
account: Optional[str],
|
|
220
|
+
dn: str,
|
|
221
|
+
appid: str,
|
|
222
|
+
ip: Optional[str] = None,
|
|
223
|
+
vo: str = 'def',
|
|
224
|
+
*,
|
|
225
|
+
session: "Session"
|
|
226
|
+
) -> Optional[TokenDict]:
|
|
227
|
+
"""
|
|
228
|
+
Authenticate a Rucio account temporarily via an x509 certificate.
|
|
229
|
+
|
|
230
|
+
The token lifetime is 1 hour.
|
|
231
|
+
|
|
232
|
+
:param account: Account identifier as a string. If account is none, the default will be used.
|
|
233
|
+
:param dn: Client certificate distinguished name string, as extracted by Apache/mod_ssl.
|
|
234
|
+
:param appid: The application identifier as a string.
|
|
235
|
+
:param ip: IP address of the client as a string.
|
|
236
|
+
:param vo: The VO to act on.
|
|
237
|
+
:param session: The database session in use.
|
|
238
|
+
|
|
239
|
+
:returns: A dict with token and expires_at entries.
|
|
240
|
+
"""
|
|
241
|
+
|
|
242
|
+
if account is None:
|
|
243
|
+
account = identity.get_default_account(dn, IdentityType.X509).external
|
|
244
|
+
|
|
245
|
+
kwargs = {'account': account, 'dn': dn}
|
|
246
|
+
auth_result = permission.has_permission(issuer=account, vo=vo, action='get_auth_token_x509', kwargs=kwargs, session=session)
|
|
247
|
+
if not auth_result.allowed:
|
|
248
|
+
raise exception.AccessDenied('User with identity %s can not log to account %s. %s' % (dn, account, auth_result.message))
|
|
249
|
+
|
|
250
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
251
|
+
|
|
252
|
+
return authentication.get_auth_token_x509(internal_account, dn, appid, ip, session=session)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@transactional_session
|
|
256
|
+
def get_auth_token_ssh(
|
|
257
|
+
account: str,
|
|
258
|
+
signature: str,
|
|
259
|
+
appid: str,
|
|
260
|
+
ip: Optional[str] = None,
|
|
261
|
+
vo: str = 'def',
|
|
262
|
+
*,
|
|
263
|
+
session: "Session"
|
|
264
|
+
) -> Optional[TokenDict]:
|
|
265
|
+
"""
|
|
266
|
+
Authenticate a Rucio account temporarily via SSH key exchange.
|
|
267
|
+
|
|
268
|
+
The token lifetime is 1 hour.
|
|
269
|
+
|
|
270
|
+
:param account: Account identifier as a string.
|
|
271
|
+
:param signature: Response to challenge token signed with SSH private key as a base64 encoded string.
|
|
272
|
+
:param appid: The application identifier as a string.
|
|
273
|
+
:param ip: IP address of the client as a string.
|
|
274
|
+
:param vo: The VO to act on.
|
|
275
|
+
:param session: The database session in use.
|
|
276
|
+
|
|
277
|
+
:returns: A dict with token and expires_at entries.
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
kwargs = {'account': account, 'signature': signature}
|
|
281
|
+
auth_result = permission.has_permission(issuer=account, vo=vo, action='get_auth_token_ssh', kwargs=kwargs, session=session)
|
|
282
|
+
if not auth_result.allowed:
|
|
283
|
+
raise exception.AccessDenied('User with provided signature can not log to account %s. %s' % (account, auth_result.message))
|
|
284
|
+
|
|
285
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
286
|
+
|
|
287
|
+
return authentication.get_auth_token_ssh(internal_account, signature, appid, ip, session=session)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
@transactional_session
|
|
291
|
+
def get_ssh_challenge_token(
|
|
292
|
+
account: str,
|
|
293
|
+
appid: str,
|
|
294
|
+
ip: Optional[str] = None,
|
|
295
|
+
vo: str = 'def',
|
|
296
|
+
*,
|
|
297
|
+
session: "Session"
|
|
298
|
+
) -> Optional[TokenDict]:
|
|
299
|
+
"""
|
|
300
|
+
Get a challenge token for subsequent SSH public key authentication.
|
|
301
|
+
|
|
302
|
+
The challenge token lifetime is 5 seconds.
|
|
303
|
+
|
|
304
|
+
:param account: Account identifier as a string.
|
|
305
|
+
:param appid: The application identifier as a string.
|
|
306
|
+
:param ip: IP address of the client as a string.
|
|
307
|
+
:param vo: The VO to act on.
|
|
308
|
+
:param session: The database session in use.
|
|
309
|
+
|
|
310
|
+
:returns: A dict with token and expires_at entries.
|
|
311
|
+
"""
|
|
312
|
+
|
|
313
|
+
kwargs = {'account': account}
|
|
314
|
+
auth_result = permission.has_permission(issuer=account, vo=vo, action='get_auth_token_ssh', kwargs=kwargs, session=session)
|
|
315
|
+
if not auth_result.allowed:
|
|
316
|
+
raise exception.AccessDenied('User can not get challenge token for account %s. %s' % (account, auth_result.message))
|
|
317
|
+
|
|
318
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
319
|
+
|
|
320
|
+
return authentication.get_ssh_challenge_token(internal_account, appid, ip, session=session)
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
@transactional_session
|
|
324
|
+
def get_auth_token_saml(
|
|
325
|
+
account: str,
|
|
326
|
+
saml_nameid: str,
|
|
327
|
+
appid: str,
|
|
328
|
+
ip: Optional[str] = None,
|
|
329
|
+
vo: str = 'def',
|
|
330
|
+
*,
|
|
331
|
+
session: "Session"
|
|
332
|
+
) -> Optional[TokenDict]:
|
|
333
|
+
"""
|
|
334
|
+
Authenticate a Rucio account temporarily via SSO.
|
|
335
|
+
|
|
336
|
+
The token lifetime is 1 hour.
|
|
337
|
+
|
|
338
|
+
:param account: Account identifier as a string.
|
|
339
|
+
:param saml_nameid: NameId returned in SAML response as a string.
|
|
340
|
+
:param appid: The application identifier as a string.
|
|
341
|
+
:param ip: IP address of the client as a string.
|
|
342
|
+
:param session: The database session in use.
|
|
343
|
+
|
|
344
|
+
:returns: A dict with token and expires_at entries.
|
|
345
|
+
"""
|
|
346
|
+
|
|
347
|
+
kwargs = {'account': account, 'saml_nameid': saml_nameid}
|
|
348
|
+
auth_result = permission.has_permission(issuer=account, vo=vo, action='get_auth_token_saml', kwargs=kwargs, session=session)
|
|
349
|
+
if not auth_result.allowed:
|
|
350
|
+
raise exception.AccessDenied('User with identity %s can not log to account %s. %s' % (saml_nameid, account, auth_result.message))
|
|
351
|
+
|
|
352
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
353
|
+
|
|
354
|
+
return authentication.get_auth_token_saml(internal_account, saml_nameid, appid, ip, session=session)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
@transactional_session
|
|
358
|
+
def validate_auth_token(
|
|
359
|
+
token: str,
|
|
360
|
+
*,
|
|
361
|
+
session: "Session"
|
|
362
|
+
) -> dict[str, Any]:
|
|
363
|
+
"""
|
|
364
|
+
Validate an authentication token.
|
|
365
|
+
|
|
366
|
+
:param token: Authentication token as a variable-length string.
|
|
367
|
+
:param session: The database session in use.
|
|
368
|
+
|
|
369
|
+
:returns: dictionary { account: <account name>,
|
|
370
|
+
identity: <identity>,
|
|
371
|
+
lifetime: <token lifetime>,
|
|
372
|
+
audience: <audience>,
|
|
373
|
+
authz_scope: <authz_scope>,
|
|
374
|
+
vo: <vo> }
|
|
375
|
+
"""
|
|
376
|
+
|
|
377
|
+
auth = authentication.validate_auth_token(token, session=session)
|
|
378
|
+
vo = auth['account'].vo
|
|
379
|
+
auth = gateway_update_return_dict(auth, session=session)
|
|
380
|
+
auth['vo'] = vo
|
|
381
|
+
return auth
|
rucio/gateway/config.py
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
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, Optional
|
|
16
|
+
|
|
17
|
+
from rucio.common import exception
|
|
18
|
+
from rucio.common.config import convert_to_any_type
|
|
19
|
+
from rucio.core import config
|
|
20
|
+
from rucio.db.sqla.session import read_session, transactional_session
|
|
21
|
+
from rucio.gateway import permission
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from sqlalchemy.orm import Session
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
ConfigParser compatible interface.
|
|
28
|
+
|
|
29
|
+
- File handling methods unnecessary.
|
|
30
|
+
- Convenience methods getint/getfloat/getboolean are superseded by auto-coercing get.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@read_session
|
|
35
|
+
def sections(issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> list[str]:
|
|
36
|
+
"""
|
|
37
|
+
Return a list of the sections available.
|
|
38
|
+
|
|
39
|
+
:param issuer: The issuer account.
|
|
40
|
+
:param vo: The VO to act on.
|
|
41
|
+
:param session: The database session in use.
|
|
42
|
+
:returns: ['section_name', ...]
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
kwargs = {'issuer': issuer}
|
|
46
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_sections', kwargs=kwargs, session=session)
|
|
47
|
+
if not auth_result.allowed:
|
|
48
|
+
raise exception.AccessDenied('%s cannot retrieve sections. %s' % (issuer, auth_result.message))
|
|
49
|
+
return config.sections(session=session)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@transactional_session
|
|
53
|
+
def add_section(section: str, issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> None:
|
|
54
|
+
"""
|
|
55
|
+
Add a section to the configuration.
|
|
56
|
+
|
|
57
|
+
:param section: The name of the section.
|
|
58
|
+
:param issuer: The issuer account.
|
|
59
|
+
:param session: The database session in use.
|
|
60
|
+
:param vo: The VO to act on.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
kwargs = {'issuer': issuer, 'section': section}
|
|
64
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_add_section', kwargs=kwargs, session=session)
|
|
65
|
+
if not auth_result.allowed:
|
|
66
|
+
raise exception.AccessDenied('%s cannot add section %s. %s' % (issuer, section, auth_result.message))
|
|
67
|
+
return config.add_section(section, session=session)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@read_session
|
|
71
|
+
def has_section(section: str, issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> bool:
|
|
72
|
+
"""
|
|
73
|
+
Indicates whether the named section is present in the configuration.
|
|
74
|
+
|
|
75
|
+
:param section: The name of the section.
|
|
76
|
+
:param issuer: The issuer account.
|
|
77
|
+
:param vo: The VO to act on.
|
|
78
|
+
:param session: The database session in use.
|
|
79
|
+
:returns: True/False
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
kwargs = {'issuer': issuer, 'section': section}
|
|
83
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_has_section', kwargs=kwargs, session=session)
|
|
84
|
+
if not auth_result.allowed:
|
|
85
|
+
raise exception.AccessDenied('%s cannot check existence of section %s. %s' % (issuer, section, auth_result.message))
|
|
86
|
+
return config.has_section(section, session=session)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@read_session
|
|
90
|
+
def options(section: str, issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> list[str]:
|
|
91
|
+
"""
|
|
92
|
+
Returns a list of options available in the specified section.
|
|
93
|
+
|
|
94
|
+
:param section: The name of the section.
|
|
95
|
+
:param issuer: The issuer account.
|
|
96
|
+
:param vo: The VO to act on.
|
|
97
|
+
:param session: The database session in use.
|
|
98
|
+
:returns: ['option', ...]
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
kwargs = {'issuer': issuer, 'section': section}
|
|
102
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_options', kwargs=kwargs, session=session)
|
|
103
|
+
if auth_result.allowed:
|
|
104
|
+
raise exception.AccessDenied('%s cannot retrieve options from section %s. %s' % (issuer, section, auth_result.message))
|
|
105
|
+
return config.options(section, session=session)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@read_session
|
|
109
|
+
def has_option(section: str, option: str, issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> bool:
|
|
110
|
+
"""
|
|
111
|
+
Check if the given section exists and contains the given option.
|
|
112
|
+
|
|
113
|
+
:param section: The name of the section.
|
|
114
|
+
:param option: The name of the option.
|
|
115
|
+
:param issuer: The issuer account.
|
|
116
|
+
:param vo: The VO to act on.
|
|
117
|
+
:param session: The database session in use.
|
|
118
|
+
:returns: True/False
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
kwargs = {'issuer': issuer, 'section': section, 'option': option}
|
|
122
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_has_option', kwargs=kwargs, session=session)
|
|
123
|
+
if not auth_result.allowed:
|
|
124
|
+
raise exception.AccessDenied('%s cannot check existence of option %s from section %s. %s' % (issuer, option, section, auth_result.message))
|
|
125
|
+
return config.has_option(section, option, session=session)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@read_session
|
|
129
|
+
def get(section: str, option: str, issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> Any:
|
|
130
|
+
"""
|
|
131
|
+
Get an option value for the named section. Value can be auto-coerced to int, float, and bool; string otherwise.
|
|
132
|
+
|
|
133
|
+
Caveat emptor: Strings, regardless the case, matching 'on'/off', 'true'/'false', 'yes'/'no' are converted to bool.
|
|
134
|
+
0/1 are converted to int, and not to bool.
|
|
135
|
+
|
|
136
|
+
:param section: The name of the section.
|
|
137
|
+
:param option: The name of the option.
|
|
138
|
+
:param issuer: The issuer account.
|
|
139
|
+
:param vo: The VO to act on.
|
|
140
|
+
:param session: The database session in use.
|
|
141
|
+
:returns: The auto-coerced value.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
kwargs = {'issuer': issuer, 'section': section, 'option': option}
|
|
145
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_get', kwargs=kwargs, session=session)
|
|
146
|
+
if not auth_result.allowed:
|
|
147
|
+
raise exception.AccessDenied('%s cannot retrieve option %s from section %s. %s' % (issuer, option, section, auth_result.message))
|
|
148
|
+
return config.get(section, option, session=session, convert_type_fnc=convert_to_any_type)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@read_session
|
|
152
|
+
def items(section: str, issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> list[tuple[str, Any]]:
|
|
153
|
+
"""
|
|
154
|
+
Return a list of (option, value) pairs for each option in the given section. Values are auto-coerced as in get().
|
|
155
|
+
|
|
156
|
+
:param section: The name of the section.
|
|
157
|
+
:param value: The content of the value.
|
|
158
|
+
:param issuer: The issuer account.
|
|
159
|
+
:param vo: The VO to act on.
|
|
160
|
+
:param session: The database session in use.
|
|
161
|
+
:returns: [('option', auto-coerced value), ...]
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
kwargs = {'issuer': issuer, 'section': section}
|
|
165
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_items', kwargs=kwargs, session=session)
|
|
166
|
+
if not auth_result.allowed:
|
|
167
|
+
raise exception.AccessDenied('%s cannot retrieve options and values from section %s. %s' % (issuer, section, auth_result.message))
|
|
168
|
+
return config.items(section, session=session, convert_type_fnc=convert_to_any_type)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@transactional_session
|
|
172
|
+
def set(section: str, option: str, value: Any, issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> None:
|
|
173
|
+
"""
|
|
174
|
+
Set the given option to the specified value.
|
|
175
|
+
|
|
176
|
+
:param section: The name of the section.
|
|
177
|
+
:param option: The name of the option.
|
|
178
|
+
:param value: The content of the value.
|
|
179
|
+
:param issuer: The issuer account.
|
|
180
|
+
:param vo: The VO to act on.
|
|
181
|
+
:param session: The database session in use.
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
kwargs = {'issuer': issuer, 'section': section, 'option': option, 'value': value}
|
|
185
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_set', kwargs=kwargs, session=session)
|
|
186
|
+
if not auth_result.allowed:
|
|
187
|
+
raise exception.AccessDenied('%s cannot set option %s to %s in section %s. %s' % (issuer, option, value, section, auth_result.message))
|
|
188
|
+
return config.set(section, option, value, session=session)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
@transactional_session
|
|
192
|
+
def remove_section(section: str, issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> bool:
|
|
193
|
+
"""
|
|
194
|
+
Remove the specified option from the specified section.
|
|
195
|
+
|
|
196
|
+
:param section: The name of the section.
|
|
197
|
+
:param issuer: The issuer account.
|
|
198
|
+
:param vo: The VO to act on.
|
|
199
|
+
:param session: The database session in use.
|
|
200
|
+
:returns: True/False.
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
kwargs = {'issuer': issuer, 'section': section}
|
|
204
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_remove_section', kwargs=kwargs, session=session)
|
|
205
|
+
if not auth_result.allowed:
|
|
206
|
+
raise exception.AccessDenied('%s cannot remove section %s. %s' % (issuer, section, auth_result.message))
|
|
207
|
+
return config.remove_section(section, session=session)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
@transactional_session
|
|
211
|
+
def remove_option(section: str, option: str, issuer: Optional[str] = None, vo: str = 'def', *, session: "Session") -> bool:
|
|
212
|
+
"""
|
|
213
|
+
Remove the specified section from the configuration.
|
|
214
|
+
|
|
215
|
+
:param section: The name of the section.
|
|
216
|
+
:param option: The name of the option.
|
|
217
|
+
:param issuer: The issuer account.
|
|
218
|
+
:param vo: The VO to act on.
|
|
219
|
+
:param session: The database session in use.
|
|
220
|
+
:returns: True/False
|
|
221
|
+
"""
|
|
222
|
+
|
|
223
|
+
kwargs = {'issuer': issuer, 'section': section, 'option': option}
|
|
224
|
+
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='config_remove_option', kwargs=kwargs, session=session)
|
|
225
|
+
if not auth_result.allowed:
|
|
226
|
+
raise exception.AccessDenied('%s cannot remove option %s from section %s. %s' % (issuer, option, section, auth_result.message))
|
|
227
|
+
return config.remove_option(section, option, session=session)
|
|
@@ -0,0 +1,70 @@
|
|
|
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
|
|
16
|
+
|
|
17
|
+
from rucio.common import exception
|
|
18
|
+
from rucio.core import credential
|
|
19
|
+
from rucio.core.rse import get_rse_id
|
|
20
|
+
from rucio.db.sqla.session import read_session
|
|
21
|
+
from rucio.gateway import permission
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from sqlalchemy.orm import Session
|
|
25
|
+
|
|
26
|
+
from rucio.common.constants import RSE_BASE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL, SUPPORTED_SIGN_URL_SERVICES_LITERAL
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@read_session
|
|
30
|
+
def get_signed_url(
|
|
31
|
+
account: str,
|
|
32
|
+
appid: str,
|
|
33
|
+
ip: str,
|
|
34
|
+
rse: str,
|
|
35
|
+
service: 'SUPPORTED_SIGN_URL_SERVICES_LITERAL',
|
|
36
|
+
operation: 'RSE_BASE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL',
|
|
37
|
+
url: str,
|
|
38
|
+
lifetime: int,
|
|
39
|
+
vo: str = 'def',
|
|
40
|
+
*,
|
|
41
|
+
session: "Session"
|
|
42
|
+
) -> str:
|
|
43
|
+
"""
|
|
44
|
+
Get a signed URL for a particular service and operation.
|
|
45
|
+
|
|
46
|
+
The signed URL will be valid for 1 hour.
|
|
47
|
+
|
|
48
|
+
:param account: Account identifier as a string.
|
|
49
|
+
:param appid: The application identifier as a string.
|
|
50
|
+
:param ip: IP address of the client as a string.
|
|
51
|
+
:param rse: The name of the RSE to which the URL points.
|
|
52
|
+
:param service: The service to authorise, currently only 'gsc'.
|
|
53
|
+
:param operation: The operation to sign, either 'read', 'write', or 'delete'.
|
|
54
|
+
:param url: The URL to sign.
|
|
55
|
+
:param lifetime: Lifetime in seconds.
|
|
56
|
+
:param vo: The vo to act on.
|
|
57
|
+
:param session: The database session in use.
|
|
58
|
+
:returns: Signed URL as a variable-length string.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
kwargs = {'account': account}
|
|
62
|
+
auth_result = permission.has_permission(issuer=account, vo=vo, action='get_signed_url', kwargs=kwargs, session=session)
|
|
63
|
+
if not auth_result.allowed:
|
|
64
|
+
raise exception.AccessDenied('Account %s can not get signed URL for rse=%s, service=%s, operation=%s, url=%s, lifetime=%s. %s' %
|
|
65
|
+
(account, rse, service, operation, url, lifetime, auth_result.message))
|
|
66
|
+
|
|
67
|
+
# look up RSE ID for name
|
|
68
|
+
rse_id = get_rse_id(rse, vo=vo, session=session)
|
|
69
|
+
|
|
70
|
+
return credential.get_signed_url(rse_id, service, operation, url, lifetime)
|