Ejemplo n.º 1
0
    def _get_project_id_from_auth(self, context, auth):
        """Extract tenant information from auth dict.

        Returns a valid tenant_id if it exists, or None if not specified.
        """
        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)

        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)

        if tenant_name:
            try:
                tenant_ref = self.identity_api.get_project_by_name(
                    context=context,
                    tenant_name=tenant_name,
                    domain_id=DEFAULT_DOMAIN_ID)
                tenant_id = tenant_ref['id']
            except exception.ProjectNotFound as e:
                raise exception.Unauthorized(e)
        return tenant_id
Ejemplo n.º 2
0
    def _get_project_id_from_auth(self, auth):
        """Extract and normalize project information from auth dict.

        :param auth: Dictionary representing the authentication request.
        :returns: A string representing the project in the authentication
                  request. If project scope isn't present in the request None
                  is returned.
        """
        project_id = auth.get('tenantId')
        project_name = auth.get('tenantName')

        if project_id:
            if len(project_id) > CONF.max_param_size:
                raise exception.ValidationSizeError(
                    attribute='tenantId', size=CONF.max_param_size
                )
        elif project_name:
            if len(project_name) > CONF.max_param_size:
                raise exception.ValidationSizeError(
                    attribute='tenantName', size=CONF.max_param_size
                )
            if (CONF.resource.project_name_url_safe == 'strict' and
                    utils.is_not_url_safe(project_name)):
                msg = _('Tenant name cannot contain reserved characters.')
                raise exception.Unauthorized(message=msg)
            try:
                project_id = self.resource_api.get_project_by_name(
                    project_name, CONF.identity.default_domain_id
                )['id']
            except exception.ProjectNotFound as e:
                raise exception.Unauthorized(e)
        else:
            project_id = None

        return project_id
Ejemplo n.º 3
0
    def _get_project_id_from_auth(self, auth):
        """Extract tenant information from auth dict.

        Returns a valid tenant_id if it exists, or None if not specified.
        """
        tenant_id = auth.get('tenantId')
        if tenant_id and len(tenant_id) > CONF.max_param_size:
            raise exception.ValidationSizeError(attribute='tenantId',
                                                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)

        if tenant_name:
            if (CONF.resource.project_name_url_safe == 'strict'
                    and utils.is_not_url_safe(tenant_name)):
                msg = _('Tenant name cannot contain reserved characters.')
                raise exception.Unauthorized(message=msg)
            try:
                tenant_ref = self.resource_api.get_project_by_name(
                    tenant_name, CONF.identity.default_domain_id)
                tenant_id = tenant_ref['id']
            except exception.ProjectNotFound as e:
                raise exception.Unauthorized(e)
        return tenant_id
Ejemplo n.º 4
0
    def _authenticate_local(self, context, auth):
        """Try to authenticate against the identity backend.

        Returns auth_token_data, (user_ref, tenant_ref, metadata_ref)
        """
        if 'passwordCredentials' not in auth:
            raise exception.ValidationError(
                attribute='passwordCredentials', target='auth')

        if "password" not in auth['passwordCredentials']:
            raise exception.ValidationError(
                attribute='password', target='passwordCredentials')

        password = auth['passwordCredentials']['password']
        if password and len(password) > CONF.identity.max_password_length:
            raise exception.ValidationSizeError(
                attribute='password', size=CONF.identity.max_password_length)

        if (not auth['passwordCredentials'].get("userId") and
                not auth['passwordCredentials'].get("username")):
            raise exception.ValidationError(
                attribute='username or userId',
                target='passwordCredentials')

        user_id = auth['passwordCredentials'].get('userId')
        if user_id and len(user_id) > CONF.max_param_size:
            raise exception.ValidationSizeError(attribute='userId',
                                                size=CONF.max_param_size)

        username = auth['passwordCredentials'].get('username', '')

        if username:
            if len(username) > CONF.max_param_size:
                raise exception.ValidationSizeError(attribute='username',
                                                    size=CONF.max_param_size)
            try:
                user_ref = self.identity_api.get_user_by_name(
                    username, CONF.identity.default_domain_id)
                user_id = user_ref['id']
            except exception.UserNotFound as e:
                raise exception.Unauthorized(e)

        try:
            user_ref = self.identity_api.authenticate(
                context,
                user_id=user_id,
                password=password)
        except AssertionError as e:
            raise exception.Unauthorized(e.args[0])

        metadata_ref = {}
        tenant_id = self._get_project_id_from_auth(auth)
        tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref(
            user_id, tenant_id)

        expiry = provider.default_expire_time()
        bind = None
        audit_id = None
        return (user_ref, tenant_ref, metadata_ref, expiry, bind, audit_id)
Ejemplo n.º 5
0
    def _authenticate_local(self, context, auth):
        """Try to authenticate against the identity backend.

        Returns auth_token_data, (user_ref, tenant_ref, metadata_ref)
        """
        if 'passwordCredentials' not in auth:
            raise exception.ValidationError(
                attribute='passwordCredentials', target='auth')

        if "password" not in auth['passwordCredentials']:
            raise exception.ValidationError(
                attribute='password', target='passwordCredentials')

        password = auth['passwordCredentials']['password']
        max_pw_size = utils.MAX_PASSWORD_LENGTH
        if password and len(password) > max_pw_size:
            raise exception.ValidationSizeError(attribute='password',
                                                size=max_pw_size)

        if ("userId" not in auth['passwordCredentials'] and
                "username" not in auth['passwordCredentials']):
            raise exception.ValidationError(
                attribute='username or userId',
                target='passwordCredentials')

        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)

        username = auth['passwordCredentials'].get('username', '')
        if len(username) > CONF.max_param_size:
            raise exception.ValidationSizeError(attribute='username',
                                                size=CONF.max_param_size)

        if username:
            try:
                user_ref = self.identity_api.get_user_by_name(
                    username, DEFAULT_DOMAIN_ID)
                user_id = user_ref['id']
            except exception.UserNotFound as e:
                raise exception.Unauthorized(e)

        try:
            user_ref = self.identity_api.authenticate(
                user_id=user_id,
                password=password)
        except AssertionError as e:
            raise exception.Unauthorized(e)

        metadata_ref = {}
        tenant_id = self._get_project_id_from_auth(auth)
        tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref(
            user_id, tenant_id)

        expiry = core.default_expire_time()
        return (user_ref, tenant_ref, metadata_ref, expiry, None)
Ejemplo n.º 6
0
    def authenticate(self, request, auth):
        """Try to authenticate against the identity backend.

        :param request: A request object.
        :param auth: Dictionary representing the authentication request.
        :returns: A tuple containing the user reference, project identifier,
                  token expiration, bind information, and original audit
                  information.
        """
        if 'password' not in auth['passwordCredentials']:
            raise exception.ValidationError(
                attribute='password', target='passwordCredentials')

        password = auth['passwordCredentials']['password']
        if password and len(password) > CONF.identity.max_password_length:
            raise exception.ValidationSizeError(
                attribute='password', size=CONF.identity.max_password_length)

        if (not auth['passwordCredentials'].get('userId') and
                not auth['passwordCredentials'].get('username')):
            raise exception.ValidationError(
                attribute='username or userId',
                target='passwordCredentials')

        user_id = auth['passwordCredentials'].get('userId')
        if user_id and len(user_id) > CONF.max_param_size:
            raise exception.ValidationSizeError(attribute='userId',
                                                size=CONF.max_param_size)

        username = auth['passwordCredentials'].get('username', '')

        if username:
            if len(username) > CONF.max_param_size:
                raise exception.ValidationSizeError(attribute='username',
                                                    size=CONF.max_param_size)
            try:
                user_ref = self.identity_api.get_user_by_name(
                    username, CONF.identity.default_domain_id)
                user_id = user_ref['id']
            except exception.UserNotFound as e:
                raise exception.Unauthorized(e)

        try:
            user_ref = self.identity_api.authenticate(
                request,
                user_id=user_id,
                password=password)
        except AssertionError as e:
            raise exception.Unauthorized(e.args[0])

        project_id = self._get_project_id_from_auth(auth)
        expiry = common.default_expire_time()
        bind = None
        audit_id = None
        return (user_ref, project_id, expiry, bind, audit_id)
Ejemplo n.º 7
0
    def _authenticate_ak(self, context, auth):
        if 'accessKeyCredentials' not in auth:
            raise exception.ValidationError(attribute='accessKeyCredentials',
                                            target='auth')

        if "accessKey" not in auth['accessKeyCredentials']:
            raise exception.ValidationError(attribute='password',
                                            target='passwordCredentials')

        access_key = auth['accessKeyCredentials']['accessKey']
        #TODO: ATHEENDRA
        #if access_key and len(access_key) > CONF.identity.max_password_length:
        #    raise exception.ValidationSizeError(
        #        attribute='accessKey', size=CONF.identity.max_password_length)

        if ("userId" not in auth['accessKeyCredentials']
                and "username" not in auth['accessKeyCredentials']):
            raise exception.ValidationError(attribute='username or userId',
                                            target='accessKeyCredentials')

        user_id = auth['accessKeyCredentials'].get('userId')
        if user_id and len(user_id) > CONF.max_param_size:
            raise exception.ValidationSizeError(attribute='userId',
                                                size=CONF.max_param_size)

        username = auth['accessKeyCredentials'].get('username', '')
        if len(username) > CONF.max_param_size:
            raise exception.ValidationSizeError(attribute='username',
                                                size=CONF.max_param_size)

        if username:
            try:
                user_ref = self.identity_api.get_user_by_name(
                    username, CONF.identity.default_domain_id)
                user_id = user_ref['id']
            except exception.UserNotFound as e:
                raise exception.Unauthorized(e)

        try:
            user_ref = self.identity_api.authenticate_ak(context,
                                                         user_id=user_id,
                                                         access_key=access_key)
        except AssertionError as e:
            raise exception.Unauthorized(e.args[0])

        metadata_ref = {}
        tenant_id = self._get_project_id_from_auth(auth)
        tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref(
            user_id, tenant_id)

        expiry = core.default_expire_time()
        return (user_ref, tenant_ref, metadata_ref, expiry, None)
Ejemplo n.º 8
0
    def _authenticate_token(self, context, auth):
        """Try to authenticate using an already existing token.

        Returns auth_token_data, (user_ref, tenant_ref, metadata_ref)
        """
        if 'token' not in auth:
            raise exception.ValidationError(attribute='token', target='auth')

        if "id" not in auth['token']:
            raise exception.ValidationError(attribute="id", target="token")

        old_token = auth['token']['id']
        if len(old_token) > CONF.max_token_size:
            raise exception.ValidationSizeError(attribute='token',
                                                size=CONF.max_token_size)

        try:
            old_token_ref = self.token_api.get_token(old_token)
        except exception.NotFound as e:
            raise exception.Unauthorized(e)

        wsgi.validate_token_bind(context, old_token_ref)

        # A trust token cannot be used to get another token
        if 'trust' in old_token_ref:
            raise exception.Forbidden()
        if 'trust_id' in old_token_ref['metadata']:
            raise exception.Forbidden()

        user_ref = old_token_ref['user']
        user_id = user_ref['id']
        tenant_id = self._get_project_id_from_auth(auth)

        if not CONF.trust.enabled and 'trust_id' in auth:
            raise exception.Forbidden('Trusts are disabled.')
        elif CONF.trust.enabled and 'trust_id' in auth:
            trust_ref = self.trust_api.get_trust(auth['trust_id'])
            if trust_ref is None:
                raise exception.Forbidden()
            if user_id != trust_ref['trustee_user_id']:
                raise exception.Forbidden()
            if (trust_ref['project_id']
                    and tenant_id != trust_ref['project_id']):
                raise exception.Forbidden()
            if ('expires' in trust_ref) and (trust_ref['expires']):
                expiry = trust_ref['expires']
                if expiry < timeutils.parse_isotime(timeutils.isotime()):
                    raise exception.Forbidden()()
            user_id = trust_ref['trustor_user_id']
            trustor_user_ref = self.identity_api.get_user(
                trust_ref['trustor_user_id'])
            if not trustor_user_ref['enabled']:
                raise exception.Forbidden()()
            trustee_user_ref = self.identity_api.get_user(
                trust_ref['trustee_user_id'])
            if not trustee_user_ref['enabled']:
                raise exception.Forbidden()()

            if trust_ref['impersonation'] is True:
                current_user_ref = trustor_user_ref
            else:
                current_user_ref = trustee_user_ref

        else:
            current_user_ref = self.identity_api.get_user(user_id)

        metadata_ref = {}
        tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref(
            user_id, tenant_id)

        expiry = old_token_ref['expires']
        if CONF.trust.enabled and 'trust_id' in auth:
            trust_id = auth['trust_id']
            trust_roles = []
            for role in trust_ref['roles']:
                if 'roles' not in metadata_ref:
                    raise exception.Forbidden()()
                if role['id'] in metadata_ref['roles']:
                    trust_roles.append(role['id'])
                else:
                    raise exception.Forbidden()
            if 'expiry' in trust_ref and trust_ref['expiry']:
                trust_expiry = timeutils.parse_isotime(trust_ref['expiry'])
                if trust_expiry < expiry:
                    expiry = trust_expiry
            metadata_ref['roles'] = trust_roles
            metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id']
            metadata_ref['trust_id'] = trust_id

        bind = old_token_ref.get('bind')

        return (current_user_ref, tenant_ref, metadata_ref, expiry, bind)
Ejemplo n.º 9
0
    def _authenticate_local(self, context, auth):
        """Try to authenticate against the identity backend.

        Returns auth_token_data, (user_ref, tenant_ref, metadata_ref)
        """
        if 'passwordCredentials' not in auth:
            raise exception.ValidationError(attribute='passwordCredentials',
                                            target='auth')

        if "password" not in auth['passwordCredentials']:
            raise exception.ValidationError(attribute='password',
                                            target='passwordCredentials')

        password = auth['passwordCredentials']['password']
        max_pw_size = utils.MAX_PASSWORD_LENGTH
        if password and len(password) > max_pw_size:
            raise exception.ValidationSizeError(attribute='password',
                                                size=max_pw_size)

        if ("userId" not in auth['passwordCredentials']
                and "username" not in auth['passwordCredentials']):
            raise exception.ValidationError(attribute='username or userId',
                                            target='passwordCredentials')

        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)

        username = auth['passwordCredentials'].get('username', '')
        if len(username) > CONF.max_param_size:
            raise exception.ValidationSizeError(attribute='username',
                                                size=CONF.max_param_size)

        if username:
            try:
                user_ref = self.identity_api.get_user_by_name(
                    context=context,
                    user_name=username,
                    domain_id=DEFAULT_DOMAIN_ID)
                user_id = user_ref['id']
            except exception.UserNotFound as e:
                raise exception.Unauthorized(e)

        tenant_id = self._get_project_id_from_auth(context, auth)

        try:
            auth_info = self.identity_api.authenticate(context=context,
                                                       user_id=user_id,
                                                       password=password,
                                                       tenant_id=tenant_id)
        except AssertionError as e:
            raise exception.Unauthorized(e)
        (user_ref, tenant_ref, metadata_ref) = auth_info

        # By now we will have authorized and if a tenant/project was
        # specified, we will have obtained its metadata.  In this case
        # we just need to add in any group roles.
        #
        # TODO (henry-nash) If no tenant was specified, instead check
        # for a domain and find any related user/group roles

        self._append_roles(
            metadata_ref,
            self._get_group_metadata_ref(context, user_id, tenant_id))

        expiry = core.default_expire_time()
        return (user_ref, tenant_ref, metadata_ref, expiry)
Ejemplo n.º 10
0
    def _authenticate_token(self, context, auth):
        """Try to authenticate using an already existing token.

        Returns auth_token_data, (user_ref, tenant_ref, metadata_ref)
        """
        if 'token' not in auth:
            raise exception.ValidationError(attribute='token', target='auth')

        if "id" not in auth['token']:
            raise exception.ValidationError(attribute="id", target="token")

        old_token = auth['token']['id']
        if len(old_token) > CONF.max_token_size:
            raise exception.ValidationSizeError(attribute='token',
                                                size=CONF.max_token_size)

        try:
            old_token_ref = self.token_api.get_token(context=context,
                                                     token_id=old_token)
        except exception.NotFound as e:
            raise exception.Unauthorized(e)

        #A trust token cannot be used to get another token
        if 'trust' in old_token_ref:
            raise exception.Forbidden()
        if 'trust_id' in old_token_ref['metadata']:
            raise exception.Forbidden()

        user_ref = old_token_ref['user']
        user_id = user_ref['id']
        if not CONF.trust.enabled and 'trust_id' in auth:
            raise exception.Forbidden('Trusts are disabled.')
        elif CONF.trust.enabled and 'trust_id' in auth:
            trust_ref = self.trust_api.get_trust(context, auth['trust_id'])
            if trust_ref is None:
                raise exception.Forbidden()
            if user_id != trust_ref['trustee_user_id']:
                raise exception.Forbidden()
            if ('expires' in trust_ref) and (trust_ref['expires']):
                expiry = trust_ref['expires']
                if expiry < timeutils.parse_isotime(timeutils.isotime()):
                    raise exception.Forbidden()()
            user_id = trust_ref['trustor_user_id']
            trustor_user_ref = (self.identity_api.get_user(
                context=context, user_id=trust_ref['trustor_user_id']))
            if not trustor_user_ref['enabled']:
                raise exception.Forbidden()()
            trustee_user_ref = self.identity_api.get_user(
                context, trust_ref['trustee_user_id'])
            if not trustee_user_ref['enabled']:
                raise exception.Forbidden()()
            if trust_ref['impersonation'] == 'True':
                current_user_ref = trustor_user_ref
            else:
                current_user_ref = trustee_user_ref

        else:
            current_user_ref = self.identity_api.get_user(context=context,
                                                          user_id=user_id)

        tenant_id = self._get_project_id_from_auth(context, auth)

        tenant_ref = self._get_project_ref(context, user_id, tenant_id)
        metadata_ref = self._get_metadata_ref(context, user_id, tenant_id)

        # TODO (henry-nash) If no tenant was specified, instead check
        # for a domain and find any related user/group roles

        self._append_roles(
            metadata_ref,
            self._get_group_metadata_ref(context, user_id, tenant_id))

        expiry = old_token_ref['expires']
        if CONF.trust.enabled and 'trust_id' in auth:
            trust_id = auth['trust_id']
            trust_roles = []
            for role in trust_ref['roles']:
                if not 'roles' in metadata_ref:
                    raise exception.Forbidden()()
                if role['id'] in metadata_ref['roles']:
                    trust_roles.append(role['id'])
                else:
                    raise exception.Forbidden()
            if 'expiry' in trust_ref and trust_ref['expiry']:
                trust_expiry = timeutils.parse_isotime(trust_ref['expiry'])
                if trust_expiry < expiry:
                    expiry = trust_expiry
            metadata_ref['roles'] = trust_roles
            metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id']
            metadata_ref['trust_id'] = trust_id

        return (current_user_ref, tenant_ref, metadata_ref, expiry)
Ejemplo n.º 11
0
    def _authenticate_token(self, context, auth):
        """Try to authenticate using an already existing token.

        Returns auth_token_data, (user_ref, tenant_ref, metadata_ref)
        """
        if 'token' not in auth:
            raise exception.ValidationError(attribute='token', target='auth')

        if "id" not in auth['token']:
            raise exception.ValidationError(attribute="id", target="token")

        old_token = auth['token']['id']
        if len(old_token) > CONF.max_token_size:
            raise exception.ValidationSizeError(attribute='token',
                                                size=CONF.max_token_size)

        try:
            token_model_ref = token_model.KeystoneToken(
                token_id=old_token,
                token_data=self.token_provider_api.validate_v2_token(
                    old_token))
        except exception.NotFound as e:
            raise exception.Unauthorized(e)

        wsgi.validate_token_bind(context, token_model_ref)

        self._restrict_scope(token_model_ref)
        user_id = token_model_ref.user_id
        tenant_id = self._get_project_id_from_auth(auth)

        if not CONF.trust.enabled and 'trust_id' in auth:
            raise exception.Forbidden('Trusts are disabled.')
        elif CONF.trust.enabled and 'trust_id' in auth:
            try:
                trust_ref = self.trust_api.get_trust(auth['trust_id'])
            except exception.TrustNotFound:
                raise exception.Forbidden()
            if user_id != trust_ref['trustee_user_id']:
                raise exception.Forbidden()
            if (trust_ref['project_id']
                    and tenant_id != trust_ref['project_id']):
                raise exception.Forbidden()
            if ('expires' in trust_ref) and (trust_ref['expires']):
                expiry = trust_ref['expires']
                if expiry < timeutils.parse_isotime(utils.isotime()):
                    raise exception.Forbidden()
            user_id = trust_ref['trustor_user_id']
            trustor_user_ref = self.identity_api.get_user(
                trust_ref['trustor_user_id'])
            if not trustor_user_ref['enabled']:
                raise exception.Forbidden()
            trustee_user_ref = self.identity_api.get_user(
                trust_ref['trustee_user_id'])
            if not trustee_user_ref['enabled']:
                raise exception.Forbidden()

            if trust_ref['impersonation'] is True:
                current_user_ref = trustor_user_ref
            else:
                current_user_ref = trustee_user_ref

        else:
            current_user_ref = self.identity_api.get_user(user_id)

        metadata_ref = {}
        tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref(
            user_id, tenant_id)

        expiry = token_model_ref.expires
        if CONF.trust.enabled and 'trust_id' in auth:
            trust_id = auth['trust_id']
            trust_roles = []
            for role in trust_ref['roles']:
                if 'roles' not in metadata_ref:
                    raise exception.Forbidden()
                if role['id'] in metadata_ref['roles']:
                    trust_roles.append(role['id'])
                else:
                    raise exception.Forbidden()
            if 'expiry' in trust_ref and trust_ref['expiry']:
                trust_expiry = timeutils.parse_isotime(trust_ref['expiry'])
                if trust_expiry < expiry:
                    expiry = trust_expiry
            metadata_ref['roles'] = trust_roles
            metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id']
            metadata_ref['trust_id'] = trust_id

        bind = token_model_ref.bind
        audit_id = token_model_ref.audit_chain_id

        return (current_user_ref, tenant_ref, metadata_ref, expiry, bind,
                audit_id)
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
    def _authenticate_local(self, context, auth):
        """Try to authenticate against the identity backend.

        {
                "auth":{
                    "accessKeyCredentials":{
                        "username":"******",
                        "accesskey":"myaccesskey",
                        "tenantName":"customer-x"
                    }
                }
            }

        Returns auth_token_data, (user_ref, tenant_ref, metadata_ref)
        """
        if 'passwordCredentials' not in auth:
            raise exception.ValidationError(attribute='passwordCredentials',
                                            target='auth')

        if "password" not in auth['passwordCredentials']:
            raise exception.ValidationError(attribute='password',
                                            target='passwordCredentials')

        password = auth['passwordCredentials']['password']
        if password and len(password) > CONF.identity.max_password_length:
            raise exception.ValidationSizeError(
                attribute='password', size=CONF.identity.max_password_length)

        if ("userId" not in auth['passwordCredentials']
                and "username" not in auth['passwordCredentials']):
            raise exception.ValidationError(attribute='username or userId',
                                            target='passwordCredentials')

        user_id = auth['passwordCredentials'].get('userId')
        if user_id and len(user_id) > CONF.max_param_size:
            raise exception.ValidationSizeError(attribute='userId',
                                                size=CONF.max_param_size)

        username = auth['passwordCredentials'].get('username', '')
        if len(username) > CONF.max_param_size:
            raise exception.ValidationSizeError(attribute='username',
                                                size=CONF.max_param_size)

        if username:
            try:
                user_ref = self.identity_api.get_user_by_name(
                    username, CONF.identity.default_domain_id)
                user_id = user_ref['id']
            except exception.UserNotFound as e:
                raise exception.Unauthorized(e)

        try:
            user_ref = self.identity_api.authenticate(context,
                                                      user_id=user_id,
                                                      password=password)
        except AssertionError as e:
            raise exception.Unauthorized(e.args[0])

        metadata_ref = {}
        tenant_id = self._get_project_id_from_auth(auth)
        tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref(
            user_id, tenant_id)

        expiry = core.default_expire_time()
        return (user_ref, tenant_ref, metadata_ref, expiry, None)
Ejemplo n.º 14
0
    def _authenticate_token(self, request, auth):
        """Try to authenticate using an already existing token.

        Returns auth_token_data, (user_ref, tenant_ref, metadata_ref)
        """
        if 'token' not in auth:
            raise exception.ValidationError(attribute='token', target='auth')

        if 'id' not in auth['token']:
            raise exception.ValidationError(attribute='id', target='token')

        old_token = auth['token']['id']
        if len(old_token) > CONF.max_token_size:
            raise exception.ValidationSizeError(attribute='token',
                                                size=CONF.max_token_size)

        try:
            v3_token_data = self.token_provider_api.validate_token(old_token)
            # NOTE(lbragstad): Even though we are not using the v2.0 token
            # reference after we translate it in v3_to_v2_token(), we still
            # need to perform that check. We have to do this because
            # v3_to_v2_token will ensure we don't use specific tokens only
            # attainable via v3 to get new tokens on v2.0. For example, an
            # exception would be raised if we passed a federated token to
            # v3_to_v2_token, because federated tokens aren't supported by
            # v2.0 (the same applies to OAuth tokens, domain-scoped tokens,
            # etc..).
            v2_helper = common.V2TokenDataHelper()
            v2_helper.v3_to_v2_token(v3_token_data, old_token)
            token_model_ref = token_model.KeystoneToken(
                token_id=old_token, token_data=v3_token_data)
        except exception.NotFound as e:
            raise exception.Unauthorized(e)

        wsgi.validate_token_bind(request.context_dict, token_model_ref)

        self._restrict_scope(token_model_ref)
        user_id = token_model_ref.user_id
        tenant_id = self._get_project_id_from_auth(auth)

        if not CONF.trust.enabled and 'trust_id' in auth:
            raise exception.Forbidden('Trusts are disabled.')
        elif CONF.trust.enabled and 'trust_id' in auth:
            try:
                trust_ref = self.trust_api.get_trust(auth['trust_id'])
            except exception.TrustNotFound:
                raise exception.Forbidden()
            if user_id != trust_ref['trustee_user_id']:
                raise exception.Forbidden()
            if (trust_ref['project_id']
                    and tenant_id != trust_ref['project_id']):
                raise exception.Forbidden()
            if ('expires' in trust_ref) and (trust_ref['expires']):
                expiry = trust_ref['expires']
                if expiry < timeutils.parse_isotime(utils.isotime()):
                    raise exception.Forbidden()
            user_id = trust_ref['trustor_user_id']
            trustor_user_ref = self.identity_api.get_user(
                trust_ref['trustor_user_id'])
            if not trustor_user_ref['enabled']:
                raise exception.Forbidden()
            trustee_user_ref = self.identity_api.get_user(
                trust_ref['trustee_user_id'])
            if not trustee_user_ref['enabled']:
                raise exception.Forbidden()

            if trust_ref['impersonation'] is True:
                current_user_ref = trustor_user_ref
            else:
                current_user_ref = trustee_user_ref

        else:
            current_user_ref = self.identity_api.get_user(user_id)

        metadata_ref = {}
        tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref(
            user_id, tenant_id)

        expiry = token_model_ref.expires
        if CONF.trust.enabled and 'trust_id' in auth:
            trust_id = auth['trust_id']
            trust_roles = []
            for role in trust_ref['roles']:
                if 'roles' not in metadata_ref:
                    raise exception.Forbidden()
                if role['id'] in metadata_ref['roles']:
                    trust_roles.append(role['id'])
                else:
                    raise exception.Forbidden()
            if 'expiry' in trust_ref and trust_ref['expiry']:
                trust_expiry = timeutils.parse_isotime(trust_ref['expiry'])
                if trust_expiry < expiry:
                    expiry = trust_expiry
            metadata_ref['roles'] = trust_roles
            metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id']
            metadata_ref['trust_id'] = trust_id

        bind = token_model_ref.bind
        audit_id = token_model_ref.audit_chain_id

        return (current_user_ref, tenant_ref, metadata_ref, expiry, bind,
                audit_id)
Ejemplo n.º 15
0
    def authenticate(self, request, auth):
        """Try to authenticate using an already existing token.

        :param request: A request object.
        :param auth: Dictionary representing the authentication request.
        :returns: A tuple containing the user reference, project identifier,
                  token expiration, bind information, and original audit
                  information.
        """
        if 'token' not in auth:
            raise exception.ValidationError(
                attribute='token', target='auth')

        if 'id' not in auth['token']:
            raise exception.ValidationError(
                attribute='id', target='token')

        old_token = auth['token']['id']
        if len(old_token) > CONF.max_token_size:
            raise exception.ValidationSizeError(attribute='token',
                                                size=CONF.max_token_size)

        try:
            v3_token_data = self.token_provider_api.validate_token(
                old_token
            )
            # NOTE(lbragstad): Even though we are not using the v2.0 token
            # reference after we translate it in v3_to_v2_token(), we still
            # need to perform that check. We have to do this because
            # v3_to_v2_token will ensure we don't use specific tokens only
            # attainable via v3 to get new tokens on v2.0. For example, an
            # exception would be raised if we passed a federated token to
            # v3_to_v2_token, because federated tokens aren't supported by
            # v2.0 (the same applies to OAuth tokens, domain-scoped tokens,
            # etc..).
            v2_helper = common.V2TokenDataHelper()
            v2_helper.v3_to_v2_token(v3_token_data, old_token)
            token_model_ref = token_model.KeystoneToken(
                token_id=old_token,
                token_data=v3_token_data
            )
        except exception.NotFound as e:
            raise exception.Unauthorized(e)

        wsgi.validate_token_bind(request.context_dict, token_model_ref)

        self._restrict_scope(token_model_ref)
        user_id = token_model_ref.user_id
        project_id = self._get_project_id_from_auth(auth)

        if not CONF.trust.enabled and 'trust_id' in auth:
            raise exception.Forbidden('Trusts are disabled.')
        elif CONF.trust.enabled and 'trust_id' in auth:
            try:
                trust_ref = self.trust_api.get_trust(auth['trust_id'])
            except exception.TrustNotFound:
                raise exception.Forbidden()
            # If a trust is being used to obtain access to another project and
            # the other project doesn't match the project in the trust, we need
            # to bail because trusts are only good up to a single project.
            if (trust_ref['project_id'] and
                    project_id != trust_ref['project_id']):
                raise exception.Forbidden()

        expiry = token_model_ref.expires
        user_ref = self.identity_api.get_user(user_id)
        bind = token_model_ref.bind
        original_audit_id = token_model_ref.audit_chain_id
        return (user_ref, project_id, expiry, bind, original_audit_id)