rucio 38.3.0__py3-none-any.whl → 38.5.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.
- rucio/cli/bin_legacy/rucio.py +12 -7
- rucio/cli/bin_legacy/rucio_admin.py +9 -2
- rucio/cli/did.py +1 -1
- rucio/cli/opendata.py +19 -2
- rucio/cli/replica.py +6 -2
- rucio/cli/rule.py +0 -1
- rucio/cli/scope.py +9 -0
- rucio/cli/utils.py +11 -0
- rucio/client/accountclient.py +20 -19
- rucio/client/accountlimitclient.py +5 -4
- rucio/client/baseclient.py +25 -25
- rucio/client/configclient.py +7 -6
- rucio/client/credentialclient.py +2 -1
- rucio/client/didclient.py +33 -32
- rucio/client/diracclient.py +2 -1
- rucio/client/downloadclient.py +3 -1
- rucio/client/exportclient.py +2 -1
- rucio/client/importclient.py +2 -1
- rucio/client/lifetimeclient.py +3 -2
- rucio/client/lockclient.py +4 -3
- rucio/client/metaconventionsclient.py +5 -4
- rucio/client/opendataclient.py +8 -7
- rucio/client/pingclient.py +2 -1
- rucio/client/replicaclient.py +27 -26
- rucio/client/requestclient.py +8 -8
- rucio/client/rseclient.py +31 -28
- rucio/client/ruleclient.py +13 -12
- rucio/client/scopeclient.py +44 -4
- rucio/client/subscriptionclient.py +6 -5
- rucio/common/constants.py +18 -0
- rucio/common/didtype.py +18 -11
- rucio/common/exception.py +20 -0
- rucio/common/plugins.py +9 -7
- rucio/core/credential.py +19 -26
- rucio/core/did.py +1 -1
- rucio/core/did_meta_plugins/__init__.py +2 -1
- rucio/core/did_meta_plugins/did_column_meta.py +2 -10
- rucio/core/did_meta_plugins/did_meta_plugin_interface.py +39 -25
- rucio/core/did_meta_plugins/elasticsearch_meta.py +3 -11
- rucio/core/did_meta_plugins/json_meta.py +2 -8
- rucio/core/did_meta_plugins/mongo_meta.py +3 -12
- rucio/core/did_meta_plugins/postgres_meta.py +7 -14
- rucio/core/dirac.py +1 -1
- rucio/core/opendata.py +150 -8
- rucio/core/rse.py +6 -2
- rucio/core/rule_grouping.py +3 -3
- rucio/core/scope.py +47 -7
- rucio/daemons/automatix/automatix.py +2 -0
- rucio/db/sqla/models.py +22 -0
- rucio/gateway/account.py +8 -7
- rucio/gateway/did.py +1 -1
- rucio/gateway/dirac.py +1 -1
- rucio/gateway/opendata.py +2 -2
- rucio/gateway/request.py +2 -117
- rucio/gateway/scope.py +35 -3
- rucio/rse/protocols/webdav.py +5 -2
- rucio/transfertool/fts3.py +0 -19
- rucio/vcsversion.py +3 -3
- rucio/web/rest/flaskapi/v1/accountlimits.py +4 -3
- rucio/web/rest/flaskapi/v1/accounts.py +26 -25
- rucio/web/rest/flaskapi/v1/archives.py +2 -2
- rucio/web/rest/flaskapi/v1/auth.py +15 -14
- rucio/web/rest/flaskapi/v1/common.py +4 -4
- rucio/web/rest/flaskapi/v1/config.py +6 -4
- rucio/web/rest/flaskapi/v1/credentials.py +3 -3
- rucio/web/rest/flaskapi/v1/dids.py +25 -24
- rucio/web/rest/flaskapi/v1/dirac.py +3 -2
- rucio/web/rest/flaskapi/v1/export.py +4 -2
- rucio/web/rest/flaskapi/v1/heartbeats.py +2 -1
- rucio/web/rest/flaskapi/v1/identities.py +5 -4
- rucio/web/rest/flaskapi/v1/import.py +3 -2
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +3 -2
- rucio/web/rest/flaskapi/v1/locks.py +4 -3
- rucio/web/rest/flaskapi/v1/meta_conventions.py +4 -3
- rucio/web/rest/flaskapi/v1/metrics.py +2 -1
- rucio/web/rest/flaskapi/v1/nongrid_traces.py +2 -1
- rucio/web/rest/flaskapi/v1/opendata.py +28 -27
- rucio/web/rest/flaskapi/v1/opendata_public.py +12 -11
- rucio/web/rest/flaskapi/v1/ping.py +3 -2
- rucio/web/rest/flaskapi/v1/redirect.py +4 -3
- rucio/web/rest/flaskapi/v1/replicas.py +31 -31
- rucio/web/rest/flaskapi/v1/requests.py +7 -7
- rucio/web/rest/flaskapi/v1/rses.py +23 -16
- rucio/web/rest/flaskapi/v1/rules.py +9 -8
- rucio/web/rest/flaskapi/v1/scopes.py +66 -13
- rucio/web/rest/flaskapi/v1/subscriptions.py +9 -8
- rucio/web/rest/flaskapi/v1/traces.py +2 -1
- rucio/web/rest/flaskapi/v1/vos.py +4 -3
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/rucio.cfg.template +2 -3
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +2 -3
- {rucio-38.3.0.dist-info → rucio-38.5.0.dist-info}/METADATA +1 -1
- {rucio-38.3.0.dist-info → rucio-38.5.0.dist-info}/RECORD +149 -149
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/alembic.ini.template +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/requirements.server.txt +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/tools/bootstrap.py +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/data/rucio/tools/reset_database.py +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-abacus-account +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-abacus-collection-replica +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-abacus-rse +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-admin +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-atropos +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-auditor +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-automatix +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-bb8 +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-cache-client +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-cache-consumer +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-conveyor-finisher +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-conveyor-poller +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-conveyor-preparer +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-conveyor-receiver +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-conveyor-stager +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-conveyor-submitter +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-conveyor-throttler +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-dark-reaper +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-dumper +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-follower +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-hermes +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-judge-cleaner +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-judge-evaluator +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-judge-injector +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-judge-repairer +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-kronos +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-minos +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-necromancer +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-oauth-manager +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-reaper +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-replica-recoverer +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-rse-decommissioner +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-storage-consistency-actions +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-transmogrifier +0 -0
- {rucio-38.3.0.data → rucio-38.5.0.data}/scripts/rucio-undertaker +0 -0
- {rucio-38.3.0.dist-info → rucio-38.5.0.dist-info}/WHEEL +0 -0
- {rucio-38.3.0.dist-info → rucio-38.5.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {rucio-38.3.0.dist-info → rucio-38.5.0.dist-info}/licenses/LICENSE +0 -0
- {rucio-38.3.0.dist-info → rucio-38.5.0.dist-info}/top_level.txt +0 -0
rucio/gateway/opendata.py
CHANGED
|
@@ -151,7 +151,7 @@ def update_opendata_did(
|
|
|
151
151
|
meta: Optional[dict] = None,
|
|
152
152
|
doi: Optional[str] = None,
|
|
153
153
|
vo: str = DEFAULT_VO,
|
|
154
|
-
) ->
|
|
154
|
+
) -> dict[str, Any]:
|
|
155
155
|
"""
|
|
156
156
|
Update an existing Opendata DID in the Opendata catalog.
|
|
157
157
|
|
|
@@ -164,7 +164,7 @@ def update_opendata_did(
|
|
|
164
164
|
vo: The virtual organization.
|
|
165
165
|
|
|
166
166
|
Returns:
|
|
167
|
-
|
|
167
|
+
A dictionary containing the scope and name of the DID and details of the updates performed. (e.g., new/old state, new/old DOI, etc.)
|
|
168
168
|
|
|
169
169
|
Raises:
|
|
170
170
|
ValueError: If meta is a string and cannot be parsed as valid JSON.
|
rucio/gateway/request.py
CHANGED
|
@@ -20,7 +20,7 @@ from typing import TYPE_CHECKING, Any, Optional
|
|
|
20
20
|
|
|
21
21
|
from rucio.common import exception
|
|
22
22
|
from rucio.common.constants import DEFAULT_VO, TransferLimitDirection
|
|
23
|
-
from rucio.common.types import
|
|
23
|
+
from rucio.common.types import InternalScope
|
|
24
24
|
from rucio.common.utils import gateway_update_return_dict
|
|
25
25
|
from rucio.core import request
|
|
26
26
|
from rucio.core.rse import get_rse_id
|
|
@@ -31,122 +31,7 @@ from rucio.gateway import permission
|
|
|
31
31
|
if TYPE_CHECKING:
|
|
32
32
|
from collections.abc import Iterable, Iterator, Sequence
|
|
33
33
|
|
|
34
|
-
from rucio.db.sqla.constants import RequestState
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def queue_requests(
|
|
38
|
-
requests: "Iterable[RequestGatewayDict]",
|
|
39
|
-
issuer: str,
|
|
40
|
-
vo: str = DEFAULT_VO,
|
|
41
|
-
) -> list[dict[str, Any]]:
|
|
42
|
-
"""
|
|
43
|
-
Submit transfer or deletion requests on destination RSEs for data identifiers.
|
|
44
|
-
|
|
45
|
-
:param requests: List of dictionaries containing 'scope', 'name', 'dest_rse_id', 'request_type', 'attributes'
|
|
46
|
-
:param issuer: Issuing account as a string.
|
|
47
|
-
:param vo: The VO to act on.
|
|
48
|
-
:returns: List of Request-IDs as 32 character hex strings
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
kwargs = {'requests': requests, 'issuer': issuer}
|
|
52
|
-
with db_session(DatabaseOperationType.WRITE) as session:
|
|
53
|
-
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='queue_requests', kwargs=kwargs, session=session)
|
|
54
|
-
if not auth_result.allowed:
|
|
55
|
-
raise exception.AccessDenied(f'{issuer} can not queue request. {auth_result.message}')
|
|
56
|
-
|
|
57
|
-
for req in requests:
|
|
58
|
-
req['scope'] = InternalScope(req['scope'], vo=vo) # type: ignore (type reassignment)
|
|
59
|
-
if 'account' in req:
|
|
60
|
-
req['account'] = InternalAccount(req['account'], vo=vo) # type: ignore (type reassignment)
|
|
61
|
-
|
|
62
|
-
new_requests = request.queue_requests(requests, session=session)
|
|
63
|
-
return [gateway_update_return_dict(r, session=session) for r in new_requests]
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def cancel_request(
|
|
67
|
-
request_id: str,
|
|
68
|
-
issuer: str,
|
|
69
|
-
account: str,
|
|
70
|
-
vo: str = DEFAULT_VO,
|
|
71
|
-
) -> None:
|
|
72
|
-
"""
|
|
73
|
-
Cancel a request.
|
|
74
|
-
|
|
75
|
-
:param request_id: Request Identifier as a 32 character hex string.
|
|
76
|
-
:param issuer: Issuing account as a string.
|
|
77
|
-
:param account: Account identifier as a string.
|
|
78
|
-
:param vo: The VO to act on.
|
|
79
|
-
"""
|
|
80
|
-
|
|
81
|
-
kwargs = {'account': account, 'issuer': issuer, 'request_id': request_id}
|
|
82
|
-
with db_session(DatabaseOperationType.WRITE) as session:
|
|
83
|
-
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='cancel_request_', kwargs=kwargs, session=session)
|
|
84
|
-
if not auth_result.allowed:
|
|
85
|
-
raise exception.AccessDenied('%s cannot cancel request %s. %s' % (account, request_id, auth_result.message))
|
|
86
|
-
|
|
87
|
-
raise NotImplementedError
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def cancel_request_did(
|
|
91
|
-
scope: str,
|
|
92
|
-
name: str,
|
|
93
|
-
dest_rse: str,
|
|
94
|
-
request_type: str,
|
|
95
|
-
issuer: str,
|
|
96
|
-
account: str,
|
|
97
|
-
vo: str = DEFAULT_VO,
|
|
98
|
-
) -> dict[str, Any]:
|
|
99
|
-
"""
|
|
100
|
-
Cancel a request based on a DID and request type.
|
|
101
|
-
|
|
102
|
-
:param scope: Data identifier scope as a string.
|
|
103
|
-
:param name: Data identifier name as a string.
|
|
104
|
-
:param dest_rse: RSE name as a string.
|
|
105
|
-
:param request_type: Type of the request as a string.
|
|
106
|
-
:param issuer: Issuing account as a string.
|
|
107
|
-
:param account: Account identifier as a string.
|
|
108
|
-
:param vo: The VO to act on.
|
|
109
|
-
"""
|
|
110
|
-
|
|
111
|
-
with db_session(DatabaseOperationType.WRITE) as session:
|
|
112
|
-
dest_rse_id = get_rse_id(rse=dest_rse, vo=vo, session=session)
|
|
113
|
-
|
|
114
|
-
kwargs = {'account': account, 'issuer': issuer}
|
|
115
|
-
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='cancel_request_did', kwargs=kwargs, session=session)
|
|
116
|
-
if not auth_result.allowed:
|
|
117
|
-
raise exception.AccessDenied(f'{account} cannot cancel {request_type} request for {scope}:{name}. {auth_result.message}')
|
|
118
|
-
|
|
119
|
-
internal_scope = InternalScope(scope, vo=vo)
|
|
120
|
-
return request.cancel_request_did(internal_scope, name, dest_rse_id, request_type, session=session)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def get_next(
|
|
124
|
-
request_type: "RequestType",
|
|
125
|
-
state: "RequestState",
|
|
126
|
-
issuer: str,
|
|
127
|
-
account: str,
|
|
128
|
-
vo: str = DEFAULT_VO,
|
|
129
|
-
) -> list[dict[str, Any]]:
|
|
130
|
-
"""
|
|
131
|
-
Retrieve the next request matching the request type and state.
|
|
132
|
-
|
|
133
|
-
:param request_type: Type of the request as a string.
|
|
134
|
-
:param state: State of the request as a string.
|
|
135
|
-
:param issuer: Issuing account as a string.
|
|
136
|
-
:param account: Account identifier as a string.
|
|
137
|
-
:param vo: The VO to act on.
|
|
138
|
-
:returns: Request as a dictionary.
|
|
139
|
-
"""
|
|
140
|
-
|
|
141
|
-
kwargs = {'account': account, 'issuer': issuer, 'request_type': request_type, 'state': state}
|
|
142
|
-
|
|
143
|
-
with db_session(DatabaseOperationType.WRITE) as session:
|
|
144
|
-
auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_next', kwargs=kwargs, session=session)
|
|
145
|
-
if not auth_result.allowed:
|
|
146
|
-
raise exception.AccessDenied(f'{account} cannot get the next request of type {request_type} in state {state}. {auth_result.message}')
|
|
147
|
-
|
|
148
|
-
reqs = request.get_and_mark_next(request_type, state, session=session)
|
|
149
|
-
return [gateway_update_return_dict(r, session=session) for r in reqs]
|
|
34
|
+
from rucio.db.sqla.constants import RequestState
|
|
150
35
|
|
|
151
36
|
|
|
152
37
|
def get_request_by_did(
|
rucio/gateway/scope.py
CHANGED
|
@@ -12,19 +12,23 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from typing import Any, Optional
|
|
15
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
16
16
|
|
|
17
17
|
import rucio.gateway.permission
|
|
18
18
|
from rucio.common.constants import DEFAULT_VO
|
|
19
19
|
from rucio.common.exception import AccessDenied
|
|
20
20
|
from rucio.common.schema import validate_schema
|
|
21
21
|
from rucio.common.types import InternalAccount, InternalScope
|
|
22
|
+
from rucio.common.utils import gateway_update_return_dict
|
|
22
23
|
from rucio.core import scope as core_scope
|
|
23
24
|
from rucio.db.sqla.constants import DatabaseOperationType
|
|
24
25
|
from rucio.db.sqla.session import db_session
|
|
25
26
|
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from collections.abc import Generator
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
|
|
31
|
+
def list_scopes(filter_: Optional[dict[str, Any]] = None, vo: str = DEFAULT_VO) -> 'Generator[dict[str, Any]]':
|
|
28
32
|
"""
|
|
29
33
|
Lists all scopes.
|
|
30
34
|
|
|
@@ -42,7 +46,9 @@ def list_scopes(filter_: Optional[dict[str, Any]] = None, vo: str = DEFAULT_VO)
|
|
|
42
46
|
filter_['scope'] = InternalScope(scope='*', vo=vo)
|
|
43
47
|
|
|
44
48
|
with db_session(DatabaseOperationType.READ) as session:
|
|
45
|
-
|
|
49
|
+
scopes = core_scope.list_scopes(filter_=filter_, session=session)
|
|
50
|
+
for scope in scopes:
|
|
51
|
+
yield gateway_update_return_dict(scope, session=session)
|
|
46
52
|
|
|
47
53
|
|
|
48
54
|
def add_scope(
|
|
@@ -92,3 +98,29 @@ def get_scopes(
|
|
|
92
98
|
|
|
93
99
|
with db_session(DatabaseOperationType.READ) as session:
|
|
94
100
|
return [scope.external for scope in core_scope.get_scopes(internal_account, session=session)]
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def update_scope(
|
|
104
|
+
scope: str,
|
|
105
|
+
account: str,
|
|
106
|
+
issuer: str,
|
|
107
|
+
vo: str = DEFAULT_VO
|
|
108
|
+
) -> None:
|
|
109
|
+
"""
|
|
110
|
+
Change ownership of a scope
|
|
111
|
+
|
|
112
|
+
:param account: New owner for the scope
|
|
113
|
+
:param scope: Scope to change
|
|
114
|
+
param issuer: User making the request
|
|
115
|
+
:param vo: VO to act on
|
|
116
|
+
|
|
117
|
+
"""
|
|
118
|
+
kwargs = {'scope': scope, 'account': account}
|
|
119
|
+
with db_session(DatabaseOperationType.WRITE) as session:
|
|
120
|
+
auth_result = rucio.gateway.permission.has_permission(issuer=issuer, vo=vo, action='update_scope', kwargs=kwargs, session=session)
|
|
121
|
+
if not auth_result.allowed:
|
|
122
|
+
raise AccessDenied('Account %s can not add scope. %s' % (issuer, auth_result.message))
|
|
123
|
+
|
|
124
|
+
internal_account = InternalAccount(account, vo=vo)
|
|
125
|
+
internal_scope = InternalScope(scope, vo=vo)
|
|
126
|
+
core_scope.update_scope(internal_scope, internal_account, session=session)
|
rucio/rse/protocols/webdav.py
CHANGED
|
@@ -25,6 +25,7 @@ from requests.adapters import HTTPAdapter
|
|
|
25
25
|
from urllib3.poolmanager import PoolManager
|
|
26
26
|
|
|
27
27
|
from rucio.common import exception
|
|
28
|
+
from rucio.common.constants import HTTPMethod
|
|
28
29
|
from rucio.rse.protocols import protocol
|
|
29
30
|
|
|
30
31
|
|
|
@@ -259,9 +260,11 @@ class Default(protocol.RSEProtocol):
|
|
|
259
260
|
try:
|
|
260
261
|
# use GET instead of HEAD for presigned urls
|
|
261
262
|
if not using_presigned_urls:
|
|
262
|
-
result = self.session.request(
|
|
263
|
+
result = self.session.request(HTTPMethod.HEAD.value, path, verify=False, timeout=self.timeout,
|
|
264
|
+
cert=self.cert)
|
|
263
265
|
else:
|
|
264
|
-
result = self.session.request(
|
|
266
|
+
result = self.session.request(HTTPMethod.GET.value, path, verify=False, timeout=self.timeout,
|
|
267
|
+
cert=self.cert)
|
|
265
268
|
if result.status_code == 200:
|
|
266
269
|
return True
|
|
267
270
|
elif result.status_code in [401, ]:
|
rucio/transfertool/fts3.py
CHANGED
|
@@ -76,7 +76,6 @@ BULK_QUERY_COUNTER = METRICS.counter(name='{host}.bulk_query.{state}',
|
|
|
76
76
|
QUERY_DETAILS_COUNTER = METRICS.counter(name='{host}.query_details.{state}',
|
|
77
77
|
documentation='Number of detailed status queries', labelnames=('state', 'host'))
|
|
78
78
|
|
|
79
|
-
REWRITE_HTTPS_TO_DAVS = config_get_bool('transfers', 'rewrite_https_to_davs', default=False)
|
|
80
79
|
VO_CERTS_PATH = config_get('conveyor', 'vo_certs_path', False, None)
|
|
81
80
|
|
|
82
81
|
# https://fts3-docs.web.cern.ch/fts3-docs/docs/state_machine.html
|
|
@@ -1073,24 +1072,6 @@ class FTS3Transfertool(Transfertool):
|
|
|
1073
1072
|
if not transfer_file['sources'] or transfer_file['sources'] == []:
|
|
1074
1073
|
raise Exception('No sources defined')
|
|
1075
1074
|
|
|
1076
|
-
# TODO: remove the following logic in rucio 1.31
|
|
1077
|
-
if REWRITE_HTTPS_TO_DAVS:
|
|
1078
|
-
new_src_urls = []
|
|
1079
|
-
new_dst_urls = []
|
|
1080
|
-
for url in transfer_file['sources']:
|
|
1081
|
-
if url.startswith('https'):
|
|
1082
|
-
new_src_urls.append(':'.join(['davs'] + url.split(':')[1:]))
|
|
1083
|
-
else:
|
|
1084
|
-
new_src_urls.append(url)
|
|
1085
|
-
for url in transfer_file['destinations']:
|
|
1086
|
-
if url.startswith('https'):
|
|
1087
|
-
new_dst_urls.append(':'.join(['davs'] + url.split(':')[1:]))
|
|
1088
|
-
else:
|
|
1089
|
-
new_dst_urls.append(url)
|
|
1090
|
-
|
|
1091
|
-
transfer_file['sources'] = new_src_urls
|
|
1092
|
-
transfer_file['destinations'] = new_dst_urls
|
|
1093
|
-
|
|
1094
1075
|
transfer_id = None
|
|
1095
1076
|
expected_transfer_id = None
|
|
1096
1077
|
if self.deterministic_id:
|
rucio/vcsversion.py
CHANGED
|
@@ -4,8 +4,8 @@ This file is automatically generated; Do not edit it. :)
|
|
|
4
4
|
'''
|
|
5
5
|
VERSION_INFO = {
|
|
6
6
|
'final': True,
|
|
7
|
-
'version': '38.
|
|
7
|
+
'version': '38.5.0',
|
|
8
8
|
'branch_nick': 'release-38-LTS',
|
|
9
|
-
'revision_id': '
|
|
10
|
-
'revno':
|
|
9
|
+
'revision_id': '430fd3dd8f4dc5103e1e932c9515421e1c515c3e',
|
|
10
|
+
'revno': 14073
|
|
11
11
|
}
|
|
@@ -16,6 +16,7 @@ from typing import TYPE_CHECKING
|
|
|
16
16
|
|
|
17
17
|
from flask import Flask, request
|
|
18
18
|
|
|
19
|
+
from rucio.common.constants import HTTPMethod
|
|
19
20
|
from rucio.common.exception import AccessDenied, AccountNotFound, RSENotFound
|
|
20
21
|
from rucio.gateway.account_limit import delete_global_account_limit, delete_local_account_limit, set_global_account_limit, set_local_account_limit
|
|
21
22
|
from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
|
|
@@ -219,11 +220,11 @@ def blueprint(with_doc: bool = False) -> AuthenticatedBlueprint:
|
|
|
219
220
|
bp = AuthenticatedBlueprint('accountlimits', __name__, url_prefix='/accountlimits')
|
|
220
221
|
|
|
221
222
|
local_account_limit_view = LocalAccountLimit.as_view('local_account_limit')
|
|
222
|
-
bp.add_url_rule('/local/<account>/<rse>', view_func=local_account_limit_view, methods=[
|
|
223
|
+
bp.add_url_rule('/local/<account>/<rse>', view_func=local_account_limit_view, methods=[HTTPMethod.POST.value, HTTPMethod.DELETE.value])
|
|
223
224
|
if not with_doc:
|
|
224
|
-
bp.add_url_rule('/<account>/<rse>', view_func=local_account_limit_view, methods=[
|
|
225
|
+
bp.add_url_rule('/<account>/<rse>', view_func=local_account_limit_view, methods=[HTTPMethod.POST.value, HTTPMethod.DELETE.value])
|
|
225
226
|
global_account_limit_view = GlobalAccountLimit.as_view('global_account_limit')
|
|
226
|
-
bp.add_url_rule('/global/<account>/<rse_expression>', view_func=global_account_limit_view, methods=[
|
|
227
|
+
bp.add_url_rule('/global/<account>/<rse_expression>', view_func=global_account_limit_view, methods=[HTTPMethod.POST.value, HTTPMethod.DELETE.value])
|
|
227
228
|
|
|
228
229
|
bp.after_request(response_headers)
|
|
229
230
|
return bp
|
|
@@ -18,7 +18,8 @@ from typing import TYPE_CHECKING, Any, Literal, Optional, Union
|
|
|
18
18
|
|
|
19
19
|
from flask import Flask, Response, jsonify, redirect, request
|
|
20
20
|
|
|
21
|
-
from rucio.common.
|
|
21
|
+
from rucio.common.constants import HTTPMethod
|
|
22
|
+
from rucio.common.exception import AccessDenied, AccountNotFound, CounterNotFound, Duplicate, IdentityError, InvalidAccountType, InvalidObject, RSENotFound, RuleNotFound, ScopeNotFound
|
|
22
23
|
from rucio.common.utils import APIEncoder, render_json
|
|
23
24
|
from rucio.gateway.account import add_account, add_account_attribute, del_account, del_account_attribute, get_account_info, get_usage_history, list_account_attributes, list_accounts, list_identities, update_account
|
|
24
25
|
from rucio.gateway.account_limit import get_global_account_limit, get_global_account_usage, get_local_account_limit, get_local_account_usage
|
|
@@ -447,7 +448,7 @@ class AccountParameter(ErrorHandlingMethodView):
|
|
|
447
448
|
return generate_http_error_flask(409, error)
|
|
448
449
|
except AccessDenied as error:
|
|
449
450
|
return generate_http_error_flask(401, error)
|
|
450
|
-
except InvalidObject as error:
|
|
451
|
+
except (InvalidObject, InvalidAccountType) as error:
|
|
451
452
|
return generate_http_error_flask(400, error)
|
|
452
453
|
|
|
453
454
|
return 'Created', 201
|
|
@@ -1047,44 +1048,44 @@ def blueprint(with_doc: bool = False) -> AuthenticatedBlueprint:
|
|
|
1047
1048
|
bp = AuthenticatedBlueprint('accounts', __name__, url_prefix='/accounts')
|
|
1048
1049
|
|
|
1049
1050
|
attributes_view = Attributes.as_view('attributes')
|
|
1050
|
-
bp.add_url_rule('/<account>/attr/', view_func=attributes_view, methods=[
|
|
1051
|
-
bp.add_url_rule('/<account>/attr/<key>', view_func=attributes_view, methods=[
|
|
1051
|
+
bp.add_url_rule('/<account>/attr/', view_func=attributes_view, methods=[HTTPMethod.GET.value])
|
|
1052
|
+
bp.add_url_rule('/<account>/attr/<key>', view_func=attributes_view, methods=[HTTPMethod.POST.value, HTTPMethod.DELETE.value])
|
|
1052
1053
|
scopes_view = Scopes.as_view('scopes')
|
|
1053
|
-
bp.add_url_rule('/<account>/scopes/', view_func=scopes_view, methods=[
|
|
1054
|
-
bp.add_url_rule('/<account>/scopes/<scope>', view_func=scopes_view, methods=[
|
|
1054
|
+
bp.add_url_rule('/<account>/scopes/', view_func=scopes_view, methods=[HTTPMethod.GET.value])
|
|
1055
|
+
bp.add_url_rule('/<account>/scopes/<scope>', view_func=scopes_view, methods=[HTTPMethod.POST.value])
|
|
1055
1056
|
local_account_limits_view = LocalAccountLimits.as_view('local_account_limit')
|
|
1056
|
-
bp.add_url_rule('/<account>/limits/local', view_func=local_account_limits_view, methods=[
|
|
1057
|
-
bp.add_url_rule('/<account>/limits', view_func=local_account_limits_view, methods=[
|
|
1058
|
-
bp.add_url_rule('/<account>/limits/local/<rse>', view_func=local_account_limits_view, methods=[
|
|
1059
|
-
bp.add_url_rule('/<account>/limits/<rse>', view_func=local_account_limits_view, methods=[
|
|
1057
|
+
bp.add_url_rule('/<account>/limits/local', view_func=local_account_limits_view, methods=[HTTPMethod.GET.value])
|
|
1058
|
+
bp.add_url_rule('/<account>/limits', view_func=local_account_limits_view, methods=[HTTPMethod.GET.value])
|
|
1059
|
+
bp.add_url_rule('/<account>/limits/local/<rse>', view_func=local_account_limits_view, methods=[HTTPMethod.GET.value])
|
|
1060
|
+
bp.add_url_rule('/<account>/limits/<rse>', view_func=local_account_limits_view, methods=[HTTPMethod.GET.value])
|
|
1060
1061
|
global_account_limits_view = GlobalAccountLimits.as_view('global_account_limit')
|
|
1061
|
-
bp.add_url_rule('/<account>/limits/global', view_func=global_account_limits_view, methods=[
|
|
1062
|
-
bp.add_url_rule('/<account>/limits/global/<rse_expression>', view_func=global_account_limits_view, methods=[
|
|
1062
|
+
bp.add_url_rule('/<account>/limits/global', view_func=global_account_limits_view, methods=[HTTPMethod.GET.value])
|
|
1063
|
+
bp.add_url_rule('/<account>/limits/global/<rse_expression>', view_func=global_account_limits_view, methods=[HTTPMethod.GET.value])
|
|
1063
1064
|
identities_view = Identities.as_view('identities')
|
|
1064
|
-
bp.add_url_rule('/<account>/identities', view_func=identities_view, methods=[
|
|
1065
|
+
bp.add_url_rule('/<account>/identities', view_func=identities_view, methods=[HTTPMethod.GET.value, HTTPMethod.POST.value, HTTPMethod.DELETE.value])
|
|
1065
1066
|
rules_view = Rules.as_view('rules')
|
|
1066
|
-
bp.add_url_rule('/<account>/rules', view_func=rules_view, methods=[
|
|
1067
|
+
bp.add_url_rule('/<account>/rules', view_func=rules_view, methods=[HTTPMethod.GET.value])
|
|
1067
1068
|
usagehistory_view = UsageHistory.as_view('usagehistory')
|
|
1068
|
-
bp.add_url_rule('/<account>/usage/history/<rse>', view_func=usagehistory_view, methods=[
|
|
1069
|
+
bp.add_url_rule('/<account>/usage/history/<rse>', view_func=usagehistory_view, methods=[HTTPMethod.GET.value])
|
|
1069
1070
|
usage_view = LocalUsage.as_view('usage')
|
|
1070
|
-
bp.add_url_rule('/<account>/usage/local', view_func=usage_view, methods=[
|
|
1071
|
-
bp.add_url_rule('/<account>/usage', view_func=usage_view, methods=[
|
|
1071
|
+
bp.add_url_rule('/<account>/usage/local', view_func=usage_view, methods=[HTTPMethod.GET.value])
|
|
1072
|
+
bp.add_url_rule('/<account>/usage', view_func=usage_view, methods=[HTTPMethod.GET.value])
|
|
1072
1073
|
if not with_doc:
|
|
1073
1074
|
# for backwards-compatibility
|
|
1074
1075
|
# rule without trailing slash needs to be added before rule with trailing slash
|
|
1075
|
-
bp.add_url_rule('/<account>/usage/', view_func=usage_view, methods=[
|
|
1076
|
-
bp.add_url_rule('/<account>/usage/local/<rse>', view_func=usage_view, methods=[
|
|
1077
|
-
bp.add_url_rule('/<account>/usage/<rse>', view_func=usage_view, methods=[
|
|
1076
|
+
bp.add_url_rule('/<account>/usage/', view_func=usage_view, methods=[HTTPMethod.GET.value])
|
|
1077
|
+
bp.add_url_rule('/<account>/usage/local/<rse>', view_func=usage_view, methods=[HTTPMethod.GET.value])
|
|
1078
|
+
bp.add_url_rule('/<account>/usage/<rse>', view_func=usage_view, methods=[HTTPMethod.GET.value])
|
|
1078
1079
|
global_usage_view = GlobalUsage.as_view('global_usage')
|
|
1079
|
-
bp.add_url_rule('/<account>/usage/global', view_func=global_usage_view, methods=[
|
|
1080
|
-
bp.add_url_rule('/<account>/usage/global/<rse_expression>', view_func=global_usage_view, methods=[
|
|
1080
|
+
bp.add_url_rule('/<account>/usage/global', view_func=global_usage_view, methods=[HTTPMethod.GET.value])
|
|
1081
|
+
bp.add_url_rule('/<account>/usage/global/<rse_expression>', view_func=global_usage_view, methods=[HTTPMethod.GET.value])
|
|
1081
1082
|
account_parameter_view = AccountParameter.as_view('account_parameter')
|
|
1082
|
-
bp.add_url_rule('/<account>', view_func=account_parameter_view, methods=[
|
|
1083
|
+
bp.add_url_rule('/<account>', view_func=account_parameter_view, methods=[HTTPMethod.GET.value, HTTPMethod.PUT.value, HTTPMethod.POST.value, HTTPMethod.DELETE.value])
|
|
1083
1084
|
account_view = Account.as_view('account')
|
|
1084
1085
|
if not with_doc:
|
|
1085
1086
|
# rule without trailing slash needs to be added before rule with trailing slash
|
|
1086
|
-
bp.add_url_rule('', view_func=account_view, methods=[
|
|
1087
|
-
bp.add_url_rule('/', view_func=account_view, methods=[
|
|
1087
|
+
bp.add_url_rule('', view_func=account_view, methods=[HTTPMethod.GET.value])
|
|
1088
|
+
bp.add_url_rule('/', view_func=account_view, methods=[HTTPMethod.GET.value])
|
|
1088
1089
|
|
|
1089
1090
|
bp.after_request(response_headers)
|
|
1090
1091
|
return bp
|
|
@@ -17,7 +17,7 @@ from typing import TYPE_CHECKING
|
|
|
17
17
|
|
|
18
18
|
from flask import Flask, Response, request
|
|
19
19
|
|
|
20
|
-
from rucio.common.constants import DEFAULT_VO
|
|
20
|
+
from rucio.common.constants import DEFAULT_VO, HTTPMethod
|
|
21
21
|
from rucio.gateway.did import list_archive_content
|
|
22
22
|
from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
|
|
23
23
|
from rucio.web.rest.flaskapi.v1.common import ErrorHandlingMethodView, check_accept_header_wrapper_flask, generate_http_error_flask, parse_scope_name, response_headers, try_stream
|
|
@@ -90,7 +90,7 @@ def blueprint() -> AuthenticatedBlueprint:
|
|
|
90
90
|
bp = AuthenticatedBlueprint('archives', __name__, url_prefix='/archives')
|
|
91
91
|
|
|
92
92
|
archive_view = Archive.as_view('archive')
|
|
93
|
-
bp.add_url_rule('/<path:scope_name>/files', view_func=archive_view, methods=[
|
|
93
|
+
bp.add_url_rule('/<path:scope_name>/files', view_func=archive_view, methods=[HTTPMethod.GET.value])
|
|
94
94
|
|
|
95
95
|
bp.after_request(response_headers)
|
|
96
96
|
return bp
|
|
@@ -23,6 +23,7 @@ from jinja2.exceptions import TemplateNotFound
|
|
|
23
23
|
from werkzeug.datastructures import Headers
|
|
24
24
|
|
|
25
25
|
from rucio.common.config import config_get
|
|
26
|
+
from rucio.common.constants import HTTPMethod
|
|
26
27
|
from rucio.common.exception import AccessDenied, CannotAuthenticate, CannotAuthorize, ConfigurationError, IdentityError, IdentityNotFound, InvalidRequest
|
|
27
28
|
from rucio.common.extra import import_extras
|
|
28
29
|
from rucio.common.utils import date_to_str
|
|
@@ -1632,31 +1633,31 @@ def blueprint() -> Blueprint:
|
|
|
1632
1633
|
bp = Blueprint('auth', __name__, url_prefix='/auth')
|
|
1633
1634
|
|
|
1634
1635
|
user_pass_view = UserPass.as_view('user_pass')
|
|
1635
|
-
bp.add_url_rule('/userpass', view_func=user_pass_view, methods=[
|
|
1636
|
+
bp.add_url_rule('/userpass', view_func=user_pass_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1636
1637
|
gss_view = GSS.as_view('gss')
|
|
1637
|
-
bp.add_url_rule('/gss', view_func=gss_view, methods=[
|
|
1638
|
+
bp.add_url_rule('/gss', view_func=gss_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1638
1639
|
x509_view = x509.as_view('x509')
|
|
1639
|
-
bp.add_url_rule('/x509', view_func=x509_view, methods=[
|
|
1640
|
-
bp.add_url_rule('/x509/webui', view_func=x509_view, methods=[
|
|
1641
|
-
bp.add_url_rule('/x509_proxy', view_func=x509_view, methods=[
|
|
1640
|
+
bp.add_url_rule('/x509', view_func=x509_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1641
|
+
bp.add_url_rule('/x509/webui', view_func=x509_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1642
|
+
bp.add_url_rule('/x509_proxy', view_func=x509_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1642
1643
|
ssh_view = SSH.as_view('ssh')
|
|
1643
|
-
bp.add_url_rule('/ssh', view_func=ssh_view, methods=[
|
|
1644
|
+
bp.add_url_rule('/ssh', view_func=ssh_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1644
1645
|
ssh_challenge_token_view = SSHChallengeToken.as_view('ssh_challenge_token')
|
|
1645
|
-
bp.add_url_rule('/ssh_challenge_token', view_func=ssh_challenge_token_view, methods=[
|
|
1646
|
+
bp.add_url_rule('/ssh_challenge_token', view_func=ssh_challenge_token_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1646
1647
|
saml_view = SAML.as_view('saml')
|
|
1647
|
-
bp.add_url_rule('/saml', view_func=saml_view, methods=[
|
|
1648
|
+
bp.add_url_rule('/saml', view_func=saml_view, methods=[HTTPMethod.GET.value, HTTPMethod.POST.value, HTTPMethod.OPTIONS.value])
|
|
1648
1649
|
validate_view = Validate.as_view('validate')
|
|
1649
|
-
bp.add_url_rule('/validate', view_func=validate_view, methods=[
|
|
1650
|
+
bp.add_url_rule('/validate', view_func=validate_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1650
1651
|
oidc_view = OIDC.as_view('oidc_view')
|
|
1651
|
-
bp.add_url_rule('/oidc', view_func=oidc_view, methods=[
|
|
1652
|
+
bp.add_url_rule('/oidc', view_func=oidc_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1652
1653
|
token_oidc_view = TokenOIDC.as_view('token_oidc_view')
|
|
1653
|
-
bp.add_url_rule('/oidc_token', view_func=token_oidc_view, methods=[
|
|
1654
|
+
bp.add_url_rule('/oidc_token', view_func=token_oidc_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1654
1655
|
code_oidc_view = CodeOIDC.as_view('code_oidc_view')
|
|
1655
|
-
bp.add_url_rule('/oidc_code', view_func=code_oidc_view, methods=[
|
|
1656
|
+
bp.add_url_rule('/oidc_code', view_func=code_oidc_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1656
1657
|
redirect_oidc_view = RedirectOIDC.as_view('redirect_oidc_view')
|
|
1657
|
-
bp.add_url_rule('/oidc_redirect', view_func=redirect_oidc_view, methods=[
|
|
1658
|
+
bp.add_url_rule('/oidc_redirect', view_func=redirect_oidc_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1658
1659
|
refresh_oidc_view = RefreshOIDC.as_view('refresh_oidc_view')
|
|
1659
|
-
bp.add_url_rule('/oidc_refresh', view_func=refresh_oidc_view, methods=[
|
|
1660
|
+
bp.add_url_rule('/oidc_refresh', view_func=refresh_oidc_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
1660
1661
|
|
|
1661
1662
|
return bp
|
|
1662
1663
|
|
|
@@ -31,7 +31,7 @@ from werkzeug.exceptions import HTTPException
|
|
|
31
31
|
from werkzeug.wrappers import Request, Response
|
|
32
32
|
|
|
33
33
|
from rucio.common import config
|
|
34
|
-
from rucio.common.constants import DEFAULT_VO
|
|
34
|
+
from rucio.common.constants import DEFAULT_VO, HTTPMethod
|
|
35
35
|
from rucio.common.exception import CannotAuthenticate, DatabaseException, IdentityError, RucioException, UnsupportedRequestedContentType
|
|
36
36
|
from rucio.common.schema import get_schema_value
|
|
37
37
|
from rucio.common.utils import generate_uuid, render_json
|
|
@@ -66,7 +66,7 @@ class CORSMiddleware:
|
|
|
66
66
|
def __call__(self, environ: 'WSGIEnvironment', start_response: 'StartResponse') -> 'Iterable[bytes]':
|
|
67
67
|
request: Request = Request(environ)
|
|
68
68
|
|
|
69
|
-
if request.environ.get('REQUEST_METHOD') ==
|
|
69
|
+
if request.environ.get('REQUEST_METHOD') == HTTPMethod.OPTIONS.value:
|
|
70
70
|
try:
|
|
71
71
|
webui_urls = config.config_get_list('webui', 'urls')
|
|
72
72
|
except (NoOptionError, NoSectionError, RuntimeError) as error:
|
|
@@ -145,7 +145,7 @@ class ErrorHandlingMethodView(MethodView):
|
|
|
145
145
|
|
|
146
146
|
|
|
147
147
|
def request_auth_env() -> Optional['ResponseReturnValue']:
|
|
148
|
-
if flask.request.environ.get('REQUEST_METHOD') ==
|
|
148
|
+
if flask.request.environ.get('REQUEST_METHOD') == HTTPMethod.OPTIONS.value:
|
|
149
149
|
return '', 200
|
|
150
150
|
|
|
151
151
|
auth_token = flask.request.headers.get('X-Rucio-Auth-Token', default=None)
|
|
@@ -176,7 +176,7 @@ def response_headers(response: ResponseTypeVar) -> ResponseTypeVar:
|
|
|
176
176
|
response.headers['Access-Control-Allow-Methods'] = '*'
|
|
177
177
|
response.headers['Access-Control-Allow-Credentials'] = 'true'
|
|
178
178
|
|
|
179
|
-
if flask.request.environ.get('REQUEST_METHOD') ==
|
|
179
|
+
if flask.request.environ.get('REQUEST_METHOD') == HTTPMethod.GET.value:
|
|
180
180
|
response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
|
|
181
181
|
response.headers['Cache-Control'] = 'post-check=0, pre-check=0'
|
|
182
182
|
response.headers['Pragma'] = 'no-cache'
|
|
@@ -17,6 +17,7 @@ from typing import TYPE_CHECKING
|
|
|
17
17
|
from flask import Flask, jsonify
|
|
18
18
|
from flask import request as request
|
|
19
19
|
|
|
20
|
+
from rucio.common.constants import HTTPMethod
|
|
20
21
|
from rucio.common.exception import AccessDenied, ConfigNotFound, ConfigurationError
|
|
21
22
|
from rucio.gateway import config
|
|
22
23
|
from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
|
|
@@ -323,13 +324,14 @@ def blueprint() -> AuthenticatedBlueprint:
|
|
|
323
324
|
bp = AuthenticatedBlueprint('config', __name__, url_prefix='/config')
|
|
324
325
|
|
|
325
326
|
option_set_view = OptionSet.as_view('option_set')
|
|
326
|
-
bp.add_url_rule('/<section>/<option>/<value>', view_func=option_set_view, methods=[
|
|
327
|
+
bp.add_url_rule('/<section>/<option>/<value>', view_func=option_set_view, methods=[HTTPMethod.PUT.value])
|
|
327
328
|
option_get_del_view = OptionGetDel.as_view('option_get_del')
|
|
328
|
-
bp.add_url_rule('/<section>/<option>', view_func=option_get_del_view, methods=[
|
|
329
|
+
bp.add_url_rule('/<section>/<option>', view_func=option_get_del_view, methods=[HTTPMethod.GET.value, HTTPMethod.DELETE.value])
|
|
329
330
|
section_view = Section.as_view('section')
|
|
330
|
-
|
|
331
|
+
|
|
332
|
+
bp.add_url_rule('/<section>', view_func=section_view, methods=[HTTPMethod.GET.value, HTTPMethod.DELETE.value])
|
|
331
333
|
config_view = Config.as_view('config')
|
|
332
|
-
bp.add_url_rule('', view_func=config_view, methods=[
|
|
334
|
+
bp.add_url_rule('', view_func=config_view, methods=[HTTPMethod.GET.value, HTTPMethod.POST.value])
|
|
333
335
|
|
|
334
336
|
bp.after_request(response_headers)
|
|
335
337
|
return bp
|
|
@@ -17,7 +17,7 @@ from typing import TYPE_CHECKING, cast
|
|
|
17
17
|
from flask import Flask, request
|
|
18
18
|
from werkzeug.datastructures import Headers
|
|
19
19
|
|
|
20
|
-
from rucio.common.constants import RSE_BASE_SUPPORTED_PROTOCOL_OPERATIONS, RSE_BASE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL, SUPPORTED_SIGN_URL_SERVICES, SUPPORTED_SIGN_URL_SERVICES_LITERAL
|
|
20
|
+
from rucio.common.constants import RSE_BASE_SUPPORTED_PROTOCOL_OPERATIONS, RSE_BASE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL, SUPPORTED_SIGN_URL_SERVICES, SUPPORTED_SIGN_URL_SERVICES_LITERAL, HTTPMethod
|
|
21
21
|
from rucio.common.exception import CannotAuthenticate
|
|
22
22
|
from rucio.gateway.credential import get_signed_url
|
|
23
23
|
from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
|
|
@@ -203,10 +203,10 @@ def blueprint(with_doc=False):
|
|
|
203
203
|
bp = AuthenticatedBlueprint('credentials', __name__, url_prefix='/credentials')
|
|
204
204
|
|
|
205
205
|
signurl_view = SignURL.as_view('signurl')
|
|
206
|
-
bp.add_url_rule('/signurl', view_func=signurl_view, methods=[
|
|
206
|
+
bp.add_url_rule('/signurl', view_func=signurl_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
207
207
|
if not with_doc:
|
|
208
208
|
# yes, /signur ~= '/signurl?$'
|
|
209
|
-
bp.add_url_rule('/signur', view_func=signurl_view, methods=[
|
|
209
|
+
bp.add_url_rule('/signur', view_func=signurl_view, methods=[HTTPMethod.GET.value, HTTPMethod.OPTIONS.value])
|
|
210
210
|
|
|
211
211
|
bp.after_request(response_headers)
|
|
212
212
|
|