def assert_admin(self, context): if not context['is_admin']: try: user_token_ref = self.token_api.get_token( context=context, token_id=context['token_id']) except exception.TokenNotFound as e: raise exception.Unauthorized(e) creds = user_token_ref['metadata'].copy() try: creds['user_id'] = user_token_ref['user'].get('id') except AttributeError: logging.debug('Invalid user') raise exception.Unauthorized() try: creds['tenant_id'] = user_token_ref['tenant'].get('id') except AttributeError: logging.debug('Invalid tenant') raise exception.Unauthorized() # NOTE(vish): this is pretty inefficient creds['roles'] = [self.identity_api.get_role(context, role)['name'] for role in creds.get('roles', [])] # Accept either is_admin or the admin role self.policy_api.enforce(context, creds, 'admin_required', {})
def check_output(*popenargs, **kwargs): r"""Run command with arguments and return its output as a byte string. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example: >>> check_output(["ls", "-l", "/dev/null"]) 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' The stdout argument is not allowed as it is used internally. To capture standard error in the result, use stderr=STDOUT. >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], ... stderr=STDOUT) 'ls: non_existent_file: No such file or directory\n' """ if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be overridden.') logging.debug(' '.join(popenargs[0])) process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) output, unused_err = process.communicate() retcode = process.poll() if retcode: cmd = kwargs.get("args") if cmd is None: cmd = popenargs[0] raise subprocess.CalledProcessError(retcode, cmd) return output
def assert_admin(self, context): if not context["is_admin"]: try: user_token_ref = self.token_api.get_token(context=context, token_id=context["token_id"]) except exception.TokenNotFound: raise exception.Unauthorized() creds = user_token_ref["metadata"].copy() try: creds["user_id"] = user_token_ref["user"].get("id") except AttributeError: logging.debug("Invalid user") raise exception.Unauthorized() try: creds["tenant_id"] = user_token_ref["tenant"].get("id") except AttributeError: logging.debug("Invalid tenant") raise exception.Unauthorized() # NOTE(vish): this is pretty inefficient creds["roles"] = [self.identity_api.get_role(context, role)["name"] for role in creds.get("roles", [])] # Accept either is_admin or the admin role self.policy_api.enforce(context, creds, "admin_required", {})
def set_user_password(self, context, user_id, user): token_id = context.get('token_id') original_password = user.get('original_password') token_ref = self.token_api.get_token(token_id) user_id_from_token = token_ref['user']['id'] if user_id_from_token != user_id: raise exception.Forbidden('Token belongs to another user') if original_password is None: raise exception.ValidationError(target='user', attribute='original password') try: user_ref = self.identity_api.authenticate( user_id=user_id_from_token, password=original_password) if not user_ref.get('enabled', True): # NOTE(dolph): why can't you set a disabled user's password? raise exception.Unauthorized('User is disabled') except AssertionError: raise exception.Unauthorized() update_dict = {'password': user['password'], 'id': user_id} admin_context = copy.copy(context) admin_context['is_admin'] = True super(UserController, self).set_user_password(admin_context, user_id, update_dict) token_id = uuid.uuid4().hex new_token_ref = copy.copy(token_ref) new_token_ref['id'] = token_id self.token_api.create_token(token_id, new_token_ref) logging.debug('TOKEN_REF %s', new_token_ref) return {'access': {'token': new_token_ref}}
def assert_admin(self, context): if not context['is_admin']: try: user_token_ref = self.token_api.get_token( context=context, token_id=context['token_id']) except exception.TokenNotFound: raise exception.Unauthorized() creds = user_token_ref['metadata'].copy() try: creds['user_id'] = user_token_ref['user'].get('id') except AttributeError: logging.debug('Invalid user') raise exception.Unauthorized() try: creds['tenant_id'] = user_token_ref['tenant'].get('id') except AttributeError: logging.debug('Invalid tenant') raise exception.Unauthorized() # NOTE(vish): this is pretty inefficient creds['roles'] = [ self.identity_api.get_role(context, role)['name'] for role in creds.get('roles', []) ] # Accept either is_admin or the admin role self.policy_api.enforce(context, creds, 'admin_required', {})
def _calc_signature_2(self, params, verb, server_string, path): """Generate AWS signature version 2 string.""" logging.debug('using _calc_signature_2') string_to_sign = '%s\n%s\n%s\n' % (verb, server_string, path) if self.hmac_256: current_hmac = self.hmac_256 params['SignatureMethod'] = 'HmacSHA256' else: current_hmac = self.hmac params['SignatureMethod'] = 'HmacSHA1' keys = params.keys() keys.sort() pairs = [] for key in keys: val = self._get_utf8_value(params[key]) val = urllib.quote(val, safe='-_~') pairs.append(urllib.quote(key, safe='') + '=' + val) qs = '&'.join(pairs) logging.debug('query string: %s', qs) string_to_sign += qs logging.debug('string_to_sign: %s', string_to_sign) current_hmac.update(string_to_sign) b64 = base64.b64encode(current_hmac.digest()) logging.debug('len(b64)=%d', len(b64)) logging.debug('base64 encoded digest: %s', b64) return b64
def set_user_password(self, context, user_id, user): token_id = context.get("token_id") original_password = user.get("original_password") token_ref = self.token_api.get_token(token_id) user_id_from_token = token_ref["user"]["id"] if user_id_from_token != user_id: raise exception.Forbidden("Token belongs to another user") if original_password is None: raise exception.ValidationError(target="user", attribute="original password") try: user_ref = self.identity_api.authenticate(user_id=user_id_from_token, password=original_password) if not user_ref.get("enabled", True): # NOTE(dolph): why can't you set a disabled user's password? raise exception.Unauthorized("User is disabled") except AssertionError: raise exception.Unauthorized() update_dict = {"password": user["password"], "id": user_id} admin_context = copy.copy(context) admin_context["is_admin"] = True super(UserController, self).set_user_password(admin_context, user_id, update_dict) token_id = uuid.uuid4().hex new_token_ref = copy.copy(token_ref) new_token_ref["id"] = token_id self.token_api.create_token(token_id, new_token_ref) logging.debug("TOKEN_REF %s", new_token_ref) return {"access": {"token": new_token_ref}}
def import_class(import_str): """Returns a class from a string including module and class.""" mod_str, _sep, class_str = import_str.rpartition('.') try: __import__(mod_str) return getattr(sys.modules[mod_str], class_str) except (ImportError, ValueError, AttributeError), exc: logging.debug('Inner Exception: %s', exc) raise
def test_authenticate_scoped(self): # NOTE(termie): the docs arbitrarily changed and inserted a 'u' in front # of one of the user ids, but none of the others raise exc.SkipTest('The docs have arbitrarily changed.') client = self.client(self.app) post_data = json.dumps( {'auth': {'passwordCredentials': {'username': self.user_123['id'], 'password': self.user_123['password'], }, 'tenantName': self.tenant_345['name']}}) resp = client.post('/v2.0/tokens', body=post_data) data = json.loads(resp.body) logging.debug('KEYS: %s', data['access'].keys()) self.assert_('expires' in data['access']['token']) self.assertDeepEquals(self.auth_response['access']['user'], data['access']['user'])
def set_user_password(self, context, user_id, user): token_id = context.get('token_id') original_password = user.get('original_password') token_ref = self.token_api.get_token(context=context, token_id=token_id) user_id_from_token = token_ref['user']['id'] if user_id_from_token != user_id: raise exception.Forbidden('Token belongs to another user') if original_password is None: raise exception.ValidationError(target='user', attribute='original password') try: user_ref = self.identity_api.authenticate( context=context, user_id=user_id_from_token, password=original_password)[0] if not user_ref.get('enabled', True): # NOTE(dolph): why can't you set a disabled user's password? raise exception.Unauthorized('User is disabled') except AssertionError: raise exception.Unauthorized() update_dict = {'password': user['password'], 'id': user_id} admin_context = copy.copy(context) admin_context['is_admin'] = True super(UserController, self).set_user_password(admin_context, user_id, update_dict) token_id = uuid.uuid4().hex new_token_ref = copy.copy(token_ref) new_token_ref['id'] = token_id self.token_api.create_token(context=context, token_id=token_id, data=new_token_ref) logging.debug('TOKEN_REF %s', new_token_ref) return {'access': {'token': new_token_ref}}
def set_user_password(self, context, user_id, user): token_id = context.get('token_id') original_password = user.get('original_password') token_ref = self.token_api.get_token(context=context, token_id=token_id) user_id_from_token = token_ref['user']['id'] if user_id_from_token != user_id or original_password is None: raise exception.Forbidden() try: user_ref = self.identity_api.authenticate( context=context, user_id=user_id_from_token, password=original_password)[0] if not user_ref.get('enabled', True): raise exception.Unauthorized() except AssertionError: raise exception.Unauthorized() update_dict = {'password': user['password'], 'id': user_id} admin_context = copy.copy(context) admin_context['is_admin'] = True self.user_controller.set_user_password(admin_context, user_id, update_dict) token_id = uuid.uuid4().hex new_token_ref = copy.copy(token_ref) new_token_ref['id'] = token_id self.token_api.create_token(context=context, token_id=token_id, data=new_token_ref) logging.debug('TOKEN_REF %s', new_token_ref) return {'access': {'token': new_token_ref}}
def authenticate(self, context, auth=None): """Authenticate credentials and return a token. Accept auth as a dict that looks like:: { "auth":{ "passwordCredentials":{ "username":"******", "password":"******" }, "tenantName":"customer-x" } } In this case, tenant is optional, if not provided the token will be considered "unscoped" and can later be used to get a scoped token. Alternatively, this call accepts auth with only a token and tenant that will return a token that is scoped to that tenant. """ token_id = uuid.uuid4().hex if 'passwordCredentials' in auth: username = auth['passwordCredentials'].get('username', '') password = auth['passwordCredentials'].get('password', '') tenant_name = auth.get('tenantName', None) user_id = auth['passwordCredentials'].get('userId', None) if username: user_ref = self.identity_api.get_user_by_name( context=context, user_name=username) if user_ref: user_id = user_ref['id'] # more compat tenant_id = auth.get('tenantId', None) if tenant_name: tenant_ref = self.identity_api.get_tenant_by_name( context=context, tenant_name=tenant_name) if tenant_ref: tenant_id = tenant_ref['id'] try: auth_info = self.identity_api.authenticate(context=context, user_id=user_id, password=password, tenant_id=tenant_id) (user_ref, tenant_ref, metadata_ref) = auth_info # If the user is disabled don't allow them to authenticate if not user_ref.get('enabled', True): LOG.warning('User %s is disabled' % user_id) raise exception.Unauthorized() except AssertionError as e: raise exception.Unauthorized(e.message) token_ref = self.token_api.create_token( context, token_id, dict(id=token_id, user=user_ref, tenant=tenant_ref, metadata=metadata_ref)) if tenant_ref: catalog_ref = self.catalog_api.get_catalog( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id'], metadata=metadata_ref) else: catalog_ref = {} elif 'token' in auth: token = auth['token'].get('id', None) tenant_name = auth.get('tenantName') # more compat if tenant_name: tenant_ref = self.identity_api.get_tenant_by_name( context=context, tenant_name=tenant_name) tenant_id = tenant_ref['id'] else: tenant_id = auth.get('tenantId', None) try: old_token_ref = self.token_api.get_token(context=context, token_id=token) except exception.NotFound: raise exception.Unauthorized() user_ref = old_token_ref['user'] # If the user is disabled don't allow them to authenticate current_user_ref = self.identity_api.get_user( context=context, user_id=user_ref['id']) if not current_user_ref.get('enabled', True): LOG.warning('User %s is disabled' % user_ref['id']) raise exception.Unauthorized() tenants = self.identity_api.get_tenants_for_user(context, user_ref['id']) if tenant_id: assert tenant_id in tenants tenant_ref = self.identity_api.get_tenant(context=context, tenant_id=tenant_id) if tenant_ref: metadata_ref = self.identity_api.get_metadata( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id']) catalog_ref = self.catalog_api.get_catalog( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id'], metadata=metadata_ref) else: metadata_ref = {} catalog_ref = {} token_ref = self.token_api.create_token( context, token_id, dict(id=token_id, user=user_ref, tenant=tenant_ref, metadata=metadata_ref)) # TODO(termie): optimize this call at some point and put it into the # the return for metadata # fill out the roles in the metadata roles_ref = [] for role_id in metadata_ref.get('roles', []): roles_ref.append(self.identity_api.get_role(context, role_id)) logging.debug('TOKEN_REF %s', token_ref) return self._format_authenticate(token_ref, roles_ref, catalog_ref)
def authenticate(self, context, auth=None): """Authenticate credentials and return a token. Accept auth as a dict that looks like:: { "auth":{ "passwordCredentials":{ "username":"******", "password":"******" }, "tenantName":"customer-x" } } In this case, tenant is optional, if not provided the token will be considered "unscoped" and can later be used to get a scoped token. Alternatively, this call accepts auth with only a token and tenant that will return a token that is scoped to that tenant. """ token_id = uuid.uuid4().hex if 'passwordCredentials' in auth: username = auth['passwordCredentials'].get('username', '') if len(username) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='username', size=CONF.max_param_size) password = auth['passwordCredentials'].get('password', '') max_pw_size = utils.MAX_PASSWORD_LENGTH if len(password) > max_pw_size: raise exception.ValidationSizeError(attribute='password', size=max_pw_size) tenant_name = auth.get('tenantName', None) if tenant_name and len(tenant_name) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantName', size=CONF.max_param_size) user_id = auth['passwordCredentials'].get('userId', None) if user_id and len(user_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='userId', size=CONF.max_param_size) if username: user_ref = self.identity_api.get_user_by_name( context=context, user_name=username) if user_ref: user_id = user_ref['id'] # more compat tenant_id = auth.get('tenantId', None) if tenant_id and len(tenant_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantId', size=CONF.max_param_size) if tenant_name: tenant_ref = self.identity_api.get_tenant_by_name( context=context, tenant_name=tenant_name) if tenant_ref: tenant_id = tenant_ref['id'] try: auth_info = self.identity_api.authenticate(context=context, user_id=user_id, password=password, tenant_id=tenant_id) (user_ref, tenant_ref, metadata_ref) = auth_info # If the user is disabled don't allow them to authenticate if not user_ref.get('enabled', True): LOG.warning('User %s is disabled' % user_id) raise exception.Unauthorized() # If the tenant is disabled don't allow them to authenticate if tenant_ref and not tenant_ref.get('enabled', True): LOG.warning('Tenant %s is disabled' % tenant_id) raise exception.Unauthorized() except AssertionError as e: raise exception.Unauthorized(e.message) token_ref = self.token_api.create_token( context, token_id, dict(id=token_id, user=user_ref, tenant=tenant_ref, metadata=metadata_ref)) if tenant_ref: catalog_ref = self.catalog_api.get_catalog( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id'], metadata=metadata_ref) else: catalog_ref = {} elif 'token' in auth: token = auth['token'].get('id', None) if len(token) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_param_size) tenant_name = auth.get('tenantName') if tenant_name and len(tenant_name) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantName', size=CONF.max_param_size) # more compat if tenant_name: tenant_ref = self.identity_api.get_tenant_by_name( context=context, tenant_name=tenant_name) tenant_id = tenant_ref['id'] else: tenant_id = auth.get('tenantId', None) try: old_token_ref = self.token_api.get_token(context=context, token_id=token) except exception.NotFound: raise exception.Unauthorized() user_ref = old_token_ref['user'] # If the user is disabled don't allow them to authenticate current_user_ref = self.identity_api.get_user( context=context, user_id=user_ref['id']) if not current_user_ref.get('enabled', True): LOG.warning('User %s is disabled' % user_ref['id']) raise exception.Unauthorized() tenants = self.identity_api.get_tenants_for_user( context, user_ref['id']) if tenant_id: assert tenant_id in tenants tenant_ref = self.identity_api.get_tenant(context=context, tenant_id=tenant_id) # If the tenant is disabled don't allow them to authenticate if tenant_ref and not tenant_ref.get('enabled', True): LOG.warning('Tenant %s is disabled' % tenant_id) raise exception.Unauthorized() if tenant_ref: metadata_ref = self.identity_api.get_metadata( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id']) catalog_ref = self.catalog_api.get_catalog( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id'], metadata=metadata_ref) else: metadata_ref = {} catalog_ref = {} token_ref = self.token_api.create_token( context, token_id, dict(id=token_id, user=user_ref, tenant=tenant_ref, metadata=metadata_ref, expires=old_token_ref['expires'])) # TODO(termie): optimize this call at some point and put it into the # the return for metadata # fill out the roles in the metadata roles_ref = [] for role_id in metadata_ref.get('roles', []): roles_ref.append(self.identity_api.get_role(context, role_id)) logging.debug('TOKEN_REF %s', token_ref) return self._format_authenticate(token_ref, roles_ref, catalog_ref)
def authenticate(self, context, auth=None): """Authenticate credentials and return a token. Accept auth as a dict that looks like:: { "auth":{ "passwordCredentials":{ "username":"******", "password":"******" }, "tenantName":"customer-x" } } In this case, tenant is optional, if not provided the token will be considered "unscoped" and can later be used to get a scoped token. Alternatively, this call accepts auth with only a token and tenant that will return a token that is scoped to that tenant. """ token_id = uuid.uuid4().hex if 'passwordCredentials' in auth: username = auth['passwordCredentials'].get('username', '') password = auth['passwordCredentials'].get('password', '') tenant_name = auth.get('tenantName', None) if username: user_ref = self.identity_api.get_user_by_name( context=context, user_name=username) user_id = user_ref['id'] else: user_id = auth['passwordCredentials'].get('userId', None) # more compat if tenant_name: tenant_ref = self.identity_api.get_tenant_by_name( context=context, tenant_name=tenant_name) tenant_id = tenant_ref['id'] else: tenant_id = auth.get('tenantId', None) try: (user_ref, tenant_ref, metadata_ref) = \ self.identity_api.authenticate(context=context, user_id=user_id, password=password, tenant_id=tenant_id) # If the user is disabled don't allow them to authenticate if not user_ref.get('enabled', True): raise webob.exc.HTTPForbidden('User has been disabled') except AssertionError as e: raise webob.exc.HTTPForbidden(e.message) token_ref = self.token_api.create_token( context, token_id, dict(expires='', id=token_id, user=user_ref, tenant=tenant_ref, metadata=metadata_ref)) if tenant_ref: catalog_ref = self.catalog_api.get_catalog( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id'], metadata=metadata_ref) else: catalog_ref = {} elif 'token' in auth: token = auth['token'].get('id', None) tenant_name = auth.get('tenantName') # more compat if tenant_name: tenant_ref = self.identity_api.get_tenant_by_name( context=context, tenant_name=tenant_name) tenant_id = tenant_ref['id'] else: tenant_id = auth.get('tenantId', None) old_token_ref = self.token_api.get_token(context=context, token_id=token) user_ref = old_token_ref['user'] tenants = self.identity_api.get_tenants_for_user( context, user_ref['id']) if tenant_id: assert tenant_id in tenants tenant_ref = self.identity_api.get_tenant(context=context, tenant_id=tenant_id) if tenant_ref: metadata_ref = self.identity_api.get_metadata( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id']) catalog_ref = self.catalog_api.get_catalog( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id'], metadata=metadata_ref) else: metadata_ref = {} catalog_ref = {} token_ref = self.token_api.create_token( context, token_id, dict(expires='', id=token_id, user=user_ref, tenant=tenant_ref, metadata=metadata_ref)) # TODO(termie): optimize this call at some point and put it into the # the return for metadata # fill out the roles in the metadata roles_ref = [] for role_id in metadata_ref.get('roles', []): roles_ref.append(self.identity_api.get_role(context, role_id)) logging.debug('TOKEN_REF %s', token_ref) return self._format_authenticate(token_ref, roles_ref, catalog_ref)