예제 #1
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 = 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)
예제 #2
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_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(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 = 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)
예제 #3
0
    def _populate_roles(self, token_data, user_id, system, domain_id,
                        project_id, trust, access_token):
        if 'roles' in token_data:
            # no need to repopulate roles
            return

        if access_token:
            filtered_roles = []
            access_token_ref = PROVIDERS.oauth_api.get_access_token(
                access_token['id']
            )
            authed_role_ids = jsonutils.loads(access_token_ref['role_ids'])
            all_roles = PROVIDERS.role_api.list_roles()
            for role in all_roles:
                for authed_role in authed_role_ids:
                    if authed_role == role['id']:
                        filtered_roles.append({'id': role['id'],
                                               'name': role['name']})
            token_data['roles'] = filtered_roles
            return

        if CONF.trust.enabled and trust:
            # If redelegated_trust_id is set, then we must traverse the
            # trust_chain in order to determine who the original trustor is. We
            # need to do this because the user ID of the original trustor helps
            # us determine scope in the redelegated context.
            if trust.get('redelegated_trust_id'):
                trust_chain = PROVIDERS.trust_api.get_trust_pedigree(
                    trust['id']
                )
                token_user_id = trust_chain[-1]['trustor_user_id']
            else:
                token_user_id = trust['trustor_user_id']

            token_project_id = trust['project_id']
            # trusts do not support domains yet
            token_domain_id = None
        else:
            token_user_id = user_id
            token_project_id = project_id
            token_domain_id = domain_id

        if system or token_domain_id or token_project_id:
            filtered_roles = []
            if CONF.trust.enabled and trust:
                # First expand out any roles that were in the trust to include
                # any implied roles, whether global or domain specific
                refs = [{'role_id': role['id']} for role in trust['roles']]
                effective_trust_roles = (
                    PROVIDERS.assignment_api.add_implied_roles(refs))
                # Now get the current role assignments for the trustor,
                # including any domain specific roles.
                assignments = PROVIDERS.assignment_api.list_role_assignments(
                    user_id=token_user_id,
                    system=system,
                    project_id=token_project_id,
                    effective=True, strip_domain_roles=False)
                current_effective_trustor_roles = (
                    list(set([x['role_id'] for x in assignments])))
                # Go through each of the effective trust roles, making sure the
                # trustor still has them, if any have been removed, then we
                # will treat the trust as invalid
                for trust_role in effective_trust_roles:

                    match_roles = [x for x in current_effective_trustor_roles
                                   if x == trust_role['role_id']]
                    if match_roles:
                        role = PROVIDERS.role_api.get_role(match_roles[0])
                        if role['domain_id'] is None:
                            filtered_roles.append(role)
                    else:
                        raise exception.Forbidden(
                            _('Trustee has no delegated roles.'))
            else:
                for role in self._get_roles_for_user(token_user_id,
                                                     system,
                                                     token_domain_id,
                                                     token_project_id):
                    filtered_roles.append({'id': role['id'],
                                           'name': role['name']})

            # user has no project or domain roles, therefore access denied
            if not filtered_roles:
                if token_project_id:
                    msg = _('User %(user_id)s has no access '
                            'to project %(project_id)s') % {
                                'user_id': user_id,
                                'project_id': token_project_id}
                elif token_domain_id:
                    msg = _('User %(user_id)s has no access '
                            'to domain %(domain_id)s') % {
                                'user_id': user_id,
                                'domain_id': token_domain_id}
                elif system:
                    msg = _('User %(user_id)s has no access '
                            'to the system') % {'user_id': user_id}
                LOG.debug(msg)
                raise exception.Unauthorized(msg)

            token_data['roles'] = filtered_roles
예제 #4
0
def _admin_trustor_trustee_only(context, trust, user_id):
    if (user_id != trust.get('trustor_user_id')
            and user_id != trust.get('trustor_user_id')
            and context['is_admin']):
        raise exception.Forbidden()
예제 #5
0
def assert_enabled_identity_provider(federation_api, idp_id):
    identity_provider = federation_api.get_idp(idp_id)
    if identity_provider.get('enabled') is not True:
        msg = _('Identity Provider %(idp)s is disabled') % {'idp': idp_id}
        LOG.debug(msg)
        raise exception.Forbidden(msg)
예제 #6
0
 def delete_domain(self, domain_id):
     self._validate_default_domain_id(domain_id)
     raise exception.Forbidden(_('Domains are read-only against LDAP'))
예제 #7
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']
        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 ('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'] == '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_id = self._get_project_id_from_auth(auth)
        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', None)

        return (current_user_ref, tenant_ref, metadata_ref, expiry, bind)
예제 #8
0
 def change_password(self, user_id, new_password):
     raise exception.Forbidden(READ_ONLY_LDAP_ERROR_MESSAGE)
예제 #9
0
 def remove_user_from_group(self, user_id, group_id):
     raise exception.Forbidden(READ_ONLY_LDAP_ERROR_MESSAGE)
예제 #10
0
 def _disallow_write(self):
     if not common_ldap.WRITABLE:
         raise exception.Forbidden(READ_ONLY_LDAP_ERROR_MESSAGE)
예제 #11
0
 def delete_user(self, user_id):
     raise exception.Forbidden(READ_ONLY_LDAP_ERROR_MESSAGE)
예제 #12
0
def authorize_aura(credentials, target):
    print "***********************"
    print "POLICY ENFORCE"
    print "***** TARGET:"
    print target
    print "***** Credentials:"
    print credentials
    print "***********************"

    admin_unit = ['target.admin_unit']
    admin_admin_unit = credentials.get('admin_unit')
    admin_location = credentials.get('location')
    print admin_location
    admin_admin_roles = credentials.get('admin_roles')
    user_admin_unit = target.get('target.admin_unit')
    user_location = target.get('target.location')
    print user_location
    user_user_clearance = target.get('target.user_clearance')
    target_role = target.get('target.role.name')

    with open(
            '/opt/stack/keystone/keystone/policy/backends/attribute_policy.json'
    ) as policy:
        policy = json.load(policy)
    for i in range(len(policy)):
        print "ADMIN ROLES"
        print policy[i]["role"]
        #for j in (policy[i]["role"]):
        if True == (target_role in policy[i]["role"]):
            print "target role is present!"
            print target_role
            #for j in (policy[i]["role"]):
            #if j == target_role:
            if (str(policy[i]["admin"]["admin_unit"])
                ) == admin_admin_unit and (str(
                    policy[i]["user"]["admin_unit"])) == user_admin_unit:
                print "ADMIN UNIT IS PRESENT!"
                print admin_admin_unit
                print user_admin_unit
                if (str(policy[i]["admin"]["location"])
                    ) == admin_location and (str(
                        policy[i]["user"]["location"])) == user_location:
                    print "LOCATION IS PRESENT"
                    print admin_location
                    print user_location
                    print policy[i]["admin"]["admin_roles"]
                    print admin_admin_roles
                    for k in (policy[i]["admin"]["admin_roles"]):
                        print "INSIDE ADMIN ROLES"
                        if k == admin_admin_roles:
                            print "ADMIN ROLES MATCH.."
                            print policy[i]["admin"]["admin_roles"]
                            print admin_admin_roles
                            print "**********************************"
                            print policy[i]["user"]["clearance"]
                            print user_user_clearance
                            if (str(policy[i]["user"]["clearance"])
                                ) == user_user_clearance:
                                print "USER CLEARANCE MATCH"
                                print(time.time())
                                print("**********")
                                print("Authorized granted!")
                                print("**********")
                                return True

    raise exception.Forbidden("Unathorised user role assignment attempt!!")
예제 #13
0
 def _assert_expired(self, ref):
     current_time = timeutils.normalize_time(timeutils.utcnow())
     expires = ref['expires_at']
     if current_time > timeutils.normalize_time(expires):
         raise exception.Forbidden()
     return ref
예제 #14
0
    def set_user_password(self, context, user_id, user):
        token_id = context.get('token_id')
        original_password = user.get('original_password')

        token_data = self.token_provider_api.validate_token(token_id)
        token_ref = token_model.KeystoneToken(token_id=token_id,
                                              token_data=token_data)

        if token_ref.user_id != user_id:
            raise exception.Forbidden('Token belongs to another user')
        if original_password is None:
            raise exception.ValidationError(target='user',
                                            attribute='original password')

        try:
            user_ref = self.identity_api.authenticate(
                context,
                user_id=token_ref.user_id,
                password=original_password)
            if not user_ref.get('enabled', True):
                # NOTE(dolph): why can't you set a disabled user's password?
                raise exception.Unauthorized('User is disabled')
        except AssertionError:
            raise exception.Unauthorized()

        update_dict = {'password': user['password'], 'id': user_id}

        admin_context = copy.copy(context)
        admin_context['is_admin'] = True
        super(UserController, self).set_user_password(admin_context,
                                                      user_id,
                                                      update_dict)

        # Issue a new token based upon the original token data. This will
        # always be a V2.0 token.

        # TODO(morganfainberg): Add a mechanism to issue a new token directly
        # from a token model so that this code can go away. This is likely
        # not the norm as most cases do not need to yank apart a token to
        # issue a new one.
        new_token_ref = {}
        metadata_ref = {}
        roles_ref = None

        new_token_ref['user'] = user_ref
        if token_ref.bind:
            new_token_ref['bind'] = token_ref.bind
        if token_ref.project_id:
            new_token_ref['tenant'] = self.assignment_api.get_project(
                token_ref.project_id)
        if token_ref.role_names:
            roles_ref = [dict(name=value)
                         for value in token_ref.role_names]
        if token_ref.role_ids:
            metadata_ref['roles'] = token_ref.role_ids
        if token_ref.trust_id:
            metadata_ref['trust'] = {
                'id': token_ref.trust_id,
                'trustee_user_id': token_ref.trustee_user_id}
        new_token_ref['metadata'] = metadata_ref
        new_token_ref['id'] = uuid.uuid4().hex

        catalog_ref = self.catalog_api.get_catalog(user_id,
                                                   token_ref.project_id)

        new_token_id, new_token_data = self.token_provider_api.issue_v2_token(
            token_ref=new_token_ref, roles_ref=roles_ref,
            catalog_ref=catalog_ref)
        LOG.debug('TOKEN_REF %s', new_token_data)
        return new_token_data
예제 #15
0
def _trustor_trustee_only(trust, user_id):
    if (user_id != trust.get('trustee_user_id')
            and user_id != trust.get('trustor_user_id')):
        raise exception.Forbidden()
예제 #16
0
 def delete_group(self, group_id):
     raise exception.Forbidden(READ_ONLY_LDAP_ERROR_MESSAGE)
예제 #17
0
 def create_domain(self, domain_id, domain):
     if domain_id == CONF.identity.default_domain_id:
         msg = _('Duplicate ID, %s.') % domain_id
         raise exception.Conflict(type='domain', details=msg)
     raise exception.Forbidden(_('Domains are read-only against LDAP'))
예제 #18
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)
예제 #19
0
    def enforce_call(cls,
                     enforcer=None,
                     action=None,
                     target_attr=None,
                     member_target_type=None,
                     member_target=None,
                     filters=None):
        """Enforce RBAC on the current request.

        This will do some legwork and then instantiate the Enforcer if an
        enforcer is not passed in.

        :param enforcer: A pre-instantiated Enforcer object (optional)
        :type enforcer: :class:`RBACEnforcer`
        :param action: the name of the rule/policy enforcement to be checked
                       against, e.g. `identity:get_user` (optional may be
                       replaced by decorating the method/function with
                       `policy_enforcer_action`.
        :type action: str
        :param target_attr: complete override of the target data. This will
                            replace all other generated target data meaning
                            `member_target_type` and `member_target` are
                            ignored. This will also prevent extraction of
                            data from the X-Subject-Token. The `target` dict
                            should contain a series of key-value pairs such
                            as `{'user': user_ref_dict}`.
        :type target_attr: dict
        :param member_target_type: the type of the target, e.g. 'user'. Both
                                   this and `member_target` must be passed if
                                   either is passed.
        :type member_target_type: str
        :param member_target: the (dict form) reference of the member object.
                              Both this and `member_target_type` must be passed
                              if either is passed.
        :type member_target: dict
        :param filters: A variable number of optional string filters, these are
                        used to extract values from the query params. The
                        filters are added to the reques data that is passed to
                        the enforcer and may be used to determine policy
                        action. In practice these are mainly supplied in the
                        various "list" APIs and are un-used in the default
                        supplied policies.
        :type filters: iterable
        """
        # NOTE(morgan) everything in the policy_dict may be used by the policy
        # DSL to action on RBAC and request information/response data.
        policy_dict = {}

        # If "action" has not explicitly been overridden, see if it is set in
        # Flask.g app-context (per-request thread local) meaning the
        # @policy_enforcer_action decorator was used.
        action = action or getattr(flask.g, cls.ACTION_STORE_ATTR, None)
        if action not in _POSSIBLE_TARGET_ACTIONS:
            LOG.warning(
                'RBAC: Unknown enforcement action name `%s`. '
                'Rejecting as Forbidden, this is a programming error '
                'and a bug should be filed with as much information '
                'about the request that caused this as possible.', action)
            # NOTE(morgan): While this is an internal error, a 500 is never
            # desirable, we have handled the case and the most appropriate
            # response here is to issue a 403 (FORBIDDEN) to any API calling
            # enforce_call with an inappropriate action/name to look up the
            # policy rule. This is simply a short-circuit as the enforcement
            # code raises a 403 on an unknown action (in keystone) by default.
            raise exception.Forbidden(message=_(
                'Internal RBAC enforcement error, invalid rule (action) '
                'name.'))

        # Mark flask.g as "enforce_call" has been called. This should occur
        # before anything except the "is this a valid action" check, ensuring
        # all proper "after request" checks pass, showing that the API has
        # enforcement.
        setattr(flask.g, _ENFORCEMENT_CHECK_ATTR, True)

        # Assert we are actually authenticated
        cls._assert_is_authenticated()

        # Check if "is_admin", this is in support of the old "admin auth token"
        # middleware with a shared "admin" token for auth
        if cls._shared_admin_auth_token_set():
            LOG.warning('RBAC: Bypassing authorization')
            return

        # NOTE(morgan): !!! ORDER OF THESE OPERATIONS IS IMPORTANT !!!
        # The lowest priority values are set first and the highest priority
        # values are set last.

        # Get the Target Data Set.
        if target_attr is None:
            policy_dict.update(
                cls._extract_member_target_data(member_target_type,
                                                member_target))

            # Special Case, extract and add subject_token data.
            subj_token_target_data = cls._extract_subject_token_target_data()
            if subj_token_target_data:
                policy_dict.setdefault('target',
                                       {}).update(subj_token_target_data)
        else:
            policy_dict['target'] = target_attr

        # Pull the data from the submitted json body to generate
        # appropriate input/target attributes, we take an explicit copy here
        # to ensure we're not somehow corrupting
        json_input = flask.request.get_json(force=True, silent=True) or {}
        policy_dict.update(json_input.copy())

        # Generate the filter_attr dataset.
        policy_dict.update(cls._extract_filter_values(filters))

        # Extract the cred data
        creds = cls._extract_policy_check_credentials()
        flattened = utils.flatten_dict(policy_dict)
        if LOG.logger.getEffectiveLevel() <= log.DEBUG:
            # LOG the Args
            args_str = ', '.join([
                '%s=%s' % (k, v)
                for k, v in (flask.request.view_args or {}).items()
            ])
            args_str = strutils.mask_password(args_str)
            LOG.debug('RBAC: Authorizing `%(action)s(%(args)s)`', {
                'action': action,
                'args': args_str
            })

            # LOG the Cred Data
            cred_str = ', '.join(['%s=%s' % (k, v) for k, v in creds.items()])
            cred_str = strutils.mask_password(cred_str)
            LOG.debug(
                'RBAC: Policy Enforcement Cred Data '
                '`%(action)s creds(%(cred_str)s)`', {
                    'action': action,
                    'cred_str': cred_str
                })

            # Log the Target Data
            target_str = ', '.join(
                ['%s=%s' % (k, v) for k, v in flattened.items()])
            target_str = strutils.mask_password(target_str)
            LOG.debug(
                'RBAC: Policy Enforcement Target Data '
                '`%(action)s => target(%(target_str)s)`', {
                    'action': action,
                    'target_str': target_str
                })

        # Instantiate the enforcer object if needed.
        enforcer_obj = enforcer or cls()
        enforcer_obj._enforce(credentials=creds,
                              action=action,
                              target=flattened)
        LOG.debug('RBAC: Authorization granted')
예제 #20
0
def authorize_aura(credentials, target):
    print "***********************"
    print "POLICY ENFORCE"
    print "***** TARGET:"
    print target
    print "***** Credentials:"
    print credentials
    print "***********************"
    admin_unit = ['target.admin_unit']
    admin_admin_unit = credentials.get('admin_unit')
    admin_location = credentials.get('location')
    #print admin_location
    admin_admin_roles = credentials.get('admin_roles')
    user_admin_unit = target.get('target.admin_unit')
    user_location = target.get('target.location')
    #print user_location
    user_user_clearance = target.get('target.user_clearance')
    target_role = target.get('target.role.name')
    #                 for i in range(11):
    #                    try:
    #                       admin_attribute+str(i) = credentials.get('attribute'+str(i))
    #                       user_attribute+str(i) = credentials.get('target.attribute'+str(i))
    #                   except:
    #                      continue
    #                with open('/opt/stack/keystone/keystone/policy/backends/policy_files/equal_attribute.json') as policy:
    #                    policy = json.load(policy)
    #                for i in range(len(policy)):
    #                    if True == (target_role in policy[i]["role"]):
    #                        if True == (admin_admin_unit in policy[i]["admin"]["admin_unit"]) and True == (user_admin_unit in policy[i]["user"]["admin_unit"]):
    #                            print "ADMIN UNIT IS PRESENT!"
    #                           # else:
    #                           #     print "admin_unit mismatch"
    #                       # else:
    #                        #    print "target role not found"
    #                raise exception.Forbidden("Unathorised user role assignment attempt!!")
    with open(
            '/opt/stack/keystone/keystone/policy/backends/attribute_policy.json'
    ) as policy:
        policy = json.load(policy)
    for i in range(len(policy)):
        print "ADMIN ROLES: "
        print policy[i]["role"]
        print "Target Role: " + target_role
        #for j in (policy[i]["role"]):
        if True == (target_role in policy[i]["role"]):
            print "target role is present: <<" + target_role + ">>"
            #for j in (policy[i]["role"]):
            #if j == target_role:
            #print "ADMIN_ADMIN_UNIT: <<" + admin_admin_unit + ">> in ROLES:"
            #print policy[i]["admin"]["admin_unit"]
            #print "USER_ADMIN_UNIT: <<" + user_admin_unit + ">> in ROLES:"
            #print policy[i]["user"]["admin_unit"]
            if (True == (admin_admin_unit in policy[i]["admin"]["admin_unit"])
                    and True == (user_admin_unit
                                 in policy[i]["user"]["admin_unit"])):
                print "ADMIN UNIT IS PRESENT: <<" + admin_admin_unit + ">>"
                #print "USER ADMIN UNIT IS PRESENT: <<"+ user_admin_unit + ">>"
                #print "ADMIN LOCATION: <<" + admin_location + ">>, User location: <<" + user_location + ">>"
                #print "Admin policy location:"
                #print policy[i]["admin"]["location"]
                #print "User location policy:"
                #print policy[i]["user"]["location"]
                if admin_location in policy[i]["admin"]["location"] and \
                    user_location in policy[i]["user"]["location"]:
                    print "LOCATION IS PRESENT"
                    if (True == (admin_admin_roles
                                 in policy[i]["admin"]["admin_roles"])):
                        print "ADMIN ROLES MATCH.."
                        print "**********************************"
                        print "USER CLEARANCE :" + user_user_clearance
                        print policy[i]["user"]["clearance"]
                        print "**********************************"
                        if (True == (user_user_clearance
                                     in policy[i]["user"]["clearance"])):
                            print "USER CLEARANCE MATCH"
                            print "getting there......."

                            #                                        print(time.time())
                            #                                        print("**********")
                            #                                        print ("Authorized granted!")
                            #                                        print("**********")
                            #                                        return True
                            for j in range(11):
                                print "-------------------------------------"
                                print "admin_attribute" + str(j)
                                print 'user_attribute' + str(j)
                                print policy[i]["admin"]
                                print policy[i]["user"]
                                if "attribute"+str(j) in policy[i]["admin"] and \
                                    "attribute"+str(j) in policy[i]["user"]:
                                    admin_attribute_i = credentials.get(
                                        'attribute' + str(j))
                                    user_attribute_i = target.get(
                                        'target.attribute' + str(j))
                                    if admin_attribute_i in policy[i]["admin"]["attribute"+str(j)] and \
                                        user_attribute_i in policy[i]["user"]["attribute"+str(j)]:
                                        print "USER + ADMIN ATTRIBUTE" + str(
                                            j) + " ARE VALID"
                                    else:
                                        print "USER + ADMIN ATTRIBUTE" + str(
                                            j) + " ARE **NOT** VALID"
                                        print admin_attribute_i
                                        print policy[i]["admin"]["attribute" +
                                                                 str(j)]
                                        print user_attribute_i
                                        print policy[i]["user"]["attribute" +
                                                                str(j)]
                                        raise exception.Forbidden(
                                            "Unathorised user role assignment attempt!!"
                                        )
예제 #21
0
def _trustor_only(context, trust, user_id):
    if user_id != trust.get('trustor_user_id'):
        raise exception.Forbidden()
예제 #22
0
    def authorize_request_token(self, context, 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.
        """
        auth_context = context.get('environment',
                                   {}).get('KEYSTONE_AUTH_CONTEXT', {})
        if auth_context.get('is_delegated_auth'):
            raise exception.Forbidden(
                _('Cannot authorize a request token'
                  ' with a token issued via delegation.'))

        req_token = self.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'))

        # put the roles in a set for easy comparison
        authed_roles = set()
        for role in roles:
            authed_roles.add(role['id'])

        # verify the authorizing user has the roles
        user_token = utils.get_token_ref(context)
        user_id = user_token.user_id
        project_id = req_token['requested_project_id']
        user_roles = self.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_list = list(authed_roles)

        # verify the user has the project too
        req_project_id = req_token['requested_project_id']
        user_projects = self.assignment_api.list_projects_for_user(user_id)
        for user_project in user_projects:
            if user_project['id'] == req_project_id:
                break
        else:
            msg = _("User is not a member of the requested project")
            raise exception.Unauthorized(message=msg)

        # finally authorize the token
        authed_token = self.oauth_api.authorize_request_token(
            request_token_id, user_id, role_list)

        to_return = {'token': {'oauth_verifier': authed_token['verifier']}}
        return to_return
예제 #23
0
def _admin_trustor_only(context, trust, user_id):
    if user_id != trust.get('trustor_user_id') and not context['is_admin']:
        raise exception.Forbidden()
예제 #24
0
    def issue_v3_token(self, user_id, method_names, expires_at=None,
                       project_id=None, domain_id=None, auth_context=None,
                       trust=None, metadata_ref=None, include_catalog=True):
        # for V2, trust is stashed in metadata_ref
        if (CONF.trust.enabled and not trust and metadata_ref and
                'trust_id' in metadata_ref):
            trust = self.trust_api.get_trust(metadata_ref['trust_id'])

        access_token = None
        if 'oauth1' in method_names:
            if self.oauth_api:
                access_token_id = auth_context['access_token_id']
                access_token = self.oauth_api.get_access_token(access_token_id)
            else:
                raise exception.Forbidden(_('Oauth is disabled.'))

        token_data = self.v3_token_data_helper.get_token_data(
            user_id,
            method_names,
            auth_context.get('extras') if auth_context else None,
            domain_id=domain_id,
            project_id=project_id,
            expires=expires_at,
            trust=trust,
            bind=auth_context.get('bind') if auth_context else None,
            include_catalog=include_catalog,
            access_token=access_token)

        token_id = self._get_token_id(token_data)
        try:
            expiry = token_data['token']['expires_at']
            if isinstance(expiry, basestring):
                expiry = timeutils.normalize_time(
                    timeutils.parse_isotime(expiry))
            # FIXME(gyee): is there really a need to store roles in metadata?
            role_ids = []
            if metadata_ref is None:
                metadata_ref = {}
            if 'project' in token_data['token']:
                # project-scoped token, fill in the v2 token data
                # all we care are the role IDs
                role_ids = [r['id'] for r in token_data['token']['roles']]
                metadata_ref = {'roles': role_ids}
            if trust:
                metadata_ref.setdefault('trust_id', trust['id'])
                metadata_ref.setdefault('trustee_user_id',
                                        trust['trustee_user_id'])
            data = dict(key=token_id,
                        id=token_id,
                        expires=expiry,
                        user=token_data['token']['user'],
                        tenant=token_data['token'].get('project'),
                        metadata=metadata_ref,
                        token_data=token_data,
                        trust_id=trust['id'] if trust else None,
                        token_version=token.provider.V3)
            self.token_api.create_token(token_id, data)
        except Exception:
            exc_info = sys.exc_info()
            # an identical token may have been created already.
            # if so, return the token_data as it is also identical
            try:
                self.token_api.get_token(token_id)
            except exception.TokenNotFound:
                raise exc_info[0], exc_info[1], exc_info[2]

        return (token_id, token_data)
예제 #25
0
def assert_enabled_service_provider_object(service_provider):
    if service_provider.get('enabled') is not True:
        sp_id = service_provider['id']
        msg = _('Service Provider %(sp)s is disabled') % {'sp': sp_id}
        LOG.debug(msg)
        raise exception.Forbidden(msg)
예제 #26
0
 def _require_user_is_trustor(self, context, trust):
     user_id = self._get_user_id(context)
     if user_id != trust.get('trustor_user_id'):
         raise exception.Forbidden(
             _("The authenticated user should match the trustor."))
예제 #27
0
 def test_403_title(self):
     e = exception.Forbidden()
     resp = wsgi.render_exception(e)
     j = jsonutils.loads(resp.body)
     self.assertEqual('Forbidden', e.title)
     self.assertEqual('Forbidden', j['error'].get('title'))
예제 #28
0
 def _require_role(self, trust):
     if not trust.get('roles'):
         raise exception.Forbidden(
             _('At least one role should be specified.'))
예제 #29
0
파일: common.py 프로젝트: sandlbn/keystone
    def _populate_roles(self, token_data, user_id, domain_id, project_id,
                        trust, access_token):
        if 'roles' in token_data:
            # no need to repopulate roles
            return

        if access_token:
            filtered_roles = []
            authed_role_ids = json.loads(access_token['role_ids'])
            all_roles = self.assignment_api.list_roles()
            for role in all_roles:
                for authed_role in authed_role_ids:
                    if authed_role == role['id']:
                        filtered_roles.append({
                            'id': role['id'],
                            'name': role['name']
                        })
            token_data['roles'] = filtered_roles
            return

        if CONF.trust.enabled and trust:
            token_user_id = trust['trustor_user_id']
            token_project_id = trust['project_id']
            # trusts do not support domains yet
            token_domain_id = None
        else:
            token_user_id = user_id
            token_project_id = project_id
            token_domain_id = domain_id

        if token_domain_id or token_project_id:
            roles = self._get_roles_for_user(token_user_id, token_domain_id,
                                             token_project_id)
            filtered_roles = []
            if CONF.trust.enabled and trust:
                for trust_role in trust['roles']:
                    match_roles = [
                        x for x in roles if x['id'] == trust_role['id']
                    ]
                    if match_roles:
                        filtered_roles.append(match_roles[0])
                    else:
                        raise exception.Forbidden(
                            _('Trustee has no delegated roles.'))
            else:
                for role in roles:
                    filtered_roles.append({
                        'id': role['id'],
                        'name': role['name']
                    })

            # user has no project or domain roles, therefore access denied
            if not filtered_roles:
                if token_project_id:
                    msg = _('User %(user_id)s has no access '
                            'to project %(project_id)s') % {
                                'user_id': user_id,
                                'project_id': token_project_id
                            }
                else:
                    msg = _('User %(user_id)s has no access '
                            'to domain %(domain_id)s') % {
                                'user_id': user_id,
                                'domain_id': token_domain_id
                            }
                LOG.debug(msg)
                raise exception.Unauthorized(msg)

            token_data['roles'] = filtered_roles
예제 #30
0
def _trustor_trustee_only(trust, user_id):
    if user_id not in [
            trust.get('trustee_user_id'),
            trust.get('trustor_user_id')
    ]:
        raise exception.Forbidden()