Ruff the code

Switch from black to ruff similarly to keystoneauth.

Change-Id: Ieee72e8598ae182d9f6cc40d7f4c20e955a69b2d
This commit is contained in:
Artem Goncharov 2024-10-09 16:31:25 +02:00
parent f7ffacb7ad
commit ae7b3a0534
295 changed files with 3137 additions and 5394 deletions

View File

@ -22,16 +22,12 @@ repos:
# rev: v1.1.1 # rev: v1.1.1
# hooks: # hooks:
# - id: doc8 # - id: doc8
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v3.15.2 rev: v0.6.9
hooks: hooks:
- id: pyupgrade - id: ruff
args: ['--py38-plus'] args: ['--fix', '--unsafe-fixes']
- repo: https://github.com/psf/black - id: ruff-format
rev: 24.4.0
hooks:
- id: black
args: ['-S', '-l', '79']
- repo: https://github.com/PyCQA/bandit - repo: https://github.com/PyCQA/bandit
rev: '1.7.9' rev: '1.7.9'
hooks: hooks:

View File

@ -23,15 +23,9 @@
# serve to show the default. # serve to show the default.
html_theme = 'openstackdocs' html_theme = 'openstackdocs'
html_theme_options = { html_theme_options = {"sidebar_dropdown": "api_ref", "sidebar_mode": "toc"}
"sidebar_dropdown": "api_ref",
"sidebar_mode": "toc",
}
extensions = [ extensions = ['os_api_ref', 'openstackdocstheme']
'os_api_ref',
'openstackdocstheme',
]
# If extensions (or modules to document with autodoc) are in another directory, # If extensions (or modules to document with autodoc) are in another directory,

View File

@ -29,7 +29,7 @@ class KeycloakClient:
} }
r = requests.post(self.token_endpoint(realm), data=params).json() r = requests.post(self.token_endpoint(realm), data=params).json()
headers = { headers = {
'Authorization': ("Bearer %s" % r['access_token']), 'Authorization': f"Bearer {r['access_token']}",
'Content-Type': 'application/json', 'Content-Type': 'application/json',
} }
self.session.headers.update(headers) self.session.headers.update(headers)

View File

@ -285,7 +285,7 @@ texinfo_documents = [
'keystone', 'keystone',
'One line description of project.', 'One line description of project.',
'Miscellaneous', 'Miscellaneous',
), )
] ]
# Documents to append as an appendix to all manuals. # Documents to append as an appendix to all manuals.

View File

@ -110,15 +110,15 @@ class ResourceBase(ks_flask.ResourceBase):
loaded = cred['blob'] loaded = cred['blob']
# Convert to the legacy format # Convert to the legacy format
cred_data = dict( cred_data = {
user_id=cred.get('user_id'), 'user_id': cred.get('user_id'),
project_id=cred.get('project_id'), 'project_id': cred.get('project_id'),
access=loaded.get('access'), 'access': loaded.get('access'),
secret=loaded.get('secret'), 'secret': loaded.get('secret'),
trust_id=loaded.get('trust_id'), 'trust_id': loaded.get('trust_id'),
app_cred_id=loaded.get('app_cred_id'), 'app_cred_id': loaded.get('app_cred_id'),
access_token_id=loaded.get('access_token_id'), 'access_token_id': loaded.get('access_token_id'),
) }
# validate the signature # validate the signature
self._check_signature(cred_data, credentials) self._check_signature(cred_data, credentials)

View File

@ -24,7 +24,7 @@ PROVIDERS = provider_api.ProviderAPIs
def build_prior_role_response_data(prior_role_id, prior_role_name): def build_prior_role_response_data(prior_role_id, prior_role_name):
return { return {
'id': prior_role_id, 'id': prior_role_id,
'links': {'self': ks_flask.base_url(path='/roles/%s' % prior_role_id)}, 'links': {'self': ks_flask.base_url(path=f'/roles/{prior_role_id}')},
'name': prior_role_name, 'name': prior_role_name,
} }
@ -33,7 +33,9 @@ def build_implied_role_response_data(implied_role):
return { return {
'id': implied_role['id'], 'id': implied_role['id'],
'links': { 'links': {
'self': ks_flask.base_url(path='/roles/%s' % implied_role['id']) 'self': ks_flask.base_url(
path='/roles/{}'.format(implied_role['id'])
)
}, },
'name': implied_role['name'], 'name': implied_role['name'],
} }

View File

@ -466,15 +466,15 @@ class AuthAPI(ks_flask.APIBase):
resource=AuthProjectsResource, resource=AuthProjectsResource,
url='/auth/projects', url='/auth/projects',
alternate_urls=[ alternate_urls=[
dict( {
url='/OS-FEDERATION/projects', 'url': '/OS-FEDERATION/projects',
json_home=ks_flask.construct_json_home_data( 'json_home': ks_flask.construct_json_home_data(
rel='projects', rel='projects',
resource_relation_func=( resource_relation_func=(
json_home_relations.os_federation_resource_rel_func json_home_relations.os_federation_resource_rel_func
), ),
), ),
) }
], ],
rel='auth_projects', rel='auth_projects',
resource_kwargs={}, resource_kwargs={},
@ -483,15 +483,15 @@ class AuthAPI(ks_flask.APIBase):
resource=AuthDomainsResource, resource=AuthDomainsResource,
url='/auth/domains', url='/auth/domains',
alternate_urls=[ alternate_urls=[
dict( {
url='/OS-FEDERATION/domains', 'url': '/OS-FEDERATION/domains',
json_home=ks_flask.construct_json_home_data( 'json_home': ks_flask.construct_json_home_data(
rel='domains', rel='domains',
resource_relation_func=( resource_relation_func=(
json_home_relations.os_federation_resource_rel_func json_home_relations.os_federation_resource_rel_func
), ),
), ),
) }
], ],
rel='auth_domains', rel='auth_domains',
resource_kwargs={}, resource_kwargs={},
@ -590,7 +590,4 @@ class AuthFederationAPI(ks_flask.APIBase):
] ]
APIs = ( APIs = (AuthAPI, AuthFederationAPI)
AuthAPI,
AuthFederationAPI,
)

View File

@ -286,7 +286,6 @@ class CredentialResource(ks_flask.ResourceBase):
class CredentialAPI(ks_flask.APIBase): class CredentialAPI(ks_flask.APIBase):
_name = 'credentials' _name = 'credentials'
_import_name = __name__ _import_name = __name__
resource_mapping = [ resource_mapping = [

View File

@ -31,12 +31,7 @@ def _get_versions_list(identity_url):
'id': 'v3.14', 'id': 'v3.14',
'status': 'stable', 'status': 'stable',
'updated': '2020-04-07T00:00:00Z', 'updated': '2020-04-07T00:00:00Z',
'links': [ 'links': [{'rel': 'self', 'href': identity_url}],
{
'rel': 'self',
'href': identity_url,
}
],
'media-types': [ 'media-types': [
{'base': 'application/json', 'type': MEDIA_TYPE_JSON % 'v3'} {'base': 'application/json', 'type': MEDIA_TYPE_JSON % 'v3'}
], ],
@ -70,7 +65,7 @@ def get_versions():
mimetype=MimeTypes.JSON_HOME, mimetype=MimeTypes.JSON_HOME,
) )
else: else:
identity_url = '%s/' % ks_flask.base_url() identity_url = f'{ks_flask.base_url()}/'
versions = _get_versions_list(identity_url) versions = _get_versions_list(identity_url)
# Set the preferred version to the latest "stable" version. # Set the preferred version to the latest "stable" version.
# TODO(morgan): If we ever have more API versions find the latest # TODO(morgan): If we ever have more API versions find the latest
@ -99,7 +94,7 @@ def get_version_v3():
response=jsonutils.dumps(content), mimetype=MimeTypes.JSON_HOME response=jsonutils.dumps(content), mimetype=MimeTypes.JSON_HOME
) )
else: else:
identity_url = '%s/' % ks_flask.base_url() identity_url = f'{ks_flask.base_url()}/'
versions = _get_versions_list(identity_url) versions = _get_versions_list(identity_url)
return flask.Response( return flask.Response(
response=jsonutils.dumps({'version': versions['v3']}), response=jsonutils.dumps({'version': versions['v3']}),

View File

@ -67,7 +67,7 @@ class EndpointResource(ks_flask.ResourceBase):
try: try:
PROVIDERS.catalog_api.get_region(endpoint['region_id']) PROVIDERS.catalog_api.get_region(endpoint['region_id'])
except exception.RegionNotFound: except exception.RegionNotFound:
region = dict(id=endpoint['region_id']) region = {'id': endpoint['region_id']}
PROVIDERS.catalog_api.create_region( PROVIDERS.catalog_api.create_region(
region, initiator=notifications.build_audit_initiator() region, initiator=notifications.build_audit_initiator()
) )

View File

@ -235,12 +235,11 @@ class EPFilterGroupsProjectsResource(ks_flask.ResourceBase):
@classmethod @classmethod
def _add_self_referential_link(cls, ref, collection_name=None): def _add_self_referential_link(cls, ref, collection_name=None):
url = ( url = (
'/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' '/OS-EP-FILTER/endpoint_groups/{endpoint_group_id}'
'/projects/%(project_id)s' '/projects/{project_id}'.format(
% { endpoint_group_id=ref['endpoint_group_id'],
'endpoint_group_id': ref['endpoint_group_id'], project_id=ref['project_id'],
'project_id': ref['project_id'], )
}
) )
ref.setdefault('links', {}) ref.setdefault('links', {})
ref['links']['self'] = url ref['links']['self'] = url

View File

@ -99,7 +99,9 @@ class IdentityProvidersResource(_ResourceBase):
""" """
base_path = ref['links'].get('self') base_path = ref['links'].get('self')
if base_path is None: if base_path is None:
base_path = '/'.join(ks_flask.base_url(path='/%s' % ref['id'])) base_path = '/'.join(
ks_flask.base_url(path='/{}'.format(ref['id']))
)
for name in ['protocols']: for name in ['protocols']:
ref['links'][name] = '/'.join([base_path, name]) ref['links'][name] = '/'.join([base_path, name])
@ -188,7 +190,6 @@ class _IdentityProvidersProtocolsResourceBase(_ResourceBase):
class IDPProtocolsListResource(_IdentityProvidersProtocolsResourceBase): class IDPProtocolsListResource(_IdentityProvidersProtocolsResourceBase):
def get(self, idp_id): def get(self, idp_id):
"""List protocols for an IDP. """List protocols for an IDP.
@ -205,7 +206,6 @@ class IDPProtocolsListResource(_IdentityProvidersProtocolsResourceBase):
class IDPProtocolsCRUDResource(_IdentityProvidersProtocolsResourceBase): class IDPProtocolsCRUDResource(_IdentityProvidersProtocolsResourceBase):
def get(self, idp_id, protocol_id): def get(self, idp_id, protocol_id):
"""Get protocols for an IDP. """Get protocols for an IDP.
@ -448,7 +448,6 @@ class SAML2MetadataResource(flask_restful.Resource):
class OSFederationAuthResource(flask_restful.Resource): class OSFederationAuthResource(flask_restful.Resource):
@ks_flask.unenforced_api @ks_flask.unenforced_api
def get(self, idp_id, protocol_id): def get(self, idp_id, protocol_id):
"""Authenticate from dedicated uri endpoint. """Authenticate from dedicated uri endpoint.

View File

@ -117,10 +117,10 @@ class ConsumerResource(ks_flask.ResourceBase):
def delete(self, consumer_id): def delete(self, consumer_id):
ENFORCER.enforce_call(action='identity:delete_consumer') ENFORCER.enforce_call(action='identity:delete_consumer')
reason = ( reason = (
'Invalidating token cache because consumer %(consumer_id)s has ' f'Invalidating token cache because consumer {consumer_id} has '
'been deleted. Authorization for users with OAuth tokens will be ' 'been deleted. Authorization for users with OAuth tokens will be '
'recalculated and enforced accordingly the next time they ' 'recalculated and enforced accordingly the next time they '
'authenticate or validate a token.' % {'consumer_id': consumer_id} 'authenticate or validate a token.'
) )
notifications.invalidate_token_cache_notification(reason) notifications.invalidate_token_cache_notification(reason)
PROVIDERS.oauth_api.delete_consumer( PROVIDERS.oauth_api.delete_consumer(
@ -191,12 +191,11 @@ class RequestTokenResource(_OAuth1ResourceBase):
) )
result = 'oauth_token={key}&oauth_token_secret={secret}'.format( result = 'oauth_token={key}&oauth_token_secret={secret}'.format(
key=token_ref['id'], key=token_ref['id'], secret=token_ref['request_secret']
secret=token_ref['request_secret'],
) )
if CONF.oauth1.request_token_duration > 0: if CONF.oauth1.request_token_duration > 0:
expiry_bit = '&oauth_expires_at=%s' % token_ref['expires_at'] expiry_bit = '&oauth_expires_at={}'.format(token_ref['expires_at'])
result += expiry_bit result += expiry_bit
resp = flask.make_response(result, http.client.CREATED) resp = flask.make_response(result, http.client.CREATED)
@ -294,12 +293,11 @@ class AccessTokenResource(_OAuth1ResourceBase):
) )
result = 'oauth_token={key}&oauth_token_secret={secret}'.format( result = 'oauth_token={key}&oauth_token_secret={secret}'.format(
key=token_ref['id'], key=token_ref['id'], secret=token_ref['access_secret']
secret=token_ref['access_secret'],
) )
if CONF.oauth1.access_token_duration > 0: if CONF.oauth1.access_token_duration > 0:
expiry_bit = '&oauth_expires_at=%s' % (token_ref['expires_at']) expiry_bit = '&oauth_expires_at={}'.format(token_ref['expires_at'])
result += expiry_bit result += expiry_bit
resp = flask.make_response(result, http.client.CREATED) resp = flask.make_response(result, http.client.CREATED)

View File

@ -37,7 +37,6 @@ _build_resource_relation = json_home_relations.os_oauth2_resource_rel_func
class AccessTokenResource(ks_flask.ResourceBase): class AccessTokenResource(ks_flask.ResourceBase):
def _method_not_allowed(self): def _method_not_allowed(self):
"""Raise a method not allowed error.""" """Raise a method not allowed error."""
raise exception.OAuth2OtherError( raise exception.OAuth2OtherError(
@ -361,11 +360,11 @@ class AccessTokenResource(ks_flask.ResourceBase):
raise error raise error
client_cert_dn = {} client_cert_dn = {}
for key in cert_subject_dn: for key in cert_subject_dn:
client_cert_dn['SSL_CLIENT_SUBJECT_DN_%s' % key.upper()] = ( client_cert_dn[f'SSL_CLIENT_SUBJECT_DN_{key.upper()}'] = (
cert_subject_dn.get(key) cert_subject_dn.get(key)
) )
for key in cert_issuer_dn: for key in cert_issuer_dn:
client_cert_dn['SSL_CLIENT_ISSUER_DN_%s' % key.upper()] = ( client_cert_dn[f'SSL_CLIENT_ISSUER_DN_{key.upper()}'] = (
cert_issuer_dn.get(key) cert_issuer_dn.get(key)
) )

View File

@ -102,7 +102,6 @@ class PolicyResource(ks_flask.ResourceBase):
class EndpointPolicyResource(flask_restful.Resource): class EndpointPolicyResource(flask_restful.Resource):
def get(self, policy_id): def get(self, policy_id):
ENFORCER.enforce_call(action='identity:list_endpoints_for_policy') ENFORCER.enforce_call(action='identity:list_endpoints_for_policy')
PROVIDERS.policy_api.get_policy(policy_id) PROVIDERS.policy_api.get_policy(policy_id)
@ -120,7 +119,6 @@ class EndpointPolicyResource(flask_restful.Resource):
class EndpointPolicyAssociations(flask_restful.Resource): class EndpointPolicyAssociations(flask_restful.Resource):
def get(self, policy_id, endpoint_id): def get(self, policy_id, endpoint_id):
action = 'identity:check_policy_association_for_endpoint' action = 'identity:check_policy_association_for_endpoint'
ENFORCER.enforce_call(action=action) ENFORCER.enforce_call(action=action)
@ -153,7 +151,6 @@ class EndpointPolicyAssociations(flask_restful.Resource):
class ServicePolicyAssociations(flask_restful.Resource): class ServicePolicyAssociations(flask_restful.Resource):
def get(self, policy_id, service_id): def get(self, policy_id, service_id):
action = 'identity:check_policy_association_for_service' action = 'identity:check_policy_association_for_service'
ENFORCER.enforce_call(action=action) ENFORCER.enforce_call(action=action)
@ -186,7 +183,6 @@ class ServicePolicyAssociations(flask_restful.Resource):
class ServiceRegionPolicyAssociations(flask_restful.Resource): class ServiceRegionPolicyAssociations(flask_restful.Resource):
def get(self, policy_id, service_id, region_id): def get(self, policy_id, service_id, region_id):
action = 'identity:check_policy_association_for_region_and_service' action = 'identity:check_policy_association_for_region_and_service'
ENFORCER.enforce_call(action=action) ENFORCER.enforce_call(action=action)

View File

@ -315,16 +315,16 @@ class RoleAssignmentsResource(ks_flask.ResourceBase):
if 'domain_id' in entity.get('indirect', {}): if 'domain_id' in entity.get('indirect', {}):
inherited_assignment = True inherited_assignment = True
formatted_link = ( formatted_link = '/domains/{}'.format(
'/domains/%s' % entity['indirect']['domain_id'] entity['indirect']['domain_id']
) )
elif 'project_id' in entity.get('indirect', {}): elif 'project_id' in entity.get('indirect', {}):
inherited_assignment = True inherited_assignment = True
formatted_link = ( formatted_link = '/projects/{}'.format(
'/projects/%s' % entity['indirect']['project_id'] entity['indirect']['project_id']
) )
else: else:
formatted_link = '/projects/%s' % entity['project_id'] formatted_link = '/projects/{}'.format(entity['project_id'])
elif 'domain_id' in entity: elif 'domain_id' in entity:
if 'domain_name' in entity: if 'domain_name' in entity:
formatted_entity['scope'] = { formatted_entity['scope'] = {
@ -337,7 +337,7 @@ class RoleAssignmentsResource(ks_flask.ResourceBase):
formatted_entity['scope'] = { formatted_entity['scope'] = {
'domain': {'id': entity['domain_id']} 'domain': {'id': entity['domain_id']}
} }
formatted_link = '/domains/%s' % entity['domain_id'] formatted_link = '/domains/{}'.format(entity['domain_id'])
elif 'system' in entity: elif 'system' in entity:
formatted_link = '/system' formatted_link = '/system'
formatted_entity['scope'] = {'system': entity['system']} formatted_entity['scope'] = {'system': entity['system']}
@ -356,13 +356,16 @@ class RoleAssignmentsResource(ks_flask.ResourceBase):
formatted_entity['user'] = {'id': entity['user_id']} formatted_entity['user'] = {'id': entity['user_id']}
if 'group_id' in entity.get('indirect', {}): if 'group_id' in entity.get('indirect', {}):
membership_url = ks_flask.base_url( membership_url = ks_flask.base_url(
path='/groups/%s/users/%s' path='/groups/{}/users/{}'.format(
% (entity['indirect']['group_id'], entity['user_id']) entity['indirect']['group_id'], entity['user_id']
)
) )
formatted_entity['links']['membership'] = membership_url formatted_entity['links']['membership'] = membership_url
formatted_link += '/groups/%s' % entity['indirect']['group_id'] formatted_link += '/groups/{}'.format(
entity['indirect']['group_id']
)
else: else:
formatted_link += '/users/%s' % entity['user_id'] formatted_link += '/users/{}'.format(entity['user_id'])
elif 'group_id' in entity: elif 'group_id' in entity:
if 'group_name' in entity: if 'group_name' in entity:
formatted_entity['group'] = { formatted_entity['group'] = {
@ -375,7 +378,7 @@ class RoleAssignmentsResource(ks_flask.ResourceBase):
} }
else: else:
formatted_entity['group'] = {'id': entity['group_id']} formatted_entity['group'] = {'id': entity['group_id']}
formatted_link += '/groups/%s' % entity['group_id'] formatted_link += '/groups/{}'.format(entity['group_id'])
if 'role_name' in entity: if 'role_name' in entity:
formatted_entity['role'] = { formatted_entity['role'] = {
@ -395,18 +398,17 @@ class RoleAssignmentsResource(ks_flask.ResourceBase):
formatted_entity['role'] = {'id': entity['role_id']} formatted_entity['role'] = {'id': entity['role_id']}
prior_role_link = '' prior_role_link = ''
if 'role_id' in entity.get('indirect', {}): if 'role_id' in entity.get('indirect', {}):
formatted_link += '/roles/%s' % entity['indirect']['role_id'] formatted_link += '/roles/{}'.format(entity['indirect']['role_id'])
prior_role_link = '/prior_role/{prior}/implies/{implied}'.format( prior_role_link = '/prior_role/{prior}/implies/{implied}'.format(
prior=entity['role_id'], prior=entity['role_id'], implied=entity['indirect']['role_id']
implied=entity['indirect']['role_id'],
) )
else: else:
formatted_link += '/roles/%s' % entity['role_id'] formatted_link += '/roles/{}'.format(entity['role_id'])
if inherited_assignment: if inherited_assignment:
formatted_entity['scope']['OS-INHERIT:inherited_to'] = 'projects' formatted_entity['scope']['OS-INHERIT:inherited_to'] = 'projects'
formatted_link = ( formatted_link = (
'/OS-INHERIT%s/inherited_to_projects' % formatted_link f'/OS-INHERIT{formatted_link}/inherited_to_projects'
) )
formatted_entity['links']['assignment'] = ks_flask.base_url( formatted_entity['links']['assignment'] = ks_flask.base_url(

View File

@ -36,7 +36,7 @@ class RoleInferencesResource(flask_restful.Resource):
for role_ref in PROVIDERS.role_api.list_roles() for role_ref in PROVIDERS.role_api.list_roles()
} }
rules = dict() rules = {}
for ref in refs: for ref in refs:
implied_role_id = ref['implied_role_id'] implied_role_id = ref['implied_role_id']
prior_role_id = ref['prior_role_id'] prior_role_id = ref['prior_role_id']
@ -49,10 +49,7 @@ class RoleInferencesResource(flask_restful.Resource):
rules[prior_role_id] = implied rules[prior_role_id] = implied
inferences = [] inferences = []
for ( for prior_id, implied in rules.items():
prior_id,
implied,
) in rules.items():
prior_response = shared.build_prior_role_response_data( prior_response = shared.build_prior_role_response_data(
prior_id, role_dict[prior_id]['name'] prior_id, role_dict[prior_id]['name']
) )

View File

@ -220,13 +220,12 @@ class RoleImplicationListResource(flask_restful.Resource):
shared.build_implied_role_response_data(implied_role) shared.build_implied_role_response_data(implied_role)
) )
response_json['links'] = { response_json['links'] = {
'self': ks_flask.base_url(path='/roles/%s/implies' % prior_role_id) 'self': ks_flask.base_url(path=f'/roles/{prior_role_id}/implies')
} }
return response_json return response_json
class RoleImplicationResource(flask_restful.Resource): class RoleImplicationResource(flask_restful.Resource):
def head(self, prior_role_id, implied_role_id=None): def head(self, prior_role_id, implied_role_id=None):
# TODO(morgan): deprecate "check_implied_role" policy, as a user must # TODO(morgan): deprecate "check_implied_role" policy, as a user must
# have both check_implied_role and get_implied_role to use the head # have both check_implied_role and get_implied_role to use the head
@ -266,8 +265,7 @@ class RoleImplicationResource(flask_restful.Resource):
) )
response_json['links'] = { response_json['links'] = {
'self': ks_flask.base_url( 'self': ks_flask.base_url(
path='/roles/%(prior)s/implies/%(implies)s' path=f'/roles/{prior_role_id}/implies/{implied_role_id}'
% {'prior': prior_role_id, 'implies': implied_role_id}
) )
} }
return response_json return response_json

View File

@ -94,7 +94,7 @@ def _normalize_trust_roles(trust):
trust['roles'] = trust_full_roles trust['roles'] = trust_full_roles
trust['roles_links'] = { trust['roles_links'] = {
'self': ks_flask.base_url(path='/%s/roles' % trust['id']), 'self': ks_flask.base_url(path='/{}/roles'.format(trust['id'])),
'next': None, 'next': None,
'previous': None, 'previous': None,
} }
@ -374,7 +374,6 @@ class TrustResource(ks_flask.ResourceBase):
# URL additions and does not have a collection key/member_key, we use # URL additions and does not have a collection key/member_key, we use
# the flask-restful Resource, not the keystone ResourceBase # the flask-restful Resource, not the keystone ResourceBase
class RolesForTrustListResource(flask_restful.Resource): class RolesForTrustListResource(flask_restful.Resource):
@property @property
def oslo_context(self): def oslo_context(self):
return flask.request.environ.get(context.REQUEST_CONTEXT_ENV, None) return flask.request.environ.get(context.REQUEST_CONTEXT_ENV, None)
@ -429,7 +428,6 @@ class RolesForTrustListResource(flask_restful.Resource):
# URL additions and does not have a collection key/member_key, we use # URL additions and does not have a collection key/member_key, we use
# the flask-restful Resource, not the keystone ResourceBase # the flask-restful Resource, not the keystone ResourceBase
class RoleForTrustResource(flask_restful.Resource): class RoleForTrustResource(flask_restful.Resource):
@property @property
def oslo_context(self): def oslo_context(self):
return flask.request.environ.get(context.REQUEST_CONTEXT_ENV, None) return flask.request.environ.get(context.REQUEST_CONTEXT_ENV, None)

View File

@ -66,7 +66,6 @@ def _convert_v3_to_ec2_credential(credential):
def _format_token_entity(entity): def _format_token_entity(entity):
formatted_entity = entity.copy() formatted_entity = entity.copy()
access_token_id = formatted_entity['id'] access_token_id = formatted_entity['id']
user_id = formatted_entity.get('authorizing_user_id', '') user_id = formatted_entity.get('authorizing_user_id', '')
@ -76,8 +75,7 @@ def _format_token_entity(entity):
formatted_entity.pop('access_secret') formatted_entity.pop('access_secret')
url = ( url = (
'/users/%(user_id)s/OS-OAUTH1/access_tokens/%(access_token_id)s' f'/users/{user_id}/OS-OAUTH1/access_tokens/{access_token_id}' '/roles'
'/roles' % {'user_id': user_id, 'access_token_id': access_token_id}
) )
formatted_entity.setdefault('links', {}) formatted_entity.setdefault('links', {})
@ -418,19 +416,19 @@ class UserOSEC2CredentialsResourceListCreate(_UserOSEC2CredBaseResource):
PROVIDERS.identity_api.get_user(user_id) PROVIDERS.identity_api.get_user(user_id)
tenant_id = self.request_body_json.get('tenant_id') tenant_id = self.request_body_json.get('tenant_id')
PROVIDERS.resource_api.get_project(tenant_id) PROVIDERS.resource_api.get_project(tenant_id)
blob = dict( blob = {
access=uuid.uuid4().hex, 'access': uuid.uuid4().hex,
secret=uuid.uuid4().hex, 'secret': uuid.uuid4().hex,
trust_id=self.oslo_context.trust_id, 'trust_id': self.oslo_context.trust_id,
) }
credential_id = utils.hash_access_key(blob['access']) credential_id = utils.hash_access_key(blob['access'])
cred_data = dict( cred_data = {
user_id=user_id, 'user_id': user_id,
project_id=tenant_id, 'project_id': tenant_id,
blob=jsonutils.dumps(blob), 'blob': jsonutils.dumps(blob),
id=credential_id, 'id': credential_id,
type=CRED_TYPE_EC2, 'type': CRED_TYPE_EC2,
) }
PROVIDERS.credential_api.create_credential(credential_id, cred_data) PROVIDERS.credential_api.create_credential(credential_id, cred_data)
ref = _convert_v3_to_ec2_credential(cred_data) ref = _convert_v3_to_ec2_credential(cred_data)
return self.wrap_member(ref), http.client.CREATED return self.wrap_member(ref), http.client.CREATED
@ -537,10 +535,10 @@ class OAuth1AccessTokenCRUDResource(_OAuth1ResourceBase):
access_token = PROVIDERS.oauth_api.get_access_token(access_token_id) access_token = PROVIDERS.oauth_api.get_access_token(access_token_id)
reason = ( reason = (
'Invalidating the token cache because an access token for ' 'Invalidating the token cache because an access token for '
'consumer %(consumer_id)s has been deleted. Authorization for ' 'consumer {consumer_id} has been deleted. Authorization for '
'users with OAuth tokens will be recalculated and enforced ' 'users with OAuth tokens will be recalculated and enforced '
'accordingly the next time they authenticate or validate a ' 'accordingly the next time they authenticate or validate a '
'token.' % {'consumer_id': access_token['consumer_id']} 'token.'.format(consumer_id=access_token['consumer_id'])
) )
notifications.invalidate_token_cache_notification(reason) notifications.invalidate_token_cache_notification(reason)
PROVIDERS.oauth_api.delete_access_token( PROVIDERS.oauth_api.delete_access_token(
@ -752,8 +750,7 @@ class UserAppCredGetDeleteResource(ks_flask.ResourceBase):
""" """
target = _update_request_user_id_attribute() target = _update_request_user_id_attribute()
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:get_application_credential', action='identity:get_application_credential', target_attr=target
target_attr=target,
) )
ref = PROVIDERS.application_credential_api.get_application_credential( ref = PROVIDERS.application_credential_api.get_application_credential(
application_credential_id application_credential_id
@ -787,11 +784,7 @@ class UserAccessRuleListResource(ks_flask.ResourceBase):
GET/HEAD /v3/users/{user_id}/access_rules GET/HEAD /v3/users/{user_id}/access_rules
""" """
filters = ( filters = ('service', 'path', 'method')
'service',
'path',
'method',
)
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:list_access_rules', action='identity:list_access_rules',
filters=filters, filters=filters,

View File

@ -52,9 +52,7 @@ def _schema_validator(
schema_validator.validate(target) schema_validator.validate(target)
def request_body_schema( def request_body_schema(schema: ty.Optional[ty.Dict[str, ty.Any]] = None):
schema: ty.Optional[ty.Dict[str, ty.Any]] = None,
):
"""Register a schema to validate request body. """Register a schema to validate request body.
``schema`` will be used for validating the request body just before the API ``schema`` will be used for validating the request body just before the API
@ -88,9 +86,7 @@ def request_body_schema(
return add_validator return add_validator
def request_query_schema( def request_query_schema(schema: ty.Optional[ty.Dict[str, ty.Any]] = None):
schema: ty.Optional[ty.Dict[str, ty.Any]] = None,
):
"""Register a schema to validate request query string parameters. """Register a schema to validate request query string parameters.
``schema`` will be used for validating request query strings just before ``schema`` will be used for validating request query strings just before
@ -113,13 +109,7 @@ def request_query_schema(
else: else:
req = flask.request.args req = flask.request.args
_schema_validator( _schema_validator(schema, req, args, kwargs, is_body=True)
schema,
req,
args,
kwargs,
is_body=True,
)
return func(*args, **kwargs) return func(*args, **kwargs)
wrapper._request_query_schema = schema wrapper._request_query_schema = schema
@ -129,9 +119,7 @@ def request_query_schema(
return add_validator return add_validator
def response_body_schema( def response_body_schema(schema: ty.Optional[ty.Dict[str, ty.Any]] = None):
schema: ty.Optional[ty.Dict[str, ty.Any]] = None,
):
"""Register a schema to validate response body. """Register a schema to validate response body.
``schema`` will be used for validating the response body just after the API ``schema`` will be used for validating the response body just after the API
@ -169,13 +157,7 @@ def response_body_schema(
else: else:
body = jsonutils.loads(_body) body = jsonutils.loads(_body)
_schema_validator( _schema_validator(schema, body, args, kwargs, is_body=True)
schema,
body,
args,
kwargs,
is_body=True,
)
return response return response
wrapper._response_body_schema = schema wrapper._response_body_schema = schema

View File

@ -11,6 +11,7 @@
# under the License. # under the License.
"""Common parameter types for validating API requests.""" """Common parameter types for validating API requests."""
from typing import Any from typing import Any
empty: dict[str, Any] = {"type": "null"} empty: dict[str, Any] = {"type": "null"}
@ -24,22 +25,11 @@ name: dict[str, Any] = {
boolean = { boolean = {
"type": ["boolean", "string"], "type": ["boolean", "string"],
"enum": [ "enum": [True, "True", "TRUE", "true", False, "False", "FALSE", "false"],
True,
"True",
"TRUE",
"true",
False,
"False",
"FALSE",
"false",
],
} }
domain_id: dict[str, str] = { domain_id: dict[str, str] = {"type": "string"}
"type": "string",
}
parent_id: dict[str, str] = {"type": "string", "format": "uuid"} parent_id: dict[str, str] = {"type": "string", "format": "uuid"}
@ -60,10 +50,7 @@ tags: dict[str, Any] = {
# As OpenAPI request parameters this is an array of string serialized # As OpenAPI request parameters this is an array of string serialized
# as csv # as csv
"openapi": { "openapi": {
"schema": { "schema": {"type": "array", "items": _tag_name_property},
"type": "array",
"items": _tag_name_property,
},
"style": "form", "style": "form",
"explode": False, "explode": False,
} }

View File

@ -11,6 +11,7 @@
# under the License. # under the License.
"""Common field types for validating API responses.""" """Common field types for validating API responses."""
from typing import Any from typing import Any
# Common schema for resource `link` attribute # Common schema for resource `link` attribute

View File

@ -26,10 +26,7 @@ from keystone.i18n import _
def _soft_validate_additional_properties( def _soft_validate_additional_properties(
validator, validator, additional_properties_value, param_value, schema
additional_properties_value,
param_value,
schema,
): ):
"""Validator function. """Validator function.

View File

@ -18,7 +18,6 @@ from keystone import exception
class ApplicationCredentialDriverBase(metaclass=abc.ABCMeta): class ApplicationCredentialDriverBase(metaclass=abc.ABCMeta):
@abc.abstractmethod @abc.abstractmethod
def authenticate(self, application_credential_id, secret): def authenticate(self, application_credential_id, secret):
"""Validate an application credential. """Validate an application credential.

View File

@ -125,7 +125,6 @@ class ApplicationCredentialAccessRuleModel(sql.ModelBase, sql.ModelDictMixin):
class ApplicationCredential(base.ApplicationCredentialDriverBase): class ApplicationCredential(base.ApplicationCredentialDriverBase):
def _check_secret(self, secret, app_cred_ref): def _check_secret(self, secret, app_cred_ref):
secret_hash = app_cred_ref['secret_hash'] secret_hash = app_cred_ref['secret_hash']
return password_hashing.check_password(secret, secret_hash) return password_hashing.check_password(secret, secret_hash)

View File

@ -21,7 +21,6 @@ CONF = keystone.conf.CONF
class AssignmentDriverBase(metaclass=abc.ABCMeta): class AssignmentDriverBase(metaclass=abc.ABCMeta):
def _get_list_limit(self): def _get_list_limit(self):
return CONF.assignment.list_limit or CONF.list_limit return CONF.assignment.list_limit or CONF.list_limit

View File

@ -41,7 +41,6 @@ class AssignmentType:
class Assignment(base.AssignmentDriverBase): class Assignment(base.AssignmentDriverBase):
@classmethod @classmethod
def default_role_driver(cls): def default_role_driver(cls):
return 'sql' return 'sql'
@ -55,7 +54,6 @@ class Assignment(base.AssignmentDriverBase):
project_id=None, project_id=None,
inherited_to_projects=False, inherited_to_projects=False,
): ):
assignment_type = AssignmentType.calculate_type( assignment_type = AssignmentType.calculate_type(
user_id, group_id, project_id, domain_id user_id, group_id, project_id, domain_id
) )
@ -182,11 +180,7 @@ class Assignment(base.AssignmentDriverBase):
) )
) )
except sql.DBDuplicateEntry: except sql.DBDuplicateEntry:
msg = 'User {} already has role {} in tenant {}'.format( msg = f'User {user_id} already has role {role_id} in tenant {project_id}'
user_id,
role_id,
project_id,
)
raise exception.Conflict(type='role grant', details=msg) raise exception.Conflict(type='role grant', details=msg)
def remove_role_from_user_and_project(self, user_id, project_id, role_id): def remove_role_from_user_and_project(self, user_id, project_id, role_id):
@ -264,7 +258,6 @@ class Assignment(base.AssignmentDriverBase):
project_ids=None, project_ids=None,
inherited_to_projects=None, inherited_to_projects=None,
): ):
def denormalize_role(ref): def denormalize_role(ref):
assignment = {} assignment = {}
if ref.type == AssignmentType.USER_PROJECT: if ref.type == AssignmentType.USER_PROJECT:

View File

@ -71,8 +71,8 @@ class Manager(manager.Manager):
self.event_callbacks = { self.event_callbacks = {
notifications.ACTIONS.deleted: { notifications.ACTIONS.deleted: {
'domain': [self._delete_domain_assignments], 'domain': [self._delete_domain_assignments]
}, }
} }
def _delete_domain_assignments( def _delete_domain_assignments(
@ -209,7 +209,6 @@ class Manager(manager.Manager):
inherited_to_projects=False, inherited_to_projects=False,
context=None, context=None,
): ):
# The parameters for this method must match the parameters for # The parameters for this method must match the parameters for
# create_grant so that the notifications.role_assignment decorator # create_grant so that the notifications.role_assignment decorator
# will work. # will work.
@ -286,7 +285,6 @@ class Manager(manager.Manager):
inherited_to_projects=False, inherited_to_projects=False,
context=None, context=None,
): ):
# The parameters for this method must match the parameters for # The parameters for this method must match the parameters for
# delete_grant so that the notifications.role_assignment decorator # delete_grant so that the notifications.role_assignment decorator
# will work. # will work.
@ -326,16 +324,9 @@ class Manager(manager.Manager):
target_id = project_id target_id = project_id
reason = ( reason = (
'Invalidating the token cache because role %(role_id)s was ' f'Invalidating the token cache because role {role_id} was '
'removed from %(actor_type)s %(actor_id)s on %(target_type)s ' f'removed from {actor_type} {actor_id} on {target_type} '
'%(target_id)s.' f'{target_id}.'
% {
'role_id': role_id,
'actor_type': actor_type,
'actor_id': actor_id,
'target_type': target_type,
'target_id': target_id,
}
) )
notifications.invalidate_token_cache_notification(reason) notifications.invalidate_token_cache_notification(reason)
@ -429,7 +420,6 @@ class Manager(manager.Manager):
inherited_to_projects=False, inherited_to_projects=False,
initiator=None, initiator=None,
): ):
# check if role exist before any processing # check if role exist before any processing
PROVIDERS.role_api.get_role(role_id) PROVIDERS.role_api.get_role(role_id)
@ -760,7 +750,7 @@ class Manager(manager.Manager):
implied_roles_cache = {} implied_roles_cache = {}
role_refs_to_check = list(role_refs) role_refs_to_check = list(role_refs)
ref_results = list(role_refs) ref_results = list(role_refs)
checked_role_refs = list() checked_role_refs = []
while role_refs_to_check: while role_refs_to_check:
next_ref = role_refs_to_check.pop() next_ref = role_refs_to_check.pop()
checked_role_refs.append(next_ref) checked_role_refs.append(next_ref)
@ -1348,9 +1338,8 @@ class Manager(manager.Manager):
role = PROVIDERS.role_api.get_role(role_id) role = PROVIDERS.role_api.get_role(role_id)
if role.get('domain_id'): if role.get('domain_id'):
raise exception.ValidationError( raise exception.ValidationError(
'Role %(role_id)s is a domain-specific role. Unable to use ' f'Role {role_id} is a domain-specific role. Unable to use '
'a domain-specific role in a system assignment.' 'a domain-specific role in a system assignment.'
% {'role_id': role_id}
) )
target_id = self._SYSTEM_SCOPE_TOKEN target_id = self._SYSTEM_SCOPE_TOKEN
assignment_type = self._USER_SYSTEM assignment_type = self._USER_SYSTEM
@ -1420,9 +1409,8 @@ class Manager(manager.Manager):
role = PROVIDERS.role_api.get_role(role_id) role = PROVIDERS.role_api.get_role(role_id)
if role.get('domain_id'): if role.get('domain_id'):
raise exception.ValidationError( raise exception.ValidationError(
'Role %(role_id)s is a domain-specific role. Unable to use ' f'Role {role_id} is a domain-specific role. Unable to use '
'a domain-specific role in a system assignment.' 'a domain-specific role in a system assignment.'
% {'role_id': role_id}
) )
target_id = self._SYSTEM_SCOPE_TOKEN target_id = self._SYSTEM_SCOPE_TOKEN
assignment_type = self._GROUP_SYSTEM assignment_type = self._GROUP_SYSTEM
@ -1556,10 +1544,10 @@ class RoleManager(manager.Manager):
notifications.Audit.deleted(self._ROLE, role_id, initiator) notifications.Audit.deleted(self._ROLE, role_id, initiator)
self.get_role.invalidate(self, role_id) self.get_role.invalidate(self, role_id)
reason = ( reason = (
'Invalidating the token cache because role %(role_id)s has been ' f'Invalidating the token cache because role {role_id} has been '
'removed. Role assignments for users will be recalculated and ' 'removed. Role assignments for users will be recalculated and '
'enforced accordingly the next time they authenticate or validate ' 'enforced accordingly the next time they authenticate or validate '
'a token' % {'role_id': role_id} 'a token'
) )
notifications.invalidate_token_cache_notification(reason) notifications.invalidate_token_cache_notification(reason)
COMPUTED_ASSIGNMENTS_REGION.invalidate() COMPUTED_ASSIGNMENTS_REGION.invalidate()

View File

@ -29,7 +29,6 @@ CONF = keystone.conf.CONF
class RoleDriverBase(metaclass=abc.ABCMeta): class RoleDriverBase(metaclass=abc.ABCMeta):
def _get_list_limit(self): def _get_list_limit(self):
return CONF.role.list_limit or CONF.list_limit return CONF.role.list_limit or CONF.list_limit

View File

@ -19,9 +19,7 @@ ROLE_OPTIONS_REGISTRY = resource_options.ResourceOptionRegistry('ROLE')
# NOTE(morgan): wrap this in a function for testing purposes. # NOTE(morgan): wrap this in a function for testing purposes.
# This is called on import by design. # This is called on import by design.
def register_role_options(): def register_role_options():
for opt in [ for opt in [ro_opt.IMMUTABLE_OPT]:
ro_opt.IMMUTABLE_OPT,
]:
ROLE_OPTIONS_REGISTRY.register_option(opt) ROLE_OPTIONS_REGISTRY.register_option(opt)

View File

@ -20,7 +20,6 @@ from keystone import exception
class Role(base.RoleDriverBase): class Role(base.RoleDriverBase):
@sql.handle_conflicts(conflict_type='role') @sql.handle_conflicts(conflict_type='role')
def create_role(self, role_id, role): def create_role(self, role_id, role):
with sql.session_for_write() as session: with sql.session_for_write() as session:

View File

@ -19,7 +19,6 @@ from keystone.common import sql
class RoleTable(sql.ModelBase, sql.ModelDictMixinWithExtras): class RoleTable(sql.ModelBase, sql.ModelDictMixinWithExtras):
def to_dict(self, include_extra_dict=False): def to_dict(self, include_extra_dict=False):
d = super().to_dict(include_extra_dict=include_extra_dict) d = super().to_dict(include_extra_dict=include_extra_dict)
if d['domain_id'] == base.NULL_DOMAIN_ID: if d['domain_id'] == base.NULL_DOMAIN_ID:
@ -96,7 +95,7 @@ class ImpliedRoleTable(sql.ModelBase, sql.ModelDictMixin):
overrides the `to_dict` function from the base class overrides the `to_dict` function from the base class
to avoid having an `extra` field. to avoid having an `extra` field.
""" """
d = dict() d = {}
for attr in self.__class__.attributes: for attr in self.__class__.attributes:
d[attr] = getattr(self, attr) d[attr] = getattr(self, attr)
return d return d

View File

@ -38,7 +38,7 @@ def _get_auth_driver_manager(namespace, plugin_name):
def load_auth_method(method): def load_auth_method(method):
plugin_name = CONF.auth.get(method) or 'default' plugin_name = CONF.auth.get(method) or 'default'
namespace = 'keystone.auth.%s' % method namespace = f'keystone.auth.{method}'
driver_manager = _get_auth_driver_manager(namespace, plugin_name) driver_manager = _get_auth_driver_manager(namespace, plugin_name)
return driver_manager.driver return driver_manager.driver
@ -261,7 +261,7 @@ class AuthInfo(provider_api.ProviderAPIMixin):
app_cred_api = PROVIDERS.application_credential_api app_cred_api = PROVIDERS.application_credential_api
app_creds = app_cred_api.list_application_credentials(user_id, hints) app_creds = app_cred_api.list_application_credentials(user_id, hints)
if len(app_creds) != 1: if len(app_creds) != 1:
message = "Could not find application credential: %s" % name message = f"Could not find application credential: {name}"
tr_message = _("Could not find application credential: %s") % name tr_message = _("Could not find application credential: %s") % name
LOG.warning(message) LOG.warning(message)
raise exception.Unauthorized(tr_message) raise exception.Unauthorized(tr_message)

View File

@ -45,13 +45,7 @@ class AuthMethodHandler(provider_api.ProviderAPIMixin, metaclass=abc.ABCMeta):
to the re-scope type action. Here's an example of ``response_data`` on to the re-scope type action. Here's an example of ``response_data`` on
successful authentication:: successful authentication::
{ {"methods": ["password", "token"], "user_id": "abc123"}
"methods": [
"password",
"token"
],
"user_id": "abc123"
}
Plugins are invoked in the order in which they are specified in the Plugins are invoked in the order in which they are specified in the
``methods`` attribute of the ``identity`` object. For example, ``methods`` attribute of the ``identity`` object. For example,
@ -61,23 +55,12 @@ class AuthMethodHandler(provider_api.ProviderAPIMixin, metaclass=abc.ABCMeta):
{ {
"auth": { "auth": {
"identity": { "identity": {
"custom-plugin": { "custom-plugin": {"custom-data": "sdfdfsfsfsdfsf"},
"custom-data": "sdfdfsfsfsdfsf" "methods": ["custom-plugin", "password", "token"],
},
"methods": [
"custom-plugin",
"password",
"token"
],
"password": { "password": {
"user": { "user": {"id": "s23sfad1", "password": "secret"}
"id": "s23sfad1",
"password": "secret"
}
}, },
"token": { "token": {"id": "sdfafasdfsfasfasdfds"},
"id": "sdfafasdfsfasfasdfds"
}
} }
} }
} }

View File

@ -27,9 +27,7 @@ CONF = keystone.conf.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
PROVIDERS = provider_api.ProviderAPIs PROVIDERS = provider_api.ProviderAPIs
_NOTIFY_OP = 'authenticate' _NOTIFY_OP = 'authenticate'
_NOTIFY_EVENT = '{service}.{event}'.format( _NOTIFY_EVENT = f'{notifications.SERVICE}.{_NOTIFY_OP}'
service=notifications.SERVICE, event=_NOTIFY_OP
)
def construct_method_map_from_config(): def construct_method_map_from_config():
@ -38,7 +36,7 @@ def construct_method_map_from_config():
:returns: a dictionary containing the methods and their indexes :returns: a dictionary containing the methods and their indexes
""" """
method_map = dict() method_map = {}
method_index = 1 method_index = 1
for method in CONF.auth.methods: for method in CONF.auth.methods:
method_map[method_index] = method method_map[method_index] = method
@ -99,7 +97,6 @@ def convert_integer_to_method_list(method_int):
class BaseUserInfo(provider_api.ProviderAPIMixin): class BaseUserInfo(provider_api.ProviderAPIMixin):
@classmethod @classmethod
def create(cls, auth_payload, method_name): def create(cls, auth_payload, method_name):
user_auth_info = cls() user_auth_info = cls()
@ -213,7 +210,6 @@ class BaseUserInfo(provider_api.ProviderAPIMixin):
class UserAuthInfo(BaseUserInfo): class UserAuthInfo(BaseUserInfo):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.password = None self.password = None
@ -225,7 +221,6 @@ class UserAuthInfo(BaseUserInfo):
class TOTPUserInfo(BaseUserInfo): class TOTPUserInfo(BaseUserInfo):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.passcode = None self.passcode = None

View File

@ -34,7 +34,6 @@ PROVIDERS = provider_api.ProviderAPIs
class Mapped(base.AuthMethodHandler): class Mapped(base.AuthMethodHandler):
def _get_token_ref(self, auth_payload): def _get_token_ref(self, auth_payload):
token_id = auth_payload['id'] token_id = auth_payload['id']
return PROVIDERS.token_provider_api.validate_token(token_id) return PROVIDERS.token_provider_api.validate_token(token_id)
@ -184,7 +183,6 @@ def handle_unscoped_token(
assignment_api, assignment_api,
role_api, role_api,
): ):
def validate_shadow_mapping( def validate_shadow_mapping(
shadow_projects, existing_roles, user_domain_id, idp_id shadow_projects, existing_roles, user_domain_id, idp_id
): ):
@ -300,7 +298,6 @@ def handle_unscoped_token(
) )
if 'projects' in mapped_properties: if 'projects' in mapped_properties:
existing_roles = { existing_roles = {
role['name']: role for role in role_api.list_roles() role['name']: role for role in role_api.list_roles()
} }

View File

@ -23,7 +23,6 @@ PROVIDERS = provider_api.ProviderAPIs
class Password(base.AuthMethodHandler): class Password(base.AuthMethodHandler):
def authenticate(self, auth_payload): def authenticate(self, auth_payload):
"""Try to authenticate against the identity backend.""" """Try to authenticate against the identity backend."""
response_data = {} response_data = {}

View File

@ -29,7 +29,6 @@ PROVIDERS = provider_api.ProviderAPIs
class Token(base.AuthMethodHandler): class Token(base.AuthMethodHandler):
def _get_token_ref(self, auth_payload): def _get_token_ref(self, auth_payload):
token_id = auth_payload['id'] token_id = auth_payload['id']
return PROVIDERS.token_provider_api.validate_token(token_id) return PROVIDERS.token_provider_api.validate_token(token_id)
@ -59,7 +58,6 @@ class Token(base.AuthMethodHandler):
def token_authenticate(token): def token_authenticate(token):
response_data = {} response_data = {}
try: try:
# Do not allow tokens used for delegation to # Do not allow tokens used for delegation to
# create another token, or perform any changes of # create another token, or perform any changes of
# state in Keystone. To do so is to invite elevation of # state in Keystone. To do so is to invite elevation of

View File

@ -90,7 +90,6 @@ def _generate_totp_passcodes(secret, included_previous_windows=0):
class TOTP(base.AuthMethodHandler): class TOTP(base.AuthMethodHandler):
def authenticate(self, auth_payload): def authenticate(self, auth_payload):
"""Try to authenticate using TOTP.""" """Try to authenticate using TOTP."""
response_data = {} response_data = {}

View File

@ -21,57 +21,34 @@ token_issue = {
'identity': { 'identity': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'methods': { 'methods': {'type': 'array', 'items': {'type': 'string'}},
'type': 'array',
'items': {
'type': 'string',
},
},
'password': { 'password': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'user': { 'user': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'id': { 'id': {'type': 'string'},
'type': 'string', 'name': {'type': 'string'},
}, 'password': {'type': 'string'},
'name': {
'type': 'string',
},
'password': {
'type': 'string',
},
'domain': { 'domain': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'id': { 'id': {'type': 'string'},
'type': 'string', 'name': {'type': 'string'},
},
'name': {
'type': 'string',
},
},
}, },
}, },
}, },
}
}, },
}, },
'token': { 'token': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {'id': {'type': 'string'}},
'id': { 'required': ['id'],
'type': 'string',
}, },
}, },
'required': [ 'required': ['methods'],
'id',
],
},
},
'required': [
'methods',
],
}, },
'scope': { 'scope': {
# For explicit unscoped authentication the type should not be # For explicit unscoped authentication the type should not be
@ -85,21 +62,13 @@ token_issue = {
'project': { 'project': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'name': { 'name': {'type': 'string'},
'type': 'string', 'id': {'type': 'string'},
},
'id': {
'type': 'string',
},
'domain': { 'domain': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'id': { 'id': {'type': 'string'},
'type': 'string', 'name': {'type': 'string'},
},
'name': {
'type': 'string',
},
}, },
}, },
}, },
@ -107,21 +76,13 @@ token_issue = {
'domain': { 'domain': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'id': { 'id': {'type': 'string'},
'type': 'string', 'name': {'type': 'string'},
},
'name': {
'type': 'string',
},
}, },
}, },
'OS-TRUST:trust': { 'OS-TRUST:trust': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {'id': {'type': 'string'}},
'id': {
'type': 'string',
},
},
}, },
'system': { 'system': {
'type': 'object', 'type': 'object',
@ -130,9 +91,7 @@ token_issue = {
}, },
}, },
}, },
'required': [ 'required': ['identity'],
'identity',
],
} }

View File

@ -246,17 +246,19 @@ class CatalogDriverBase(provider_api.ProviderAPIMixin, metaclass=abc.ABCMeta):
"interface": "public", "interface": "public",
"id": "--endpoint-id--", "id": "--endpoint-id--",
"region": "RegionOne", "region": "RegionOne",
"url": "http://external:8776/v1/--project-id--" "url": "http://external:8776/v1/--project-id--",
}, },
{ {
"interface": "internal", "interface": "internal",
"id": "--endpoint-id--", "id": "--endpoint-id--",
"region": "RegionOne", "region": "RegionOne",
"url": "http://internal:8776/v1/--project-id--" "url": "http://internal:8776/v1/--project-id--",
}], },
],
"id": "--service-id--", "id": "--service-id--",
"type": "volume" "type": "volume",
}] }
]
:returns: A list representing the service catalog or an empty list :returns: A list representing the service catalog or an empty list
:raises keystone.exception.NotFound: If the endpoint doesn't exist. :raises keystone.exception.NotFound: If the endpoint doesn't exist.

View File

@ -333,7 +333,7 @@ class Catalog(base.CatalogDriverBase):
} }
catalog.setdefault(region, {}) catalog.setdefault(region, {})
catalog[region].setdefault(service_type, default_service) catalog[region].setdefault(service_type, default_service)
interface_url = '%sURL' % endpoint['interface'] interface_url = '{}URL'.format(endpoint['interface'])
catalog[region][service_type][interface_url] = url catalog[region][service_type][interface_url] = url
return catalog return catalog
@ -355,12 +355,7 @@ class Catalog(base.CatalogDriverBase):
d.update({'user_id': user_id}) d.update({'user_id': user_id})
silent_keyerror_failures = [] silent_keyerror_failures = []
if project_id: if project_id:
d.update( d.update({'tenant_id': project_id, 'project_id': project_id})
{
'tenant_id': project_id,
'project_id': project_id,
}
)
else: else:
silent_keyerror_failures = ['tenant_id', 'project_id'] silent_keyerror_failures = ['tenant_id', 'project_id']
@ -463,8 +458,7 @@ class Catalog(base.CatalogDriverBase):
def _get_project_endpoint_ref(self, session, endpoint_id, project_id): def _get_project_endpoint_ref(self, session, endpoint_id, project_id):
endpoint_filter_ref = session.get( endpoint_filter_ref = session.get(
ProjectEndpoint, ProjectEndpoint, (endpoint_id, project_id)
(endpoint_id, project_id),
) )
if endpoint_filter_ref is None: if endpoint_filter_ref is None:
msg = _( msg = _(
@ -576,8 +570,7 @@ class Catalog(base.CatalogDriverBase):
self, session, endpoint_group_id, project_id self, session, endpoint_group_id, project_id
): ):
endpoint_group_project_ref = session.get( endpoint_group_project_ref = session.get(
ProjectEndpointGroupMembership, ProjectEndpointGroupMembership, (endpoint_group_id, project_id)
(endpoint_group_id, project_id),
) )
if endpoint_group_project_ref is None: if endpoint_group_project_ref is None:
msg = _('Endpoint Group Project Association not found') msg = _('Endpoint Group Project Association not found')

View File

@ -166,11 +166,7 @@ class Catalog(base.CatalogDriverBase):
for key in service_ref: for key in service_ref:
if key.endswith('URL'): if key.endswith('URL'):
interface = key[:-3] interface = key[:-3]
endpoint_id = '{}-{}-{}'.format( endpoint_id = f'{region_id}-{service_type}-{interface}'
region_id,
service_type,
interface,
)
yield { yield {
'id': endpoint_id, 'id': endpoint_id,
'service_id': service_type, 'service_id': service_type,
@ -215,16 +211,10 @@ class Catalog(base.CatalogDriverBase):
silent_keyerror_failures = [] silent_keyerror_failures = []
if project_id: if project_id:
substitutions.update( substitutions.update(
{ {'tenant_id': project_id, 'project_id': project_id}
'tenant_id': project_id,
'project_id': project_id,
}
) )
else: else:
silent_keyerror_failures = [ silent_keyerror_failures = ['tenant_id', 'project_id']
'tenant_id',
'project_id',
]
catalog = {} catalog = {}
# TODO(davechen): If there is service with no endpoints, we should # TODO(davechen): If there is service with no endpoints, we should

View File

@ -26,7 +26,6 @@ PROVIDERS = provider_api.ProviderAPIs
class Bootstrapper: class Bootstrapper:
def __init__(self): def __init__(self):
backends.load_backends() backends.load_backends()

View File

@ -52,7 +52,6 @@ LOG = log.getLogger(__name__)
class BaseApp: class BaseApp:
name: str name: str
@classmethod @classmethod
@ -536,8 +535,7 @@ class ResetLastActive(BaseApp):
raise SystemExit('reset_last_active aborted.') raise SystemExit('reset_last_active aborted.')
LOG.debug( LOG.debug(
"Resetting null values to current time %s", "Resetting null values to current time %s", timeutils.utcnow()
timeutils.utcnow(),
) )
drivers = backends.load_backends() drivers = backends.load_backends()
identity_api = drivers['identity_api'] identity_api = drivers['identity_api']
@ -565,14 +563,14 @@ class BasePermissionsSetup(BaseApp):
if a: if a:
keystone_user_id = utils.get_unix_user(a)[0] keystone_user_id = utils.get_unix_user(a)[0]
except KeyError: except KeyError:
raise ValueError("Unknown user '%s' in --keystone-user" % a) raise ValueError(f"Unknown user '{a}' in --keystone-user")
try: try:
a = CONF.command.keystone_group a = CONF.command.keystone_group
if a: if a:
keystone_group_id = utils.get_unix_group(a)[0] keystone_group_id = utils.get_unix_group(a)[0]
except KeyError: except KeyError:
raise ValueError("Unknown group '%s' in --keystone-group" % a) raise ValueError(f"Unknown group '{a}' in --keystone-group")
return keystone_user_id, keystone_group_id return keystone_user_id, keystone_group_id
@ -1180,7 +1178,6 @@ def _domain_config_finder(conf_dir):
class DomainConfigUploadFiles: class DomainConfigUploadFiles:
def __init__(self, domain_config_finder=_domain_config_finder): def __init__(self, domain_config_finder=_domain_config_finder):
super().__init__() super().__init__()
self.load_backends() self.load_backends()
@ -1518,12 +1515,9 @@ class MappingEngineTester(BaseApp):
tester.normalize_assertion() tester.normalize_assertion()
if CONF.command.engine_debug: if CONF.command.engine_debug:
print(f"Using Rules:\n{jsonutils.dumps(tester.rules, indent=2)}")
print( print(
"Using Rules:\n%s" % (jsonutils.dumps(tester.rules, indent=2)) f"Using Assertion:\n{jsonutils.dumps(tester.assertion, indent=2)}"
)
print(
"Using Assertion:\n%s"
% (jsonutils.dumps(tester.assertion, indent=2))
) )
rp = mapping_engine.RuleProcessor( rp = mapping_engine.RuleProcessor(

View File

@ -50,8 +50,9 @@ def diagnose():
# Some symptoms may take a long time to check, so let's keep # Some symptoms may take a long time to check, so let's keep
# curious users posted on our progress as we go. # curious users posted on our progress as we go.
print( print(
'Checking for %s...' 'Checking for {}...'.format(
% symptom.__name__[len(SYMPTOM_PREFIX) :].replace('_', ' ') symptom.__name__[len(SYMPTOM_PREFIX) :].replace('_', ' ')
)
) )
# All symptoms are just callables that return true when they match the # All symptoms are just callables that return true when they match the
@ -65,9 +66,7 @@ def diagnose():
# passing a string here. Also, we include a line break here to # passing a string here. Also, we include a line break here to
# visually separate the symptom's description from any other # visually separate the symptom's description from any other
# checks -- it provides a better user experience. # checks -- it provides a better user experience.
print( print(_('\nWARNING: %s') % _(symptom.__doc__)) # noqa: See comment above.
_('\nWARNING: %s') % _(symptom.__doc__)
) # noqa: See comment above.
return symptoms_found return symptoms_found

View File

@ -85,10 +85,10 @@ def symptom_LDAP_file_based_domain_specific_configs():
if invalid_files: if invalid_files:
invalid_str = ', '.join(invalid_files) invalid_str = ', '.join(invalid_files)
print( print(
'Warning: The following non-config files were found: %s\n' f'Warning: The following non-config files were found: {invalid_str}\n'
'If they are intended to be config files then rename them ' 'If they are intended to be config files then rename them '
'to the form of `keystone.<domain_name>.conf`. ' 'to the form of `keystone.<domain_name>.conf`. '
'Otherwise, ignore this warning' % invalid_str 'Otherwise, ignore this warning'
) )
return True return True
else: else:

View File

@ -28,7 +28,6 @@ PROVIDERS = provider_api.ProviderAPIs
class Identity: class Identity:
def __init__(self): def __init__(self):
backends.load_backends() backends.load_backends()

View File

@ -54,13 +54,14 @@ class Checks(upgradecheck.UpgradeCommands):
if any(failed_rules): if any(failed_rules):
return upgradecheck.Result( return upgradecheck.Result(
upgradecheck.Code.FAILURE, upgradecheck.Code.FAILURE,
"Policy check string for rules \"%s\" are overridden to " "Policy check string for rules \"{}\" are overridden to "
"\"\", \"@\", or []. In the next release, this will cause " "\"\", \"@\", or []. In the next release, this will cause "
"these rules to be fully permissive as hardcoded enforcement " "these rules to be fully permissive as hardcoded enforcement "
"will be removed. To correct this issue, either stop " "will be removed. To correct this issue, either stop "
"overriding these rules in config to accept the defaults, or " "overriding these rules in config to accept the defaults, or "
"explicitly set check strings that are not empty." "explicitly set check strings that are not empty.".format(
% "\", \"".join(failed_rules), "\", \"".join(failed_rules)
),
) )
return upgradecheck.Result( return upgradecheck.Result(
upgradecheck.Code.SUCCESS, 'Trust policies are safe.' upgradecheck.Code.SUCCESS, 'Trust policies are safe.'
@ -70,11 +71,7 @@ class Checks(upgradecheck.UpgradeCommands):
hints = driver_hints.Hints() hints = driver_hints.Hints()
hints.add_filter('domain_id', None) # Only check global roles hints.add_filter('domain_id', None) # Only check global roles
roles = PROVIDERS.role_api.list_roles(hints=hints) roles = PROVIDERS.role_api.list_roles(hints=hints)
default_roles = ( default_roles = ('admin', 'member', 'reader')
'admin',
'member',
'reader',
)
failed_roles = [] failed_roles = []
for role in [r for r in roles if r['name'] in default_roles]: for role in [r for r in roles if r['name'] in default_roles]:
if not role.get('options', {}).get('immutable'): if not role.get('options', {}).get('immutable'):
@ -82,7 +79,7 @@ class Checks(upgradecheck.UpgradeCommands):
if any(failed_roles): if any(failed_roles):
return upgradecheck.Result( return upgradecheck.Result(
upgradecheck.Code.FAILURE, upgradecheck.Code.FAILURE,
"Roles are not immutable: %s" % ", ".join(failed_roles), "Roles are not immutable: {}".format(", ".join(failed_roles)),
) )
return upgradecheck.Result( return upgradecheck.Result(
upgradecheck.Code.SUCCESS, "Default roles are immutable." upgradecheck.Code.SUCCESS, "Default roles are immutable."

View File

@ -11,6 +11,7 @@
# under the License. # under the License.
"""A dogpile.cache proxy that caches objects in the request local cache.""" """A dogpile.cache proxy that caches objects in the request local cache."""
from dogpile.cache import api from dogpile.cache import api
from dogpile.cache import proxy from dogpile.cache import proxy
from oslo_context import context as oslo_context from oslo_context import context as oslo_context
@ -28,7 +29,6 @@ def _register_model_handler(handler_class):
class _ResponseCacheProxy(proxy.ProxyBackend): class _ResponseCacheProxy(proxy.ProxyBackend):
__key_pfx = '_request_cache_%s' __key_pfx = '_request_cache_%s'
def _get_request_context(self): def _get_request_context(self):

View File

@ -27,7 +27,6 @@ CONF = keystone.conf.CONF
class RegionInvalidationManager: class RegionInvalidationManager:
REGION_KEY_PREFIX = '<<<region>>>:' REGION_KEY_PREFIX = '<<<region>>>:'
def __init__(self, invalidation_region, region_name): def __init__(self, invalidation_region, region_name):
@ -53,7 +52,6 @@ class RegionInvalidationManager:
class DistributedInvalidationStrategy(region.RegionInvalidationStrategy): class DistributedInvalidationStrategy(region.RegionInvalidationStrategy):
def __init__(self, region_manager): def __init__(self, region_manager):
self._region_manager = region_manager self._region_manager = region_manager
@ -165,7 +163,7 @@ def configure_invalidation_region():
config_dict['expiration_time'] = None # we don't want an expiration config_dict['expiration_time'] = None # we don't want an expiration
CACHE_INVALIDATION_REGION.configure_from_config( CACHE_INVALIDATION_REGION.configure_from_config(
config_dict, '%s.' % CONF.cache.config_prefix config_dict, f'{CONF.cache.config_prefix}.'
) )
# NOTE(breton): Wrap the cache invalidation region to avoid excessive # NOTE(breton): Wrap the cache invalidation region to avoid excessive

View File

@ -22,7 +22,6 @@ def _prop(name):
class RequestContext(oslo_context.RequestContext): class RequestContext(oslo_context.RequestContext):
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.username = kwargs.pop('username', None) self.username = kwargs.pop('username', None)
self.project_tag_name = kwargs.pop('project_tag_name', None) self.project_tag_name = kwargs.pop('project_tag_name', None)

View File

@ -96,7 +96,7 @@ class Hints:
def __init__(self): def __init__(self):
self.limit = None self.limit = None
self.filters = list() self.filters = []
self.cannot_match = False self.cannot_match = False
def add_filter( def add_filter(

View File

@ -34,7 +34,6 @@ NULL_KEY = base64.urlsafe_b64encode(b'\x00' * 32)
class FernetUtils: class FernetUtils:
def __init__(self, key_repository, max_active_keys, config_group): def __init__(self, key_repository, max_active_keys, config_group):
self.key_repository = key_repository self.key_repository = key_repository
self.max_active_keys = max_active_keys self.max_active_keys = max_active_keys
@ -157,8 +156,8 @@ class FernetUtils:
LOG.info('Become a valid new key: %s', valid_key_file) LOG.info('Become a valid new key: %s', valid_key_file)
def _get_key_files(self, key_repo): def _get_key_files(self, key_repo):
key_files = dict() key_files = {}
keys = dict() keys = {}
for filename in os.listdir(key_repo): for filename in os.listdir(key_repo):
path = os.path.join(key_repo, str(filename)) path = os.path.join(key_repo, str(filename))
if os.path.isfile(path): if os.path.isfile(path):

View File

@ -20,34 +20,28 @@ from keystone.i18n import _
def build_v3_resource_relation(resource_name): def build_v3_resource_relation(resource_name):
return ( return f'https://docs.openstack.org/api/openstack-identity/3/rel/{resource_name}'
'https://docs.openstack.org/api/openstack-identity/3/rel/%s'
% resource_name
)
def build_v3_extension_resource_relation( def build_v3_extension_resource_relation(
extension_name, extension_version, resource_name extension_name, extension_version, resource_name
): ):
return ( return (
'https://docs.openstack.org/api/openstack-identity/3/ext/%s/%s/rel/' f'https://docs.openstack.org/api/openstack-identity/3/ext/{extension_name}/{extension_version}/rel/'
'%s' % (extension_name, extension_version, resource_name) f'{resource_name}'
) )
def build_v3_parameter_relation(parameter_name): def build_v3_parameter_relation(parameter_name):
return ( return f'https://docs.openstack.org/api/openstack-identity/3/param/{parameter_name}'
'https://docs.openstack.org/api/openstack-identity/3/param/%s'
% parameter_name
)
def build_v3_extension_parameter_relation( def build_v3_extension_parameter_relation(
extension_name, extension_version, parameter_name extension_name, extension_version, parameter_name
): ):
return ( return (
'https://docs.openstack.org/api/openstack-identity/3/ext/%s/%s/param/' f'https://docs.openstack.org/api/openstack-identity/3/ext/{extension_name}/{extension_version}/param/'
'%s' % (extension_name, extension_version, parameter_name) f'{parameter_name}'
) )

View File

@ -86,10 +86,8 @@ class _TraceMeta(type):
@staticmethod @staticmethod
def wrapper(__f, __classname): def wrapper(__f, __classname):
__argspec = inspect.getfullargspec(__f) __argspec = inspect.getfullargspec(__f)
__fn_info = '{module}.{classname}.{funcname}'.format( __fn_info = (
module=inspect.getmodule(__f).__name__, f'{inspect.getmodule(__f).__name__}.{__classname}.{__f.__name__}'
classname=__classname,
funcname=__f.__name__,
) )
# NOTE(morganfainberg): Omit "cls" and "self" when printing trace logs # NOTE(morganfainberg): Omit "cls" and "self" when printing trace logs
# the index can be calculated at wrap time rather than at runtime. # the index can be calculated at wrap time rather than at runtime.

View File

@ -26,11 +26,7 @@ class Bcrypt(password_hashers.PasswordHasher):
ident_values: set[str] = {"$2$", "$2a$", "$2b$", "$2x$", "$2y$"} ident_values: set[str] = {"$2$", "$2a$", "$2b$", "$2x$", "$2y$"}
@staticmethod @staticmethod
def hash( def hash(password: bytes, rounds: int = 12, **kwargs) -> str:
password: bytes,
rounds: int = 12,
**kwargs,
) -> str:
"""Generate password hash string with ident and params """Generate password hash string with ident and params
https://pypi.org/project/bcrypt/ https://pypi.org/project/bcrypt/
@ -66,11 +62,7 @@ class Bcrypt_sha256(password_hashers.PasswordHasher):
prefix: str = "$bcrypt-sha256$" prefix: str = "$bcrypt-sha256$"
@staticmethod @staticmethod
def hash( def hash(password: bytes, rounds: int = 12, **kwargs) -> str:
password: bytes,
rounds: int = 12,
**kwargs,
) -> str:
"""Generate password hash string with ident and params """Generate password hash string with ident and params
https://pypi.org/project/bcrypt/ https://pypi.org/project/bcrypt/

View File

@ -29,11 +29,7 @@ class Sha512(password_hashers.PasswordHasher):
hash_algo = hashes.SHA512() hash_algo = hashes.SHA512()
@staticmethod @staticmethod
def hash( def hash(password: bytes, salt_size: int = 16, rounds: int = 25000) -> str:
password: bytes,
salt_size: int = 16,
rounds: int = 25000,
) -> str:
"""Generate password hash string with ident and params """Generate password hash string with ident and params
https://cryptography.io/en/stable/hazmat/primitives/key-derivation-functions/#pbkdf2 https://cryptography.io/en/stable/hazmat/primitives/key-derivation-functions/#pbkdf2
@ -49,10 +45,7 @@ class Sha512(password_hashers.PasswordHasher):
# Prepave the kdf function with params # Prepave the kdf function with params
kdf = PBKDF2HMAC( kdf = PBKDF2HMAC(
algorithm=Sha512.hash_algo, algorithm=Sha512.hash_algo, length=64, salt=salt, iterations=rounds
length=64,
salt=salt,
iterations=rounds,
) )
# derive - create a digest # derive - create a digest
@ -101,10 +94,7 @@ class Sha512(password_hashers.PasswordHasher):
# Prepave the kdf function with params # Prepave the kdf function with params
kdf = PBKDF2HMAC( kdf = PBKDF2HMAC(
algorithm=Sha512.hash_algo, algorithm=Sha512.hash_algo, length=64, salt=salt, iterations=rounds
length=64,
salt=salt,
iterations=rounds,
) )
# Verify the key. # Verify the key.

View File

@ -28,9 +28,7 @@ RULE_ADMIN_OR_TARGET_PROJECT = (
) )
RULE_ADMIN_OR_TOKEN_SUBJECT = 'rule:admin_or_token_subject' # nosec RULE_ADMIN_OR_TOKEN_SUBJECT = 'rule:admin_or_token_subject' # nosec
RULE_REVOKE_EVENT_OR_ADMIN = 'rule:revoke_event_or_admin' RULE_REVOKE_EVENT_OR_ADMIN = 'rule:revoke_event_or_admin'
RULE_SERVICE_ADMIN_OR_TOKEN_SUBJECT = ( RULE_SERVICE_ADMIN_OR_TOKEN_SUBJECT = 'rule:service_admin_or_token_subject' # nosec
'rule:service_admin_or_token_subject' # nosec
)
RULE_SERVICE_OR_ADMIN = 'rule:service_or_admin' RULE_SERVICE_OR_ADMIN = 'rule:service_or_admin'
RULE_TRUST_OWNER = 'user_id:%(trust.trustor_user_id)s' RULE_TRUST_OWNER = 'user_id:%(trust.trustor_user_id)s'

View File

@ -40,9 +40,7 @@ SYSTEM_ADMIN_OR_DOMAIN_ADMIN_OR_PROJECT_ADMIN = (
# /v3/users/{user_id}/project path. # /v3/users/{user_id}/project path.
SYSTEM_READER_OR_DOMAIN_READER_OR_OWNER = ( SYSTEM_READER_OR_DOMAIN_READER_OR_OWNER = (
# System reader policy # System reader policy
'(' '(' + base.SYSTEM_READER + ') or '
+ base.SYSTEM_READER
+ ') or '
# Domain reader policy # Domain reader policy
'(role:reader and domain_id:%(target.user.domain_id)s) or ' '(role:reader and domain_id:%(target.user.domain_id)s) or '
# User accessing the API with a token they've obtained, matching # User accessing the API with a token they've obtained, matching

View File

@ -35,7 +35,7 @@ class ProviderAPIRegistry:
try: try:
return self.__registry[item] return self.__registry[item]
except KeyError: except KeyError:
raise AttributeError("'ProviderAPIs' has no attribute %s" % item) raise AttributeError(f"'ProviderAPIs' has no attribute {item}")
def __setattr__(self, key, value): def __setattr__(self, key, value):
"""Do not allow setting values on the registry object.""" """Do not allow setting values on the registry object."""
@ -58,9 +58,8 @@ class ProviderAPIRegistry:
if name in self.__registry: if name in self.__registry:
raise DuplicateProviderError( raise DuplicateProviderError(
'`%(name)s` has already been registered as an api ' f'`{name}` has already been registered as an api '
'provider by `%(prov)r`' f'provider by `{self.__registry[name]!r}`'
% {'name': name, 'prov': self.__registry[name]}
) )
self.__registry[name] = obj self.__registry[name] = obj

View File

@ -242,7 +242,7 @@ class RBACEnforcer:
member_name = None member_name = None
func = getattr(resource, 'get_member_from_driver', None) func = getattr(resource, 'get_member_from_driver', None)
if member_name is not None and callable(func): if member_name is not None and callable(func):
key = '%s_id' % member_name key = f'{member_name}_id'
if key in (flask.request.view_args or {}): if key in (flask.request.view_args or {}):
# NOTE(morgan): For most correct setup, instantiate the # NOTE(morgan): For most correct setup, instantiate the
# view_class. There is no current support for passing # view_class. There is no current support for passing

View File

@ -107,11 +107,11 @@ def render_token_response_from_model(token, include_catalog=True):
token_reference['token']['service_providers'] = sps token_reference['token']['service_providers'] = sps
if token.is_federated: if token.is_federated:
PROVIDERS.federation_api.get_idp(token.identity_provider_id) PROVIDERS.federation_api.get_idp(token.identity_provider_id)
federated_dict = dict( federated_dict = {
groups=token.federated_groups, 'groups': token.federated_groups,
identity_provider={'id': token.identity_provider_id}, 'identity_provider': {'id': token.identity_provider_id},
protocol={'id': token.protocol_id}, 'protocol': {'id': token.protocol_id},
) }
token_reference['token']['user']['OS-FEDERATION'] = federated_dict token_reference['token']['user']['OS-FEDERATION'] = federated_dict
del token_reference['token']['user']['password_expires_at'] del token_reference['token']['user']['password_expires_at']
if token.access_token_id: if token.access_token_id:

View File

@ -183,7 +183,6 @@ class ResourceOptionRegistry:
class ResourceOption: class ResourceOption:
def __init__( def __init__(
self, self,
option_id, option_id,

View File

@ -18,6 +18,7 @@ Before using this module, call initialize(). This has to be done before
CONF() because it sets up configuration options. CONF() because it sets up configuration options.
""" """
import datetime import datetime
import functools import functools
@ -117,7 +118,6 @@ ModelBase.__init__ = initialize_decorator(ModelBase.__init__)
# Special Fields # Special Fields
class JsonBlob(sql_types.TypeDecorator): class JsonBlob(sql_types.TypeDecorator):
impl = sql.Text impl = sql.Text
# NOTE(ralonsoh): set to True as any other TypeDecorator in SQLAlchemy # NOTE(ralonsoh): set to True as any other TypeDecorator in SQLAlchemy
# https://docs.sqlalchemy.org/en/14/core/custom_types.html# \ # https://docs.sqlalchemy.org/en/14/core/custom_types.html# \
@ -256,7 +256,6 @@ class ModelDictMixinWithExtras(models.ModelBase):
class ModelDictMixin(models.ModelBase): class ModelDictMixin(models.ModelBase):
@classmethod @classmethod
def from_dict(cls, d): def from_dict(cls, d):
"""Return a model instance from a dictionary.""" """Return a model instance from a dictionary."""
@ -413,13 +412,13 @@ def _filter(model, query, hints):
if filter_['comparator'] == 'contains': if filter_['comparator'] == 'contains':
_WontMatch.check(filter_['value'], column_attr) _WontMatch.check(filter_['value'], column_attr)
query_term = column_attr.ilike('%%%s%%' % filter_['value']) query_term = column_attr.ilike('%{}%'.format(filter_['value']))
elif filter_['comparator'] == 'startswith': elif filter_['comparator'] == 'startswith':
_WontMatch.check(filter_['value'], column_attr) _WontMatch.check(filter_['value'], column_attr)
query_term = column_attr.ilike('%s%%' % filter_['value']) query_term = column_attr.ilike('{}%'.format(filter_['value']))
elif filter_['comparator'] == 'endswith': elif filter_['comparator'] == 'endswith':
_WontMatch.check(filter_['value'], column_attr) _WontMatch.check(filter_['value'], column_attr)
query_term = column_attr.ilike('%%%s' % filter_['value']) query_term = column_attr.ilike('%{}'.format(filter_['value']))
else: else:
# It's a filter we don't understand, so let the caller # It's a filter we don't understand, so let the caller
# work out if they need to do something with it. # work out if they need to do something with it.

View File

@ -51,8 +51,7 @@ def _migration_script_ops(context, directive, phase):
""" """
autogen_kwargs = {} autogen_kwargs = {}
version_path = upgrades.get_version_branch_path( version_path = upgrades.get_version_branch_path(
release=upgrades.CURRENT_RELEASE, release=upgrades.CURRENT_RELEASE, branch=phase
branch=phase,
) )
upgrades.check_bootstrap_new_branch(phase, version_path, autogen_kwargs) upgrades.check_bootstrap_new_branch(phase, version_path, autogen_kwargs)
@ -65,7 +64,7 @@ def _migration_script_ops(context, directive, phase):
), ),
ops.DowngradeOps(ops=[]), ops.DowngradeOps(ops=[]),
message=directive.message, message=directive.message,
**autogen_kwargs **autogen_kwargs,
) )
if not op.upgrade_ops.is_empty(): if not op.upgrade_ops.is_empty():

View File

@ -134,14 +134,10 @@ def do_upgrade(config, cmd):
if revision in upgrades.MILESTONES: if revision in upgrades.MILESTONES:
expand_revisions = _find_milestone_revisions( expand_revisions = _find_milestone_revisions(
config, config, revision, upgrades.EXPAND_BRANCH
revision,
upgrades.EXPAND_BRANCH,
) )
contract_revisions = _find_milestone_revisions( contract_revisions = _find_milestone_revisions(
config, config, revision, upgrades.CONTRACT_BRANCH
revision,
upgrades.CONTRACT_BRANCH,
) )
# Expand revisions must be run before contract revisions # Expand revisions must be run before contract revisions
revisions = expand_revisions + contract_revisions revisions = expand_revisions + contract_revisions
@ -152,10 +148,7 @@ def do_upgrade(config, cmd):
# if not CONF.command.sql: # if not CONF.command.sql:
# run_sanity_checks(config, revision) # run_sanity_checks(config, revision)
do_alembic_command( do_alembic_command(
config, config, cmd, revision=revision, sql=CONF.command.sql
cmd,
revision=revision,
sql=CONF.command.sql,
) )
@ -179,8 +172,7 @@ def do_revision(config, cmd):
for branch in branches: for branch in branches:
args = copy.copy(kwargs) args = copy.copy(kwargs)
version_path = upgrades.get_version_branch_path( version_path = upgrades.get_version_branch_path(
release=upgrades.CURRENT_RELEASE, release=upgrades.CURRENT_RELEASE, branch=branch
branch=branch,
) )
upgrades.check_bootstrap_new_branch(branch, version_path, args) upgrades.check_bootstrap_new_branch(branch, version_path, args)
do_alembic_command(config, cmd, **args) do_alembic_command(config, cmd, **args)

View File

@ -46,8 +46,7 @@ def upgrade():
if bind.engine.name == 'mysql': if bind.engine.name == 'mysql':
# Set default DB charset to UTF8. # Set default DB charset to UTF8.
op.execute( op.execute(
'ALTER DATABASE %s DEFAULT CHARACTER SET utf8' f'ALTER DATABASE {bind.engine.url.database} DEFAULT CHARACTER SET utf8'
% bind.engine.url.database
) )
op.create_table( op.create_table(
@ -89,11 +88,7 @@ def upgrade():
sql.Column('role_id', sql.String(64), nullable=False), sql.Column('role_id', sql.String(64), nullable=False),
sql.Column('inherited', sql.Boolean, default=False, nullable=False), sql.Column('inherited', sql.Boolean, default=False, nullable=False),
sql.PrimaryKeyConstraint( sql.PrimaryKeyConstraint(
'type', 'type', 'actor_id', 'target_id', 'role_id', 'inherited'
'actor_id',
'target_id',
'role_id',
'inherited',
), ),
sql.Index('ix_actor_id', 'actor_id'), sql.Index('ix_actor_id', 'actor_id'),
mysql_engine='InnoDB', mysql_engine='InnoDB',
@ -109,8 +104,7 @@ def upgrade():
sql.Column('external_id', sql.String(64)), sql.Column('external_id', sql.String(64)),
sql.Column('user_id', sql.String(64)), sql.Column('user_id', sql.String(64)),
sql.UniqueConstraint( sql.UniqueConstraint(
'external_id', 'external_id', name='access_rule_external_id_key'
name='access_rule_external_id_key',
), ),
sql.UniqueConstraint( sql.UniqueConstraint(
'user_id', 'user_id',
@ -149,11 +143,7 @@ def upgrade():
sql.Column('type', sql.String(length=255), nullable=False), sql.Column('type', sql.String(length=255), nullable=False),
sql.Column('extra', ks_sql.JsonBlob.impl), sql.Column('extra', ks_sql.JsonBlob.impl),
sql.Column('key_hash', sql.String(64), nullable=False), sql.Column('key_hash', sql.String(64), nullable=False),
sql.Column( sql.Column('encrypted_blob', ks_sql.Text, nullable=False),
'encrypted_blob',
ks_sql.Text,
nullable=False,
),
mysql_engine='InnoDB', mysql_engine='InnoDB',
mysql_charset='utf8', mysql_charset='utf8',
) )
@ -166,9 +156,7 @@ def upgrade():
sql.Column('description', sql.Text), sql.Column('description', sql.Text),
sql.Column('extra', ks_sql.JsonBlob.impl), sql.Column('extra', ks_sql.JsonBlob.impl),
sql.UniqueConstraint( sql.UniqueConstraint(
'domain_id', 'domain_id', 'name', name='ixu_group_name_domain_id'
'name',
name='ixu_group_name_domain_id',
), ),
mysql_engine='InnoDB', mysql_engine='InnoDB',
mysql_charset='utf8', mysql_charset='utf8',
@ -189,10 +177,7 @@ def upgrade():
nullable=False, nullable=False,
), ),
sql.UniqueConstraint( sql.UniqueConstraint(
'domain_id', 'domain_id', 'local_id', 'entity_type', name='domain_id'
'local_id',
'entity_type',
name='domain_id',
), ),
mysql_engine='InnoDB', mysql_engine='InnoDB',
mysql_charset='utf8', mysql_charset='utf8',
@ -261,19 +246,13 @@ def upgrade():
sql.Column( sql.Column(
'domain_id', 'domain_id',
sql.String(length=64), sql.String(length=64),
sql.ForeignKey( sql.ForeignKey('project.id', name='project_domain_id_fkey'),
'project.id',
name='project_domain_id_fkey',
),
nullable=False, nullable=False,
), ),
sql.Column( sql.Column(
'parent_id', 'parent_id',
sql.String(64), sql.String(64),
sql.ForeignKey( sql.ForeignKey('project.id', name='project_parent_id_fkey'),
'project.id',
name='project_parent_id_fkey',
),
nullable=True, nullable=True,
), ),
sql.Column( sql.Column(
@ -284,9 +263,7 @@ def upgrade():
default=False, default=False,
), ),
sql.UniqueConstraint( sql.UniqueConstraint(
'domain_id', 'domain_id', 'name', name='ixu_project_name_domain_id'
'name',
name='ixu_project_name_domain_id',
), ),
mysql_engine='InnoDB', mysql_engine='InnoDB',
mysql_charset='utf8', mysql_charset='utf8',
@ -439,9 +416,7 @@ def upgrade():
), ),
sql.Column('description', sql.String(255), nullable=True), sql.Column('description', sql.String(255), nullable=True),
sql.UniqueConstraint( sql.UniqueConstraint(
'name', 'name', 'domain_id', name='ixu_role_name_domain_id'
'domain_id',
name='ixu_role_name_domain_id',
), ),
mysql_engine='InnoDB', mysql_engine='InnoDB',
mysql_charset='utf8', mysql_charset='utf8',
@ -558,16 +533,8 @@ def upgrade():
'expires_at_int', 'expires_at_int',
name='duplicate_trust_constraint_expanded', name='duplicate_trust_constraint_expanded',
), ),
sql.Column( sql.Column('redelegated_trust_id', sql.String(64), nullable=True),
'redelegated_trust_id', sql.Column('redelegation_count', sql.Integer, nullable=True),
sql.String(64),
nullable=True,
),
sql.Column(
'redelegation_count',
sql.Integer,
nullable=True,
),
mysql_engine='InnoDB', mysql_engine='InnoDB',
mysql_charset='utf8', mysql_charset='utf8',
) )
@ -604,18 +571,14 @@ def upgrade():
sql.Column( sql.Column(
'user_id', 'user_id',
sql.String(length=64), sql.String(length=64),
sql.ForeignKey( sql.ForeignKey('user.id', name='fk_user_group_membership_user_id'),
'user.id',
name='fk_user_group_membership_user_id',
),
primary_key=True, primary_key=True,
), ),
sql.Column( sql.Column(
'group_id', 'group_id',
sql.String(length=64), sql.String(length=64),
sql.ForeignKey( sql.ForeignKey(
'group.id', 'group.id', name='fk_user_group_membership_group_id'
name='fk_user_group_membership_group_id',
), ),
primary_key=True, primary_key=True,
), ),
@ -720,10 +683,7 @@ def upgrade():
sql.Column( sql.Column(
'service_id', 'service_id',
sql.String(length=64), sql.String(length=64),
sql.ForeignKey( sql.ForeignKey('service.id', name='endpoint_service_id_fkey'),
'service.id',
name='endpoint_service_id_fkey',
),
nullable=False, nullable=False,
), ),
sql.Column('url', sql.Text, nullable=False), sql.Column('url', sql.Text, nullable=False),
@ -738,10 +698,7 @@ def upgrade():
sql.Column( sql.Column(
'region_id', 'region_id',
sql.String(length=255), sql.String(length=255),
sql.ForeignKey( sql.ForeignKey('region.id', name='fk_endpoint_region_id'),
'region.id',
name='fk_endpoint_region_id',
),
nullable=True, nullable=True,
), ),
# NOTE(stevemar): The index was named 'service_id' in # NOTE(stevemar): The index was named 'service_id' in
@ -835,10 +792,7 @@ def upgrade():
# FIXME(stephenfin): This should have a foreign key constraint on # FIXME(stephenfin): This should have a foreign key constraint on
# registered_limit.id, but sqlalchemy-migrate clearly didn't handle # registered_limit.id, but sqlalchemy-migrate clearly didn't handle
# creating a column with embedded FK info as was attempted in 048 # creating a column with embedded FK info as was attempted in 048
sql.Column( sql.Column('registered_limit_id', sql.String(64)),
'registered_limit_id',
sql.String(64),
),
sql.Column('domain_id', sql.String(64), nullable=True), sql.Column('domain_id', sql.String(64), nullable=True),
# NOTE(stephenfin): Name chosen to preserve backwards compatibility # NOTE(stephenfin): Name chosen to preserve backwards compatibility
# with names used for primary key unique constraints # with names used for primary key unique constraints
@ -850,12 +804,7 @@ def upgrade():
op.create_table( op.create_table(
'local_user', 'local_user',
sql.Column('id', sql.Integer, primary_key=True, nullable=False), sql.Column('id', sql.Integer, primary_key=True, nullable=False),
sql.Column( sql.Column('user_id', sql.String(64), nullable=False, unique=True),
'user_id',
sql.String(64),
nullable=False,
unique=True,
),
sql.Column('domain_id', sql.String(64), nullable=False), sql.Column('domain_id', sql.String(64), nullable=False),
sql.Column('name', sql.String(255), nullable=False), sql.Column('name', sql.String(255), nullable=False),
sql.Column('failed_auth_count', sql.Integer, nullable=True), sql.Column('failed_auth_count', sql.Integer, nullable=True),
@ -874,11 +823,7 @@ def upgrade():
'nonlocal_user', 'nonlocal_user',
sql.Column('domain_id', sql.String(64), primary_key=True), sql.Column('domain_id', sql.String(64), primary_key=True),
sql.Column('name', sql.String(255), primary_key=True), sql.Column('name', sql.String(255), primary_key=True),
sql.Column( sql.Column('user_id', sql.String(64), nullable=False),
'user_id',
sql.String(64),
nullable=False,
),
sql.ForeignKeyConstraint( sql.ForeignKeyConstraint(
['user_id', 'domain_id'], ['user_id', 'domain_id'],
['user.id', 'user.domain_id'], ['user.id', 'user.domain_id'],
@ -974,10 +919,7 @@ def upgrade():
# only for sqlite, once we collapse 073 we can remove this constraint # only for sqlite, once we collapse 073 we can remove this constraint
with op.batch_alter_table('assignment') as batch_op: with op.batch_alter_table('assignment') as batch_op:
batch_op.create_foreign_key( batch_op.create_foreign_key(
'fk_assignment_role_id', 'fk_assignment_role_id', 'role', ['role_id'], ['id']
'role',
['role_id'],
['id'],
) )
# TODO(stephenfin): Remove these procedures in a future contract migration # TODO(stephenfin): Remove these procedures in a future contract migration
@ -1064,9 +1006,7 @@ def upgrade():
# FIXME(stephenfin): This should be dropped when we add the FK # FIXME(stephenfin): This should be dropped when we add the FK
# constraint to this column # constraint to this column
op.create_index( op.create_index(
'registered_limit_id', 'registered_limit_id', 'limit', ['registered_limit_id']
'limit',
['registered_limit_id'],
) )
# FIXME(stephenfin): These are leftover from when we removed a FK # FIXME(stephenfin): These are leftover from when we removed a FK

View File

@ -28,7 +28,4 @@ depends_on = None
def upgrade(): def upgrade():
with op.batch_alter_table('service_provider', schema=None) as batch_op: with op.batch_alter_table('service_provider', schema=None) as batch_op:
batch_op.alter_column( batch_op.alter_column('relay_state_prefix', server_default=None)
'relay_state_prefix',
server_default=None,
)

View File

@ -36,11 +36,7 @@ EXPAND_BRANCH = 'expand'
DATA_MIGRATION_BRANCH = 'data_migration' DATA_MIGRATION_BRANCH = 'data_migration'
CONTRACT_BRANCH = 'contract' CONTRACT_BRANCH = 'contract'
RELEASES = ( RELEASES = ('yoga', 'bobcat', '2024.01')
'yoga',
'bobcat',
'2024.01',
)
MILESTONES = ( MILESTONES = (
'yoga', 'yoga',
# Do not add the milestone until the end of the release # Do not add the milestone until the end of the release
@ -48,9 +44,7 @@ MILESTONES = (
CURRENT_RELEASE = RELEASES[-1] CURRENT_RELEASE = RELEASES[-1]
MIGRATION_BRANCHES = (EXPAND_BRANCH, CONTRACT_BRANCH) MIGRATION_BRANCHES = (EXPAND_BRANCH, CONTRACT_BRANCH)
VERSIONS_PATH = os.path.join( VERSIONS_PATH = os.path.join(
os.path.dirname(sql.__file__), os.path.dirname(sql.__file__), 'migrations', 'versions'
'migrations',
'versions',
) )
@ -77,8 +71,7 @@ def _find_alembic_conf():
:returns: An instance of ``alembic.config.Config`` :returns: An instance of ``alembic.config.Config``
""" """
path = os.path.join( path = os.path.join(
os.path.abspath(os.path.dirname(__file__)), os.path.abspath(os.path.dirname(__file__)), 'alembic.ini'
'alembic.ini',
) )
config = alembic_config.Config(os.path.abspath(path)) config = alembic_config.Config(os.path.abspath(path))

View File

@ -66,9 +66,7 @@ check_password = password_hashing.check_password
# NOTE(hiromu): This dict defines alternative DN string for X.509. When # NOTE(hiromu): This dict defines alternative DN string for X.509. When
# retriving DN from X.509, converting attributes types that are not listed # retriving DN from X.509, converting attributes types that are not listed
# in the RFC4514 to a corresponding alternative DN string. # in the RFC4514 to a corresponding alternative DN string.
ATTR_NAME_OVERRIDES = { ATTR_NAME_OVERRIDES = {x509.NameOID.EMAIL_ADDRESS: "emailAddress"}
x509.NameOID.EMAIL_ADDRESS: "emailAddress",
}
def resource_uuid(value): def resource_uuid(value):
@ -217,7 +215,7 @@ def get_unix_user(user=None):
try: try:
i = int(user) i = int(user)
except ValueError: except ValueError:
raise KeyError("user name '%s' not found" % user) raise KeyError(f"user name '{user}' not found")
try: try:
user_info = pwd.getpwuid(i) user_info = pwd.getpwuid(i)
except KeyError: except KeyError:
@ -232,8 +230,7 @@ def get_unix_user(user=None):
else: else:
user_cls_name = reflection.get_class_name(user, fully_qualified=False) user_cls_name = reflection.get_class_name(user, fully_qualified=False)
raise TypeError( raise TypeError(
'user must be string, int or None; not %s (%r)' f'user must be string, int or None; not {user_cls_name} ({user!r})'
% (user_cls_name, user)
) )
return user_info.pw_uid, user_info.pw_name return user_info.pw_uid, user_info.pw_name
@ -278,7 +275,7 @@ def get_unix_group(group=None):
try: try:
i = int(group) i = int(group)
except ValueError: except ValueError:
raise KeyError("group name '%s' not found" % group) raise KeyError(f"group name '{group}' not found")
try: try:
group_info = grp.getgrgid(i) group_info = grp.getgrgid(i)
except KeyError: except KeyError:
@ -295,15 +292,13 @@ def get_unix_group(group=None):
group, fully_qualified=False group, fully_qualified=False
) )
raise TypeError( raise TypeError(
'group must be string, int or None; not %s (%r)' f'group must be string, int or None; not {group_cls_name} ({group!r})'
% (group_cls_name, group)
) )
return group_info.gr_gid, group_info.gr_name return group_info.gr_gid, group_info.gr_name
class WhiteListedItemFilter: class WhiteListedItemFilter:
def __init__(self, whitelist, data): def __init__(self, whitelist, data):
self._whitelist = set(whitelist or []) self._whitelist = set(whitelist or [])
self._data = data self._data = data

View File

@ -105,10 +105,7 @@ def set_default_for_default_log_levels():
This function needs to be called before CONF(). This function needs to be called before CONF().
""" """
extra_log_level_defaults = [ extra_log_level_defaults = ['dogpile=INFO', 'routes=INFO']
'dogpile=INFO',
'routes=INFO',
]
log.register_options(CONF) log.register_options(CONF)
log.set_defaults( log.set_defaults(

View File

@ -63,12 +63,7 @@ keystone database or open keystone to a DoS attack.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver, caching, cache_time, user_limit]
driver,
caching,
cache_time,
user_limit,
]
def register_opts(conf): def register_opts(conf):

View File

@ -75,13 +75,7 @@ have enough services or endpoints to exceed a reasonable limit.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [template_file, driver, caching, cache_time, list_limit]
template_file,
driver,
caching,
cache_time,
list_limit,
]
def register_opts(conf): def register_opts(conf):

View File

@ -16,7 +16,6 @@ package.
""" """
_DEFAULT_AUTH_METHODS = [ _DEFAULT_AUTH_METHODS = [
'external', 'external',
'password', 'password',

View File

@ -42,10 +42,7 @@ catalog. If set to false, keystone will return an empty service catalog.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver, return_all_endpoints_if_no_filter]
driver,
return_all_endpoints_if_no_filter,
]
def register_opts(conf): def register_opts(conf):

View File

@ -28,9 +28,7 @@ to set this unless you are providing a custom entry point.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver]
driver,
]
def register_opts(conf): def register_opts(conf):

View File

@ -62,10 +62,7 @@ this value means that additional secondary keys will be kept in the rotation.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [key_repository, max_active_keys]
key_repository,
max_active_keys,
]
def register_opts(conf): def register_opts(conf):

View File

@ -60,10 +60,7 @@ this value means that additional secondary keys will be kept in the rotation.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [key_repository, max_active_keys]
key_repository,
max_active_keys,
]
def register_opts(conf): def register_opts(conf):

View File

@ -67,11 +67,7 @@ recommended value.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver, generator, backward_compatible_ids]
driver,
generator,
backward_compatible_ids,
]
def register_opts(conf): def register_opts(conf):

View File

@ -55,11 +55,7 @@ means that access tokens will last forever.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver, request_token_duration, access_token_duration]
driver,
request_token_duration,
access_token_duration,
]
def register_opts(conf): def register_opts(conf):

View File

@ -47,7 +47,7 @@ def list_opts():
def _tupleize(d): def _tupleize(d):
"""Convert a dict of options to the 2-tuple format.""" """Convert a dict of options to the 2-tuple format."""
return [(key, value) for key, value in d.items()] return list(d.items())
def _list_module_names(): def _list_module_names():
@ -69,9 +69,8 @@ def _import_modules(module_names):
module = importlib.import_module(full_module_path) module = importlib.import_module(full_module_path)
if not hasattr(module, LIST_OPTS_FUNC_NAME): if not hasattr(module, LIST_OPTS_FUNC_NAME):
raise Exception( raise Exception(
"The module '%s' should have a '%s' function which " f"The module '{full_module_path}' should have a '{LIST_OPTS_FUNC_NAME}' function which "
"returns the config options." "returns the config options."
% (full_module_path, LIST_OPTS_FUNC_NAME)
) )
else: else:
imported_modules.append(module) imported_modules.append(module)

View File

@ -38,10 +38,7 @@ Maximum number of entities that will be returned in a policy collection.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver, list_limit]
driver,
list_limit,
]
def register_opts(conf): def register_opts(conf):

View File

@ -83,13 +83,7 @@ has no effect unless global caching and receipt caching are enabled.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [expiration, provider, caching, cache_time, cache_on_issue]
expiration,
provider,
caching,
cache_time,
cache_on_issue,
]
def register_opts(conf): def register_opts(conf):

View File

@ -65,12 +65,7 @@ has no effect unless global and `[revoke] caching` are both enabled.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver, expiration_buffer, caching, cache_time]
driver,
expiration_buffer,
caching,
cache_time,
]
def register_opts(conf): def register_opts(conf):

View File

@ -61,12 +61,7 @@ deployment.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver, caching, cache_time, list_limit]
driver,
caching,
cache_time,
list_limit,
]
def register_opts(conf): def register_opts(conf):

View File

@ -30,9 +30,7 @@ this option unless you are providing a custom entry point.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver]
driver,
]
def register_opts(conf): def register_opts(conf):

View File

@ -61,11 +61,7 @@ this value.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [trusted_issuer, protocol, issuer_attribute]
trusted_issuer,
protocol,
issuer_attribute,
]
def register_opts(conf): def register_opts(conf):

View File

@ -28,9 +28,7 @@ The number of previous windows to check when processing TOTP passcodes.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [included_previous_windows]
included_previous_windows,
]
def register_opts(conf): def register_opts(conf):

View File

@ -52,11 +52,7 @@ unless you are providing a custom entry point.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [allow_redelegation, max_redelegation_count, driver]
allow_redelegation,
max_redelegation_count,
driver,
]
def register_opts(conf): def register_opts(conf):

View File

@ -74,13 +74,7 @@ running deployment.
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [driver, caching, cache_time, list_limit, enforcement_model]
driver,
caching,
cache_time,
list_limit,
enforcement_model,
]
def register_opts(conf): def register_opts(conf):

View File

@ -39,9 +39,7 @@ SENSITIVE/PRIVILEGED DATA.
) )
GROUP_NAME = __name__.split('.')[-1] GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [ ALL_OPTS = [debug_middleware]
debug_middleware,
]
def register_opts(conf): def register_opts(conf):

View File

@ -54,7 +54,6 @@ class CredentialModel(sql.ModelBase, sql.ModelDictMixinWithExtras):
class Credential(base.CredentialDriverBase): class Credential(base.CredentialDriverBase):
# credential crud # credential crud
@sql.handle_conflicts(conflict_type='credential') @sql.handle_conflicts(conflict_type='credential')

View File

@ -50,7 +50,7 @@ class Manager(manager.Manager):
if credential['type'] == 'ec2': if credential['type'] == 'ec2':
decrypted_blob = json.loads( decrypted_blob = json.loads(
PROVIDERS.credential_provider_api.decrypt( PROVIDERS.credential_provider_api.decrypt(
credential['encrypted_blob'], credential['encrypted_blob']
) )
) )
else: else:

View File

@ -17,7 +17,6 @@ CONF = keystone.conf.CONF
class Manager(manager.Manager): class Manager(manager.Manager):
driver_namespace = 'keystone.credential.provider' driver_namespace = 'keystone.credential.provider'
_provides_api = 'credential_provider_api' _provides_api = 'credential_provider_api'

View File

@ -85,7 +85,7 @@ class Provider(core.Provider):
primary_key_hash(keys), primary_key_hash(keys),
) )
except (TypeError, ValueError) as e: except (TypeError, ValueError) as e:
msg = 'Credential could not be encrypted: %s' % str(e) msg = f'Credential could not be encrypted: {str(e)}'
tr_msg = _('Credential could not be encrypted: %s') % str(e) tr_msg = _('Credential could not be encrypted: %s') % str(e)
LOG.error(msg) LOG.error(msg)
raise exception.CredentialEncryptionError(tr_msg) raise exception.CredentialEncryptionError(tr_msg)

View File

@ -135,7 +135,7 @@ update_request_body: dict[str, Any] = {
"properties": _credential_properties, "properties": _credential_properties,
"additionalProperties": True, "additionalProperties": True,
"minProperties": 1, "minProperties": 1,
}, }
}, },
"required": ["credential"], "required": ["credential"],
} }

View File

@ -50,7 +50,6 @@ class PolicyAssociation(sql.ModelBase, sql.ModelDictMixin):
class EndpointPolicy(base.EndpointPolicyDriverBase): class EndpointPolicy(base.EndpointPolicyDriverBase):
def create_policy_association( def create_policy_association(
self, policy_id, endpoint_id=None, service_id=None, region_id=None self, policy_id, endpoint_id=None, service_id=None, region_id=None
): ):

View File

@ -97,7 +97,6 @@ class Manager(manager.Manager):
) )
def list_endpoints_for_policy(self, policy_id): def list_endpoints_for_policy(self, policy_id):
def _get_endpoint(endpoint_id, policy_id): def _get_endpoint(endpoint_id, policy_id):
try: try:
return PROVIDERS.catalog_api.get_endpoint(endpoint_id) return PROVIDERS.catalog_api.get_endpoint(endpoint_id)
@ -235,7 +234,6 @@ class Manager(manager.Manager):
return matching_endpoints return matching_endpoints
def get_policy_for_endpoint(self, endpoint_id): def get_policy_for_endpoint(self, endpoint_id):
def _get_policy(policy_id, endpoint_id): def _get_policy(policy_id, endpoint_id):
try: try:
return PROVIDERS.policy_api.get_policy(policy_id) return PROVIDERS.policy_api.get_policy(policy_id)

Some files were not shown because too many files have changed in this diff Show More