def authenticate(self, context, auth_payload, auth_context): if not auth_payload.get('id'): raise exception.ValidationError(attribute='id', target='token') scope = utils.get_scope(context) if scope.get('domain', {}).get('id'): raise exception.ForbiddenNotSecurity( 'Token authentication with domain scoped authorization is not ' 'supported by the v3 API.') scope_project_id = scope.get('project', {}).get('id') if not scope_project_id: raise exception.ValidationError(attribute='project_id', target='scope') x_forwarded_for = utils.determine_x_forwarded_for_header(context) token_id = auth_payload['id'] identity = v2.RackspaceIdentityToken.from_token( token_id, scope_project_id=scope_project_id, x_forwarded_for=x_forwarded_for) token_data = identity.authenticate() auth_context['user_id'] = token_data['access']['user']['id'] auth_context[const.TOKEN_RESPONSE] = token_data
def handle_unexpected_response(self, resp): if resp.status_code == requests.codes.not_found: msg = resp.json()['itemNotFound']['message'] LOG.info(msg) raise exception.NotFound(msg) elif resp.status_code == requests.codes.unauthorized: msg = resp.json()['unauthorized']['message'] LOG.info(msg) raise exception.Unauthorized(msg) elif resp.status_code == requests.codes.bad_request: msg = resp.json()['badRequest']['message'] LOG.info(msg) raise exception.ValidationError(msg) elif resp.status_code == requests.codes.forbidden: body = resp.json() # User/domain disabled cases if 'userDisabled' in body: msg = body['userDisabled']['message'] else: msg = body['forbidden']['message'] LOG.info(msg) raise exception.ForbiddenNotSecurity(msg) LOG.info(resp.text) raise exception.UnexpectedError(resp.text)
def delete_access_rule(self, access_rule_id): try: with sql.session_for_write() as session: query = session.query(AccessRuleModel) ref = query.filter_by(external_id=access_rule_id).first() if not ref: raise exception.AccessRuleNotFound( access_rule_id=access_rule_id) session.delete(ref) except AssertionError: raise exception.ForbiddenNotSecurity( "May not delete access rule in use")
def validate_v3_token(self, token_ref): raise exception.ForbiddenNotSecurity( 'The requested operation is forbidden because token validation is' ' not supported by the v3 API; use v2.0 instead.')
def update_user(self, user_id, user): # only allow password or status changes allowed = ['password', 'enabled', 'login'] for k in user: if k not in allowed: self._disallow_write() old_obj = self.user.get(user_id) if 'name' in user and old_obj.get('name') != user['name']: raise exception.Conflict(_('Cannot change user name')) if 'password' in user: # force LDAP replace old_obj['password'] = '******' LOG.info("User password update %s" % user_id) # special CC sauce to allow onboarding of new provisioned CAM users with no password and userAccountControl 514 if 'login' in user: user.pop('login') if 'ccObjectStatus' not in old_obj: # this indicates that it is indeed a freshly provisioned CAM user: enable the user user['enabled'] = True if 'enabled' in user: if user['enabled']: if 'sapObjectStatus' in old_obj and \ old_obj['sapObjectStatus'] != STATUS_ACTIVE: raise exception.Conflict(_('User is inactive.')) else: user['ccObjectStatus'] = STATUS_ACTIVE else: user['ccObjectStatus'] = STATUS_INACTIVE if self.user.enabled_mask: self.user.mask_enabled_attribute(user) elif self.user.enabled_invert and not self.user.enabled_emulation: # We need to invert the enabled value for the old model object # to prevent the LDAP update code from thinking that the enabled # values are already equal. user['enabled'] = not user['enabled'] old_obj['enabled'] = not old_obj['enabled'] if 'camObjectStatus' in user and old_obj.get('camObjectStatus') != \ user['camObjectStatus']: raise exception.ForbiddenNotSecurity( _('user.camObjectStatus is a read-only attribute')) if 'sapObjectStatus' in user and old_obj.get('sapObjectStatus') != \ user['sapObjectStatus']: raise exception.ForbiddenNotSecurity( _('user.sapObjectStatus is a read-only attribute')) try: self.user.update(user_id, user, old_obj) except ldap.UNWILLING_TO_PERFORM as e: # If the exceptions's 'info' field begins with: # 00000056 - Current passwords do not match # 0000052D - New password violates length/complexity/history msg = e[0]['desc'] LOG.error("User update %s failed: %s" % (user_id, msg)) if e[0]['info'].startswith('0000052D'): msg = '"Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain." ' raise exception.PasswordRequirementsValidationError(msg) else: raise e return self.user.get_filtered(user_id)