Esempio n. 1
0
    def post(self):
        """Create project.

        POST /v3/projects
        """
        project = self.request_body_json.get('project', {})
        target = {'project': project}
        ENFORCER.enforce_call(
            action='identity:create_project', target_attr=target
        )
        validation.lazy_validate(schema.project_create, project)
        project = self._assign_unique_id(project)
        if not project.get('is_domain'):
            project = self._normalize_domain_id(project)
            # Our API requires that you specify the location in the hierarchy
            # unambiguously. This could be by parent_id or, if it is a top
            # level project, just by providing a domain_id.
        if not project.get('parent_id'):
            project['parent_id'] = project.get('domain_id')
        project = self._normalize_dict(project)
        try:
            ref = PROVIDERS.resource_api.create_project(
                project['id'],
                project,
                initiator=self.audit_initiator)
        except (exception.DomainNotFound, exception.ProjectNotFound) as e:
            raise exception.ValidationError(e)
        return self.wrap_member(ref), http_client.CREATED
Esempio n. 2
0
    def patch(self, role_id):
        """Update role.

        PATCH /v3/roles/{role_id}
        """
        err = None
        role = {}
        try:
            role = PROVIDERS.role_api.get_role(role_id)
        except Exception as e:  # nosec
            # We don't raise out here, we raise out after enforcement, this
            # ensures we do not leak role existence. Do nothing yet, process
            # enforcement before raising out an error.
            err = e
        finally:
            if err is not None or not self._is_domain_role(role):
                ENFORCER.enforce_call(action='identity:update_role')
                if err:
                    raise err
            else:
                ENFORCER.enforce_call(action='identity:update_domain_role',
                                      member_target_type='role',
                                      member_target=role)
        request_body_role = self.request_body_json.get('role', {})
        validation.lazy_validate(schema.role_update, request_body_role)
        self._require_matching_id(request_body_role)
        ref = PROVIDERS.role_api.update_role(
            role_id, request_body_role, initiator=self.audit_initiator)
        return self.wrap_member(ref)
Esempio n. 3
0
    def create_user(self, request, user):
        validation.lazy_validate(schema.user_create_v2, user)
        user = self._normalize_OSKSADM_password_on_request(user)
        user = self.normalize_username_in_request(user)
        user = self._normalize_dict(user)
        self.assert_admin(request)

        default_project_id = user.pop('tenantId', None)
        if default_project_id is not None:
            # Check to see if the project is valid before moving on.
            self.resource_api.get_project(default_project_id)
            user['default_project_id'] = default_project_id

        self.resource_api.ensure_default_domain_exists()

        # The manager layer will generate the unique ID for users
        user_ref = self._normalize_domain_id(request, user.copy())
        new_user_ref = self.v3_to_v2_user(
            self.identity_api.create_user(
                user_ref, initiator=request.audit_initiator
            )
        )

        if default_project_id is not None:
            self.assignment_api.add_user_to_project(default_project_id,
                                                    new_user_ref['id'])
        return {'user': new_user_ref}
def create_project_patched(self, request, project):
    validation.lazy_validate(schema.project_create, project)
    ref = self._assign_unique_id(self._normalize_dict(project))

    if not ref.get('is_domain'):
        ref = self._normalize_domain_id(request, ref)

        LOG.warn(
            "Monkypatch in action! "
            "Hacking the new project id to equal the new project name.")
        ref['id'] = project['name']

    # Our API requires that you specify the location in the hierarchy
    # unambiguously. This could be by parent_id or, if it is a top level
    # project, just by providing a domain_id.
    if not ref.get('parent_id'):
        ref['parent_id'] = ref.get('domain_id')

    initiator = notifications._get_request_audit_info(request.context_dict)
    try:
        ref = self.resource_api.create_project(ref['id'], ref,
                                               initiator=initiator)
    except (exception.DomainNotFound, exception.ProjectNotFound) as e:
        raise exception.ValidationError(e)
    return resource_controllers.ProjectV3.wrap_member(request.context_dict, ref)
Esempio n. 5
0
 def update_limits(self, request, limits):
     validation.lazy_validate(schema.limit_update, limits)
     refs = PROVIDERS.unified_limit_api.update_limits(
         [self._normalize_dict(limit) for limit in limits])
     refs = LimitV3.wrap_collection(request.context_dict, refs)
     refs.pop("links")
     return refs
Esempio n. 6
0
 def create_service(self, request, service):
     validation.lazy_validate(schema.service_create, service)
     ref = self._assign_unique_id(self._normalize_dict(service))
     ref = self.catalog_api.create_service(
         ref['id'], ref, initiator=request.audit_initiator
     )
     return ServiceV3.wrap_member(request.context_dict, ref)
Esempio n. 7
0
 def create_endpoint(self, request, endpoint):
     validation.lazy_validate(schema.endpoint_create, endpoint)
     utils.check_endpoint_url(endpoint["url"])
     ref = self._assign_unique_id(self._normalize_dict(endpoint))
     ref = self._validate_endpoint_region(ref, request)
     ref = self.catalog_api.create_endpoint(ref["id"], ref, initiator=request.audit_initiator)
     return EndpointV3.wrap_member(request.context_dict, ref)
Esempio n. 8
0
 def create_credential(self, request, credential):
     validation.lazy_validate(schema.credential_create, credential)
     trust_id = self._get_trust_id_for_request(request.context_dict)
     ref = self._assign_unique_id(self._normalize_dict(credential),
                                  trust_id)
     ref = self.credential_api.create_credential(ref['id'], ref)
     return CredentialV3.wrap_member(request.context_dict, ref)
Esempio n. 9
0
 def update_service(self, request, service_id, service):
     validation.lazy_validate(schema.service_update, service)
     self._require_matching_id(service_id, service)
     ref = self.catalog_api.update_service(
         service_id, service, initiator=request.audit_initiator
     )
     return ServiceV3.wrap_member(request.context_dict, ref)
Esempio n. 10
0
    def create_application_credential(self, request, user_id,
                                      application_credential):
        validation.lazy_validate(schema.application_credential_create,
                                 application_credential)

        token = request.auth_context['token']
        self._check_unrestricted(token)
        if request.context.user_id != user_id:
            action = _("Cannot create an application credential for another "
                       "user")
            raise exception.ForbiddenAction(action=action)
        project_id = request.context.project_id
        app_cred = self._assign_unique_id(application_credential)
        if not app_cred.get('secret'):
            app_cred['secret'] = self._generate_secret()
        app_cred['user_id'] = user_id
        app_cred['project_id'] = project_id
        app_cred['roles'] = self._normalize_role_list(
            app_cred.get('roles', token['roles']))
        if app_cred.get('expires_at'):
            app_cred['expires_at'] = utils.parse_expiration_date(
                app_cred['expires_at'])
        app_cred = self._normalize_dict(app_cred)
        app_cred_api = PROVIDERS.application_credential_api
        try:
            ref = app_cred_api.create_application_credential(
                app_cred, initiator=request.audit_initiator
            )
        except exception.RoleAssignmentNotFound as e:
            # Raise a Bad Request, not a Not Found, in accordance with the
            # API-SIG recommendations:
            # https://specs.openstack.org/openstack/api-wg/guidelines/http.html#failure-code-clarifications
            raise exception.ApplicationCredentialValidationError(
                detail=str(e))
        return ApplicationCredentialV3.wrap_member(request.context_dict, ref)
Esempio n. 11
0
 def update_endpoint_group(self, request, endpoint_group_id, endpoint_group):
     """Update fixed values and/or extend the filters."""
     validation.lazy_validate(schema.endpoint_group_update, endpoint_group)
     if "filters" in endpoint_group:
         self._require_valid_filter(endpoint_group)
     ref = self.catalog_api.update_endpoint_group(endpoint_group_id, endpoint_group)
     return EndpointGroupV3Controller.wrap_member(request.context_dict, ref)
Esempio n. 12
0
 def update_project(self, request, project_id, project):
     validation.lazy_validate(schema.project_update, project)
     self._require_matching_id(project_id, project)
     self._require_matching_domain_id(project_id, project, self.resource_api.get_project)
     initiator = notifications._get_request_audit_info(request.context_dict)
     ref = self.resource_api.update_project(project_id, project, initiator=initiator)
     return ProjectV3.wrap_member(request.context_dict, ref)
Esempio n. 13
0
 def update_consumer(self, request, consumer_id, consumer):
     validation.lazy_validate(schema.consumer_update, consumer)
     self._require_matching_id(consumer_id, consumer)
     ref = self._normalize_dict(consumer)
     initiator = notifications._get_request_audit_info(request.context_dict)
     ref = self.oauth_api.update_consumer(consumer_id, ref, initiator)
     return ConsumerCrudV3.wrap_member(request.context_dict, ref)
Esempio n. 14
0
 def create_consumer(self, request, consumer):
     validation.lazy_validate(schema.consumer_create, consumer)
     ref = self._assign_unique_id(self._normalize_dict(consumer))
     consumer_ref = self.oauth_api.create_consumer(
         ref, initiator=request.audit_initiator
     )
     return ConsumerCrudV3.wrap_member(request.context_dict, consumer_ref)
Esempio n. 15
0
 def patch(self, region_id):
     ENFORCER.enforce_call(action='identity:update_region')
     region = self.request_body_json.get('region')
     validation.lazy_validate(schema.region_update, region)
     self._require_matching_id(region)
     return self.wrap_member(PROVIDERS.catalog_api.update_region(
         region_id, region, initiator=self.audit_initiator))
Esempio n. 16
0
 def create_domain(self, request, domain):
     validation.lazy_validate(schema.domain_create, domain)
     ref = self._assign_unique_id(self._normalize_dict(domain))
     ref = self.resource_api.create_domain(
         ref['id'], ref, initiator=request.audit_initiator
     )
     return DomainV3.wrap_member(request.context_dict, ref)
Esempio n. 17
0
 def update_group(self, request, group_id, group):
     validation.lazy_validate(schema.group_update, group)
     self._require_matching_id(group_id, group)
     ref = PROVIDERS.identity_api.update_group(
         group_id, group, initiator=request.audit_initiator
     )
     return GroupV3.wrap_member(request.context_dict, ref)
Esempio n. 18
0
 def update_region(self, request, region_id, region):
     validation.lazy_validate(schema.region_update, region)
     self._require_matching_id(region_id, region)
     ref = self.catalog_api.update_region(region_id,
                                          region,
                                          initiator=request.audit_initiator)
     return RegionV3.wrap_member(request.context_dict, ref)
Esempio n. 19
0
 def update_domain(self, request, domain_id, domain):
     validation.lazy_validate(schema.domain_update, domain)
     self._require_matching_id(domain_id, domain)
     ref = self.resource_api.update_domain(
         domain_id, domain, initiator=request.audit_initiator
     )
     return DomainV3.wrap_member(request.context_dict, ref)
Esempio n. 20
0
 def create_service(self, request, OS_KSADM_service):
     validation.lazy_validate(schema.service_create_v2, OS_KSADM_service)
     self.assert_admin(request)
     service_id = uuid.uuid4().hex
     service_ref = OS_KSADM_service.copy()
     service_ref["id"] = service_id
     new_service_ref = self.catalog_api.create_service(service_id, service_ref, initiator=request.audit_initiator)
     return {"OS-KSADM:service": new_service_ref}
Esempio n. 21
0
 def update_identity_provider(self, request, idp_id, identity_provider):
     validation.lazy_validate(schema.identity_provider_update,
                              identity_provider)
     identity_provider = self._normalize_dict(identity_provider)
     idp_ref = PROVIDERS.federation_api.update_idp(
         idp_id, identity_provider
     )
     return IdentityProvider.wrap_member(request.context_dict, idp_ref)
Esempio n. 22
0
 def create_protocol(self, request, idp_id, protocol_id, protocol):
     validation.lazy_validate(schema.protocol_create, protocol)
     ref = self._normalize_dict(protocol)
     ref = self.federation_api.create_protocol(idp_id, protocol_id, ref)
     response = FederationProtocol.wrap_member(request.context_dict, ref)
     return wsgi.render_response(
         body=response, status=(http_client.CREATED,
                                http_client.responses[http_client.CREATED]))
Esempio n. 23
0
    def update_endpoint(self, request, endpoint_id, endpoint):
        validation.lazy_validate(schema.endpoint_update, endpoint)
        self._require_matching_id(endpoint_id, endpoint)

        endpoint = self._validate_endpoint_region(endpoint.copy(), request)

        ref = self.catalog_api.update_endpoint(endpoint_id, endpoint, initiator=request.audit_initiator)
        return EndpointV3.wrap_member(request.context_dict, ref)
Esempio n. 24
0
 def create_limits(self, request, limits):
     validation.lazy_validate(schema.limit_create, limits)
     limits = [self._assign_unique_id(self._normalize_dict(limit))
               for limit in limits]
     refs = PROVIDERS.unified_limit_api.create_limits(limits)
     refs = LimitV3.wrap_collection(request.context_dict, refs)
     refs.pop("links")
     return refs
Esempio n. 25
0
 def create_endpoint_group(self, request, endpoint_group):
     """Create an Endpoint Group with the associated filters."""
     validation.lazy_validate(schema.endpoint_group_create, endpoint_group)
     ref = self._assign_unique_id(self._normalize_dict(endpoint_group))
     self._require_attribute(ref, 'filters')
     self._require_valid_filter(ref)
     ref = self.catalog_api.create_endpoint_group(ref['id'], ref)
     return EndpointGroupV3Controller.wrap_member(request.context_dict, ref)
Esempio n. 26
0
    def update_project(self, request, tenant_id, tenant):
        validation.lazy_validate(schema.tenant_update, tenant)
        self.assert_admin(request)
        self._assert_not_is_domain_project(tenant_id)

        tenant_ref = self.resource_api.update_project(
            tenant_id, tenant, initiator=request.audit_initiator)
        return {'tenant': self.v3_to_v2_project(tenant_ref)}
Esempio n. 27
0
 def patch(self, service_id):
     ENFORCER.enforce_call(action='identity:update_service')
     service = self.request_body_json.get('service')
     validation.lazy_validate(schema.service_update, service)
     self._require_matching_id(service)
     ref = PROVIDERS.catalog_api.update_service(
         service_id, service, initiator=self.audit_initiator)
     return self.wrap_member(ref)
Esempio n. 28
0
 def create_endpoint(self, request, endpoint):
     validation.lazy_validate(schema.endpoint_create, endpoint)
     utils.check_endpoint_url(endpoint['url'])
     ref = self._assign_unique_id(self._normalize_dict(endpoint))
     ref = self._validate_endpoint_region(ref, request.context_dict)
     initiator = notifications._get_request_audit_info(request.context_dict)
     ref = self.catalog_api.create_endpoint(ref['id'], ref, initiator)
     return EndpointV3.wrap_member(request.context_dict, ref)
Esempio n. 29
0
    def update_credential(self, request, credential_id, credential):
        validation.lazy_validate(schema.credential_update, credential)
        self._require_matching_id(credential_id, credential)

        ref = PROVIDERS.credential_api.update_credential(
            credential_id, credential
        )
        return CredentialV3.wrap_member(request.context_dict, ref)
Esempio n. 30
0
 def post(self):
     ENFORCER.enforce_call(action='identity:create_service')
     service = self.request_body_json.get('service')
     validation.lazy_validate(schema.service_create, service)
     service = self._assign_unique_id(self._normalize_dict(service))
     ref = PROVIDERS.catalog_api.create_service(
         service['id'], service, initiator=self.audit_initiator)
     return self.wrap_member(ref), http_client.CREATED
Esempio n. 31
0
 def create_service_provider(self, request, sp_id, service_provider):
     validation.lazy_validate(schema.service_provider_create,
                              service_provider)
     service_provider = self._normalize_dict(service_provider)
     service_provider.setdefault('enabled', False)
     service_provider.setdefault('relay_state_prefix',
                                 CONF.saml.relay_state_prefix)
     sp_ref = self.federation_api.create_sp(sp_id, service_provider)
     response = ServiceProvider.wrap_member(request.context_dict, sp_ref)
     return wsgi.render_response(
         body=response,
         status=(http_client.CREATED,
                 http_client.responses[http_client.CREATED]))
Esempio n. 32
0
 def post(self):
     ENFORCER.enforce_call(action='identity:create_region')
     region = self.request_body_json.get('region')
     validation.lazy_validate(schema.region_create, region)
     region = self._normalize_dict(region)
     if not region.get('id'):
         # NOTE(morgan): even though we officially only support 'id' setting
         # via the PUT mechanism, this is historical and we need to support
         # both ways.
         region = self._assign_unique_id(region)
     ref = PROVIDERS.catalog_api.create_region(
         region, initiator=self.audit_initiator)
     return self.wrap_member(ref), http_client.CREATED
Esempio n. 33
0
    def create_region(self, request, region):
        validation.lazy_validate(schema.region_create, region)
        ref = self._normalize_dict(region)

        if not ref.get('id'):
            ref = self._assign_unique_id(ref)

        ref = self.catalog_api.create_region(ref,
                                             initiator=request.audit_initiator)
        return wsgi.render_response(
            RegionV3.wrap_member(request.context_dict, ref),
            status=(http_client.CREATED,
                    http_client.responses[http_client.CREATED]))
Esempio n. 34
0
    def post(self):
        """Create group.

        POST /groups
        """
        ENFORCER.enforce_call(action='identity:create_group')
        group = self.request_body_json.get('group', {})
        validation.lazy_validate(schema.group_create, group)
        group = self._normalize_dict(group)
        group = self._normalize_domain_id(group)
        ref = PROVIDERS.identity_api.create_group(
            group, initiator=self.audit_initiator)
        return self.wrap_member(ref), http_client.CREATED
Esempio n. 35
0
    def patch(self, project_id):
        """Update project.

        PATCH /v3/projects/{project_id}
        """
        ENFORCER.enforce_call(action='identity:update_project',
                              build_target=_build_project_target_enforcement)
        project = self.request_body_json.get('project', {})
        validation.lazy_validate(schema.project_update, project)
        self._require_matching_id(project)
        ref = PROVIDERS.resource_api.update_project(
            project_id, project, initiator=self.audit_initiator)
        return self.wrap_member(ref)
Esempio n. 36
0
    def put(self, request_token_id):
        ENFORCER.enforce_call(action='identity:authorize_request_token')
        roles = (flask.request.get_json(force=True, silent=True)
                 or {}).get('roles', [])
        validation.lazy_validate(schema.request_token_authorize, roles)
        ctx = flask.request.environ[context.REQUEST_CONTEXT_ENV]
        if ctx.is_delegated_auth:
            raise exception.Forbidden(
                _('Cannot authorize a request token with a token issued via '
                  'delegation.'))

        req_token = PROVIDERS.oauth_api.get_request_token(request_token_id)

        expires_at = req_token['expires_at']
        if expires_at:
            now = timeutils.utcnow()
            expires = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
            if now > expires:
                raise exception.Unauthorized(_('Request token is expired'))

        authed_roles = _normalize_role_list(roles)

        # verify the authorizing user has the roles
        try:
            auth_context = flask.request.environ[
                authorization.AUTH_CONTEXT_ENV]
            user_token_ref = auth_context['token']
        except KeyError:
            LOG.warning("Couldn't find the auth context.")
            raise exception.Unauthorized()

        user_id = user_token_ref.user_id
        project_id = req_token['requested_project_id']
        user_roles = PROVIDERS.assignment_api.get_roles_for_user_and_project(
            user_id, project_id)
        cred_set = set(user_roles)

        if not cred_set.issuperset(authed_roles):
            msg = _('authorizing user does not have role required')
            raise exception.Unauthorized(message=msg)

        # create least of just the id's for the backend
        role_ids = list(authed_roles)

        # finally authorize the token
        authed_token = PROVIDERS.oauth_api.authorize_request_token(
            request_token_id, user_id, role_ids)

        to_return = {'token': {'oauth_verifier': authed_token['verifier']}}
        return to_return
Esempio n. 37
0
    def create_project(self, request, tenant):
        tenant_ref = self._normalize_dict(tenant)

        validation.lazy_validate(schema.tenant_create, tenant)
        self.assert_admin(request)

        self.resource_api.ensure_default_domain_exists()

        tenant_ref['id'] = tenant_ref.get('id', uuid.uuid4().hex)
        tenant = self.resource_api.create_project(
            tenant_ref['id'],
            self._normalize_domain_id(request, tenant_ref),
            initiator=request.audit_initiator)
        return {'tenant': self.v3_to_v2_project(tenant)}
Esempio n. 38
0
    def put(self, project_id):
        """Update all tags associated with a given project.

        PUT /v3/projects/{project_id}/tags
        """
        ENFORCER.enforce_call(
            action='identity:update_project_tags',
            build_target=_build_project_target_enforcement
        )
        tags = self.request_body_json.get('tags', {})
        validation.lazy_validate(schema.project_tags_update, tags)
        ref = PROVIDERS.resource_api.update_project_tags(
            project_id, tags, initiator=self.audit_initiator)
        return self.wrap_member(ref)
Esempio n. 39
0
 def post(self):
     ENFORCER.enforce_call(action='identity:create_endpoint_group')
     ep_group = self.request_body_json.get('endpoint_group', {})
     validation.lazy_validate(schema.endpoint_group_create, ep_group)
     if not ep_group.get('filters'):
         # TODO(morgan): Make this not require substitution. Substitution is
         # done here due to String Freeze in the Rocky release.
         msg = _('%s field is required and cannot be empty') % 'filters'
         raise exception.ValidationError(message=msg)
     self._require_valid_filter(ep_group)
     ep_group = self._assign_unique_id(ep_group)
     return self.wrap_member(
         PROVIDERS.catalog_api.create_endpoint_group(
             ep_group['id'], ep_group)), http.client.CREATED
Esempio n. 40
0
    def patch(self, credential_id):
        # Update Credential
        ENFORCER.enforce_call(
            action='identity:update_credential',
            build_target=_build_target_enforcement
        )
        PROVIDERS.credential_api.get_credential(credential_id)

        credential = self.request_body_json.get('credential', {})
        validation.lazy_validate(schema.credential_update, credential)
        self._require_matching_id(credential)
        ref = PROVIDERS.credential_api.update_credential(
            credential_id, credential)
        return self.wrap_member(ref)
Esempio n. 41
0
    def post(self):
        """Create a user.

        POST /v3/users
        """
        ENFORCER.enforce_call(action='identity:create_user')
        user_data = self.request_body_json.get('user', {})
        validation.lazy_validate(schema.user_create, user_data)
        user_data = self._normalize_dict(user_data)
        user_data = self._normalize_domain_id(user_data)
        ref = PROVIDERS.identity_api.create_user(
            user_data,
            initiator=self.audit_initiator)
        return self.wrap_member(ref), http_client.CREATED
Esempio n. 42
0
 def post(self):
     # Create a new credential
     credential = self.request_body_json.get('credential', {})
     target = {}
     target['credential'] = credential
     ENFORCER.enforce_call(action='identity:create_credential',
                           target_attr=target)
     validation.lazy_validate(schema.credential_create, credential)
     trust_id = getattr(self.oslo_context, 'trust_id', None)
     ref = self._assign_unique_id(self._normalize_dict(credential),
                                  trust_id=trust_id)
     ref = PROVIDERS.credential_api.create_credential(
         ref['id'], ref, initiator=self.audit_initiator)
     return self.wrap_member(ref), http.client.CREATED
Esempio n. 43
0
    def post(self, user_id):
        user_data = self.request_body_json.get('user', {})
        validation.lazy_validate(schema.password_change, user_data)

        try:
            PROVIDERS.identity_api.change_password(
                user_id=user_id,
                original_password=user_data['original_password'],
                new_password=user_data['password'],
                initiator=self.audit_initiator)
        except AssertionError as e:
            raise ks_exception.Unauthorized(
                _('Error when changing user password: %s') % e)
        return None, http.client.NO_CONTENT
Esempio n. 44
0
    def post(self, user_id):
        """Create application credential.

        POST /v3/users/{user_id}/application_credentials
        """
        ENFORCER.enforce_call(action='identity:create_application_credential')
        app_cred_data = self.request_body_json.get('application_credential',
                                                   {})
        validation.lazy_validate(app_cred_schema.application_credential_create,
                                 app_cred_data)
        token = self.auth_context['token']
        _check_unrestricted_application_credential(token)
        if self.oslo_context.user_id != user_id:
            action = _('Cannot create an application credential for another '
                       'user.')
            raise ks_exception.ForbiddenAction(action=action)
        project_id = self.oslo_context.project_id
        app_cred_data = self._assign_unique_id(app_cred_data)
        if not app_cred_data.get('secret'):
            app_cred_data['secret'] = self._generate_secret()
        app_cred_data['user_id'] = user_id
        app_cred_data['project_id'] = project_id
        app_cred_data['roles'] = self._normalize_role_list(
            app_cred_data.get('roles', token.roles))
        if app_cred_data.get('expires_at'):
            app_cred_data['expires_at'] = utils.parse_expiration_date(
                app_cred_data['expires_at'])
        if app_cred_data.get('access_rules'):
            for access_rule in app_cred_data['access_rules']:
                # If user provides an access rule by ID, it will be looked up
                # by ID. If user provides an access rule that is identical to
                # an existing one, the ID generated here will be ignored and
                # the pre-existing access rule will be used.
                if 'id' not in access_rule:
                    # Generate directly, rather than using _assign_unique_id,
                    # so that there is no deep copy made
                    access_rule['id'] = uuid.uuid4().hex
        app_cred_data = self._normalize_dict(app_cred_data)
        app_cred_api = PROVIDERS.application_credential_api

        try:
            ref = app_cred_api.create_application_credential(
                app_cred_data, initiator=self.audit_initiator)
        except ks_exception.RoleAssignmentNotFound as e:
            # Raise a Bad Request, not a Not Found, in accordance with the
            # API-SIG recommendations:
            # https://specs.openstack.org/openstack/api-wg/guidelines/http.html#failure-code-clarifications
            raise ks_exception.ApplicationCredentialValidationError(
                detail=str(e))
        return self.wrap_member(ref), http.client.CREATED
Esempio n. 45
0
    def patch(self, user_id):
        """Update a user.

        PATCH /v3/users/{user_id}
        """
        ENFORCER.enforce_call(action='identity:update_user',
                              build_target=_build_user_target_enforcement)
        PROVIDERS.identity_api.get_user(user_id)
        user_data = self.request_body_json.get('user', {})
        validation.lazy_validate(schema.user_update, user_data)
        self._require_matching_id(user_data)
        ref = PROVIDERS.identity_api.update_user(
            user_id, user_data, initiator=self.audit_initiator)
        return self.wrap_member(ref)
    def create_saml_assertion(self, request, auth):
        """Exchange a scoped token for a SAML assertion.

        :param auth: Dictionary that contains a token and service provider ID
        :returns: SAML Assertion based on properties from the token
        """
        validation.lazy_validate(schema.saml_create, auth)
        t = self._create_base_saml_assertion(request.context_dict, auth)
        (response, service_provider) = t

        headers = self._build_response_headers(service_provider)
        return wsgi.render_response(
            body=response.to_string(),
            status=(http_client.OK, http_client.responses[http_client.OK]),
            headers=headers)
Esempio n. 47
0
    def post(self):
        """Create role.

        POST /v3/roles
        """
        role = self.request_body_json.get('role', {})
        if self._is_domain_role(role):
            ENFORCER.enforce_call(action='identity:create_domain_role')
        else:
            ENFORCER.enforce_call(action='identity:create_role')
        validation.lazy_validate(schema.role_create, role)
        role = self._assign_unique_id(role)
        role = self._normalize_dict(role)
        ref = PROVIDERS.role_api.create_role(
            role['id'], role, initiator=self.audit_initiator)
        return self.wrap_member(ref), http_client.CREATED
Esempio n. 48
0
    def authorize_request_token(self, request, request_token_id, roles):
        """An authenticated user is going to authorize a request token.

        As a security precaution, the requested roles must match those in
        the request token. Because this is in a CLI-only world at the moment,
        there is not another easy way to make sure the user knows which roles
        are being requested before authorizing.
        """
        validation.lazy_validate(schema.request_token_authorize, roles)
        if request.context.is_delegated_auth:
            raise exception.Forbidden(
                _('Cannot authorize a request token'
                  ' with a token issued via delegation.'))

        req_token = PROVIDERS.oauth_api.get_request_token(request_token_id)

        expires_at = req_token['expires_at']
        if expires_at:
            now = timeutils.utcnow()
            expires = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
            if now > expires:
                raise exception.Unauthorized(_('Request token is expired'))

        authed_roles = self._normalize_role_list(roles)

        # verify the authorizing user has the roles
        user_token = authorization.get_token_ref(request.context_dict)
        user_id = user_token.user_id
        project_id = req_token['requested_project_id']
        user_roles = PROVIDERS.assignment_api.get_roles_for_user_and_project(
            user_id, project_id)
        cred_set = set(user_roles)

        if not cred_set.issuperset(authed_roles):
            msg = _('authorizing user does not have role required')
            raise exception.Unauthorized(message=msg)

        # create list of just the id's for the backend
        role_ids = list(authed_roles)

        # finally authorize the token
        authed_token = PROVIDERS.oauth_api.authorize_request_token(
            request_token_id, user_id, role_ids)

        to_return = {'token': {'oauth_verifier': authed_token['verifier']}}
        return to_return
Esempio n. 49
0
    def patch(self, credential_id):
        # Update Credential
        ENFORCER.enforce_call(action='identity:update_credential',
                              build_target=_build_target_enforcement)
        current = PROVIDERS.credential_api.get_credential(credential_id)

        credential = self.request_body_json.get('credential', {})
        validation.lazy_validate(schema.credential_update, credential)
        self._validate_blob_update_keys(current.copy(), credential.copy())
        self._require_matching_id(credential)
        # Check that the user hasn't illegally modified the owner or scope
        target = {'credential': dict(current, **credential)}
        ENFORCER.enforce_call(action='identity:update_credential',
                              target_attr=target)
        ref = PROVIDERS.credential_api.update_credential(
            credential_id, credential)
        return self.wrap_member(ref)
Esempio n. 50
0
    def create_role(self, request, role):
        validation.lazy_validate(schema.role_create_v2, role)
        role = self._normalize_dict(role)
        self.assert_admin(request)

        if role['name'] == CONF.member_role_name:
            # Use the configured member role ID when creating the configured
            # member role name. This avoids the potential of creating a
            # "member" role with an unexpected ID.
            role_id = CONF.member_role_id
        else:
            role_id = uuid.uuid4().hex

        role['id'] = role_id
        initiator = notifications._get_request_audit_info(request.context_dict)
        role_ref = self.role_api.create_role(role_id, role, initiator)
        return {'role': role_ref}
Esempio n. 51
0
    def put(self, project_id, value):
        """Add a single tag to a project.

        PUT /v3/projects/{project_id}/tags/{value}
        """
        ENFORCER.enforce_call(action='identity:create_project_tag')
        validation.lazy_validate(schema.project_tag_create, value)
        # Check if we will exceed the max number of tags on this project
        tags = PROVIDERS.resource_api.list_project_tags(project_id)
        tags.append(value)
        validation.lazy_validate(schema.project_tags_update, tags)
        PROVIDERS.resource_api.create_project_tag(
            project_id, value, initiator=self.audit_initiator)
        url = '/'.join((ks_flask.base_url(), project_id, 'tags', value))
        response = flask.make_response('', http_client.CREATED)
        response.headers['Location'] = url
        return response
Esempio n. 52
0
    def create_trust(self, request, trust):
        """Create a new trust.

        The user creating the trust must be the trustor.

        """
        validation.lazy_validate(schema.trust_create, trust)
        # Check if delegated via trust
        if request.context.is_delegated_auth:
            # Redelegation case
            src_trust_id = request.context.trust_id
            if not src_trust_id:
                raise exception.Forbidden(
                    _('Redelegation allowed for delegated by trust only'))

            redelegated_trust = self.trust_api.get_trust(src_trust_id)
        else:
            redelegated_trust = None

        if trust.get('project_id') and not trust.get('roles'):
            msg = _('At least one role should be specified.')
            raise exception.Forbidden(msg)

        # the creating user must be the trustor
        if request.context.user_id != trust.get('trustor_user_id'):
            msg = _("The authenticated user should match the trustor.")
            raise exception.Forbidden(msg)

        # ensure trustee exists
        self.identity_api.get_user(trust['trustee_user_id'])

        all_roles = self.role_api.list_roles()
        # Normalize roles
        normalized_roles = self._normalize_role_list(trust, all_roles)
        trust['roles'] = normalized_roles
        self._require_trustor_has_role_in_project(trust)
        trust['expires_at'] = self._parse_expiration_date(
            trust.get('expires_at'))
        trust_id = uuid.uuid4().hex
        initiator = notifications._get_request_audit_info(request.context_dict)
        new_trust = self.trust_api.create_trust(trust_id, trust,
                                                normalized_roles,
                                                redelegated_trust, initiator)
        self._fill_in_roles(request.context_dict, new_trust, all_roles)
        return TrustV3.wrap_member(request.context_dict, new_trust)
Esempio n. 53
0
    def create_project(self, request, project):
        validation.lazy_validate(schema.project_create, project)
        ref = self._assign_unique_id(self._normalize_dict(project))

        if not ref.get('is_domain'):
            ref = self._normalize_domain_id(request, ref)
        # Our API requires that you specify the location in the hierarchy
        # unambiguously. This could be by parent_id or, if it is a top level
        # project, just by providing a domain_id.
        if not ref.get('parent_id'):
            ref['parent_id'] = ref.get('domain_id')

        try:
            ref = PROVIDERS.resource_api.create_project(
                ref['id'], ref, initiator=request.audit_initiator)
        except (exception.DomainNotFound, exception.ProjectNotFound) as e:
            raise exception.ValidationError(e)
        return ProjectV3.wrap_member(request.context_dict, ref)
Esempio n. 54
0
    def put(self, region_id):
        ENFORCER.enforce_call(action='identity:create_region')
        region = self.request_body_json.get('region')
        validation.lazy_validate(schema.region_create, region)
        region = self._normalize_dict(region)
        if 'id' not in region:
            region['id'] = region_id
        elif region_id != region.get('id'):
            raise exception.ValidationError(
                _('Conflicting region IDs specified: '
                  '"%(url_id)s" != "%(ref_id)s"') % {
                      'url_id': region_id,
                      'ref_id': region['id']
                  })

        ref = PROVIDERS.catalog_api.create_region(
            region, initiator=self.audit_initiator)
        return self.wrap_member(ref), http.client.CREATED
Esempio n. 55
0
def validate_issue_token_auth(auth=None):
    if auth is None:
        return
    validation.lazy_validate(schema.token_issue, auth)

    user = auth['identity'].get('password', {}).get('user')
    if user is not None:
        if 'id' not in user and 'name' not in user:
            msg = _('Invalid input for field identity/password/user: '******'id or name must be present.')
            raise exception.SchemaValidationError(detail=msg)

        domain = user.get('domain')
        if domain is not None:
            if 'id' not in domain and 'name' not in domain:
                msg = _(
                    'Invalid input for field identity/password/user/domain: '
                    'id or name must be present.')
                raise exception.SchemaValidationError(detail=msg)

    scope = auth.get('scope')
    if scope is not None and isinstance(scope, dict):
        project = scope.get('project')
        if project is not None:
            if 'id' not in project and 'name' not in project:
                msg = _(
                    'Invalid input for field scope/project: '
                    'id or name must be present.')
                raise exception.SchemaValidationError(detail=msg)
            domain = project.get('domain')
            if domain is not None:
                if 'id' not in domain and 'name' not in domain:
                    msg = _(
                        'Invalid input for field scope/project/domain: '
                        'id or name must be present.')
                    raise exception.SchemaValidationError(detail=msg)
        domain = scope.get('domain')
        if domain is not None:
            if 'id' not in domain and 'name' not in domain:
                msg = _(
                    'Invalid input for field scope/domain: '
                    'id or name must be present.')
                raise exception.SchemaValidationError(detail=msg)
Esempio n. 56
0
    def post(self):
        """Exchange a scoped token for an ECP assertion.

        POST /v3/auth/OS-FEDERATION/saml2/ecp
        """
        auth = self.request_body_json.get('auth')
        validation.lazy_validate(federation_schema.saml_create, auth)
        saml_assertion, service_provider = saml.create_base_saml_assertion(
            auth)
        relay_state_prefix = service_provider['relay_state_prefix']

        generator = keystone_idp.ECPGenerator()
        ecp_assertion = generator.generate_ecp(saml_assertion,
                                               relay_state_prefix)
        headers = _build_response_headers(service_provider)
        response = flask.make_response(ecp_assertion.to_string(),
                                       http_client.OK)
        for header, value in headers:
            response.headers[header] = value
        return response
    def create_ecp_assertion(self, request, auth):
        """Exchange a scoped token for an ECP assertion.

        :param auth: Dictionary that contains a token and service provider ID
        :returns: ECP Assertion based on properties from the token
        """
        validation.lazy_validate(schema.saml_create, auth)
        t = self._create_base_saml_assertion(request.context_dict, auth)
        (saml_assertion, service_provider) = t
        relay_state_prefix = service_provider['relay_state_prefix']

        generator = keystone_idp.ECPGenerator()
        ecp_assertion = generator.generate_ecp(saml_assertion,
                                               relay_state_prefix)

        headers = self._build_response_headers(service_provider)
        return wsgi.render_response(
            body=ecp_assertion.to_string(),
            status=(http_client.OK, http_client.responses[http_client.OK]),
            headers=headers)
Esempio n. 58
0
    def post(self, user_id):
        """Create application credential.

        POST /v3/users/{user_id}/application_credentials
        """
        ENFORCER.enforce_call(action='identity:create_application_credential')
        app_cred_data = self.request_body_json.get('application_credential',
                                                   {})
        validation.lazy_validate(app_cred_schema.application_credential_create,
                                 app_cred_data)
        token = self.auth_context['token']
        _check_unrestricted_application_credential(token)
        if self.oslo_context.user_id != user_id:
            action = _('Cannot create an application credential for another '
                       'user.')
            raise ks_exception.ForbiddenAction(action=action)
        project_id = self.oslo_context.project_id
        app_cred_data = self._assign_unique_id(app_cred_data)
        if not app_cred_data.get('secret'):
            app_cred_data['secret'] = self._generate_secret()
        app_cred_data['user_id'] = user_id
        app_cred_data['project_id'] = project_id
        app_cred_data['roles'] = self._normalize_role_list(
            app_cred_data.get('roles', token.roles))
        if app_cred_data.get('expires_at'):
            app_cred_data['expires_at'] = utils.parse_expiration_date(
                app_cred_data['expires_at'])
        app_cred_data = self._normalize_dict(app_cred_data)
        app_cred_api = PROVIDERS.application_credential_api

        try:
            ref = app_cred_api.create_application_credential(
                app_cred_data, initiator=self.audit_initiator)
        except ks_exception.RoleAssignmentNotFound as e:
            # Raise a Bad Request, not a Not Found, in accordance with the
            # API-SIG recommendations:
            # https://specs.openstack.org/openstack/api-wg/guidelines/http.html#failure-code-clarifications
            raise ks_exception.ApplicationCredentialValidationError(
                detail=str(e))
        return self.wrap_member(ref), http_client.CREATED
Esempio n. 59
0
    def create_trust(self, request, trust):
        """Create a new trust.

        The user creating the trust must be the trustor.

        """
        validation.lazy_validate(schema.trust_create, trust)

        token = request.auth_context['token']
        self._check_unrestricted(token)

        redelegated_trust = self._find_redelegated_trust(request)

        if trust.get('project_id') and not trust.get('roles'):
            action = _('At least one role should be specified')
            raise exception.ForbiddenAction(action=action)

        # the creating user must be the trustor
        if request.context.user_id != trust.get('trustor_user_id'):
            action = _("The authenticated user should match the trustor")
            raise exception.ForbiddenAction(action=action)

        # ensure trustee exists
        PROVIDERS.identity_api.get_user(trust['trustee_user_id'])

        # Normalize roles
        normalized_roles = self._normalize_role_list(trust.get('roles', []))
        trust['roles'] = normalized_roles
        self._require_trustor_has_role_in_project(trust)
        trust['expires_at'] = self._parse_expiration_date(
            trust.get('expires_at'))
        trust_id = uuid.uuid4().hex
        new_trust = PROVIDERS.trust_api.create_trust(
            trust_id,
            trust,
            normalized_roles,
            redelegated_trust,
            initiator=request.audit_initiator)
        self._fill_in_roles(request.context_dict, new_trust)
        return TrustV3.wrap_member(request.context_dict, new_trust)
Esempio n. 60
0
    def post(self):
        """Create domain.

        POST /v3/domains
        """
        ENFORCER.enforce_call(action='identity:create_domain')
        domain = self.request_body_json.get('domain', {})
        validation.lazy_validate(schema.domain_create, domain)

        domain_id = domain.get('explicit_domain_id')
        if domain_id is None:
            domain = self._assign_unique_id(domain)
        else:
            # Domain ID validation provided by PyCADF
            try:
                self._validate_id_format(domain_id)
            except ValueError:
                raise exception.DomainIdInvalid
            domain['id'] = domain_id
        domain = self._normalize_dict(domain)
        ref = PROVIDERS.resource_api.create_domain(
            domain['id'], domain, initiator=self.audit_initiator)
        return self.wrap_member(ref), http_client.CREATED