def check_credential_exists(ec2credential, credential_table, session):
    credential = session.query(credential_table).filter_by(
        id=utils.hash_access_key(ec2credential.access)).first()
    if credential is None:
        return False
    blob = utils.get_blob_from_credential(credential)
    # check if credential with same access key but different
    # secret key already exists in credential table.
    # If exists raise an exception
    if blob['secret'] != ec2credential.secret:
        msg = _('Credential %(access)s already exists with different secret'
                ' in %(table)s table')
        message = msg % {'access': ec2credential.access,
                         'table': credential_table.name}
        raise exception.Conflict(type='credential', details=message)
    # check if credential with same access and secret key but
    # associated with a different project exists. If exists raise
    # an exception
    elif credential.project_id is not None and (
            credential.project_id != ec2credential.tenant_id):
        msg = _('Credential %(access)s already exists with different project'
                ' in %(table)s table')
        message = msg % {'access': ec2credential.access,
                         'table': credential_table.name}
        raise exception.Conflict(type='credential', details=message)
    # if credential with same access and secret key and not associated
    # with any projects already exists in the credential table, then
    # return true.
    else:
        return True
예제 #2
0
    def create_credential(self, context, user_id, tenant_id):
        """Create a secret/access pair for use with ec2 style auth.

        Generates a new set of credentials that map the user/tenant
        pair.

        :param context: standard context
        :param user_id: id of user
        :param tenant_id: id of tenant
        :returns: credential: dict of ec2 credential
        """
        if not self._is_admin(context):
            self._assert_identity(context, user_id)

        self._assert_valid_user_id(user_id)
        self._assert_valid_project_id(tenant_id)
        trust_id = self._get_trust_id_for_request(context)
        blob = {'access': uuid.uuid4().hex,
                'secret': uuid.uuid4().hex,
                'trust_id': trust_id}
        credential_id = utils.hash_access_key(blob['access'])
        cred_ref = {'user_id': user_id,
                    'project_id': tenant_id,
                    'blob': jsonutils.dumps(blob),
                    'id': credential_id,
                    'type': 'ec2'}
        self.credential_api.create_credential(credential_id, cred_ref)
        return {'credential': self._convert_v3_to_ec2_credential(cred_ref)}
예제 #3
0
    def post(self, user_id):
        """Create EC2 Credential for user.

        POST /v3/users/{user_id}/credentials/OS-EC2
        """
        ENFORCER.enforce_call(action='identity:ec2_create_credential')
        PROVIDERS.identity_api.get_user(user_id)
        tenant_id = self.request_body_json.get('tenant_id')
        PROVIDERS.resource_api.get_project(tenant_id)
        blob = dict(
            access=uuid.uuid4().hex,
            secret=uuid.uuid4().hex,
            trust_id=self.oslo_context.trust_id
        )
        credential_id = utils.hash_access_key(blob['access'])
        cred_data = dict(
            user_id=user_id,
            project_id=tenant_id,
            blob=jsonutils.dumps(blob),
            id=credential_id,
            type=CRED_TYPE_EC2
        )
        PROVIDERS.credential_api.create_credential(credential_id, cred_data)
        ref = _convert_v3_to_ec2_credential(cred_data)
        return self.wrap_member(ref), http_client.CREATED
예제 #4
0
    def create_credential(self, context, user_id, tenant_id):
        """Create a secret/access pair for use with ec2 style auth.

        Generates a new set of credentials that map the user/tenant
        pair.

        :param context: standard context
        :param user_id: id of user
        :param tenant_id: id of tenant
        :returns: credential: dict of ec2 credential
        """
        if not self._is_admin(context):
            self._assert_identity(context, user_id)

        self._assert_valid_user_id(user_id)
        self._assert_valid_project_id(tenant_id)
        blob = {'access': uuid.uuid4().hex,
                'secret': uuid.uuid4().hex}
        credential_id = utils.hash_access_key(blob['access'])
        cred_ref = {'user_id': user_id,
                    'project_id': tenant_id,
                    'blob': blob,
                    'id': credential_id,
                    'type': 'ec2'}
        self.credential_api.create_credential(credential_id, cred_ref)
        return {'credential': self._convert_v3_to_ec2_credential(cred_ref)}
예제 #5
0
    def create_credential(self, context, user_id, tenant_id):
        """Create a secret/access pair for use with ec2 style auth.

        Generates a new set of credentials that map the user/tenant
        pair.

        :param context: standard context
        :param user_id: id of user
        :param tenant_id: id of tenant
        :returns: credential: dict of ec2 credential
        """
        self.identity_api.get_user(user_id)
        self.resource_api.get_project(tenant_id)
        trust_id = self._get_trust_id_for_request(context)
        blob = {"access": uuid.uuid4().hex, "secret": uuid.uuid4().hex, "trust_id": trust_id}
        credential_id = utils.hash_access_key(blob["access"])
        cred_ref = {
            "user_id": user_id,
            "project_id": tenant_id,
            "blob": jsonutils.dumps(blob),
            "id": credential_id,
            "type": "ec2",
        }
        self.credential_api.create_credential(credential_id, cred_ref)
        return {"credential": self._convert_v3_to_ec2_credential(cred_ref)}
예제 #6
0
파일: users.py 프로젝트: mahak/keystone
    def post(self, user_id):
        """Create EC2 Credential for user.

        POST /v3/users/{user_id}/credentials/OS-EC2
        """
        ENFORCER.enforce_call(action='identity:ec2_create_credential')
        PROVIDERS.identity_api.get_user(user_id)
        tenant_id = self.request_body_json.get('tenant_id')
        PROVIDERS.resource_api.get_project(tenant_id)
        blob = dict(
            access=uuid.uuid4().hex,
            secret=uuid.uuid4().hex,
            trust_id=self.oslo_context.trust_id
        )
        credential_id = utils.hash_access_key(blob['access'])
        cred_data = dict(
            user_id=user_id,
            project_id=tenant_id,
            blob=jsonutils.dumps(blob),
            id=credential_id,
            type=CRED_TYPE_EC2
        )
        PROVIDERS.credential_api.create_credential(credential_id, cred_data)
        ref = _convert_v3_to_ec2_credential(cred_data)
        return self.wrap_member(ref), http_client.CREATED
예제 #7
0
    def create_credential(self, context, user_id, tenant_id):
        """Create a secret/access pair for use with ec2 style auth.

        Generates a new set of credentials that map the user/tenant
        pair.

        :param context: standard context
        :param user_id: id of user
        :param tenant_id: id of tenant
        :returns: credential: dict of ec2 credential
        """

        self.identity_api.get_user(user_id)
        self.assignment_api.get_project(tenant_id)
        trust_id = self._get_trust_id_for_request(context)
        blob = {'access': uuid.uuid4().hex,
                'secret': uuid.uuid4().hex,
                'trust_id': trust_id}
        credential_id = utils.hash_access_key(blob['access'])
        cred_ref = {'user_id': user_id,
                    'project_id': tenant_id,
                    'blob': jsonutils.dumps(blob),
                    'id': credential_id,
                    'type': 'ec2'}
        self.credential_api.create_credential(credential_id, cred_ref)
        return {'credential': self._convert_v3_to_ec2_credential(cred_ref)}
예제 #8
0
    def create_credential(self, request, user_id, tenant_id):
        """Create a secret/access pair for use with ec2 style auth.

        Generates a new set of credentials that map the user/tenant
        pair.

        :param request: current request
        :param user_id: id of user
        :param tenant_id: id of tenant
        :returns: credential: dict of ec2 credential
        """
        self.identity_api.get_user(user_id)
        self.resource_api.get_project(tenant_id)
        blob = {
            'access': uuid.uuid4().hex,
            'secret': uuid.uuid4().hex,
            'trust_id': request.context.trust_id
        }
        credential_id = utils.hash_access_key(blob['access'])
        cred_ref = {
            'user_id': user_id,
            'project_id': tenant_id,
            'blob': jsonutils.dumps(blob),
            'id': credential_id,
            'type': CRED_TYPE_EC2
        }
        self.credential_api.create_credential(credential_id, cred_ref)
        return {'credential': self._convert_v3_to_ec2_credential(cred_ref)}
예제 #9
0
def check_credential_exists(ec2credential, credential_table, session):
    credential = session.query(credential_table).filter_by(
        id=utils.hash_access_key(ec2credential.access)).first()
    if credential is None:
        return False
    blob = utils.get_blob_from_credential(credential)
    # check if credential with same access key but different
    # secret key already exists in credential table.
    # If exists raise an exception
    if blob['secret'] != ec2credential.secret:
        msg = _('Credential %(access)s already exists with different secret'
                ' in %(table)s table')
        message = msg % {
            'access': ec2credential.access,
            'table': credential_table.name
        }
        raise exception.Conflict(type='credential', details=message)
    # check if credential with same access and secret key but
    # associated with a different project exists. If exists raise
    # an exception
    elif credential.project_id is not None and (credential.project_id !=
                                                ec2credential.tenant_id):
        msg = _('Credential %(access)s already exists with different project'
                ' in %(table)s table')
        message = msg % {
            'access': ec2credential.access,
            'table': credential_table.name
        }
        raise exception.Conflict(type='credential', details=message)
    # if credential with same access and secret key and not associated
    # with any projects already exists in the credential table, then
    # return true.
    else:
        return True
예제 #10
0
파일: users.py 프로젝트: mahak/keystone
def _build_enforcer_target_data_owner_and_user_id_match():
    ref = {}
    if flask.request.view_args:
        credential_id = flask.request.view_args.get('credential_id')
        if credential_id is not None:
            hashed_id = utils.hash_access_key(credential_id)
            ref['credential'] = PROVIDERS.credential_api.get_credential(
                hashed_id)
    return ref
예제 #11
0
def _build_enforcer_target_data_owner_and_user_id_match():
    ref = {}
    if flask.request.view_args:
        credential_id = flask.request.view_args.get('credential_id')
        if credential_id is not None:
            hashed_id = utils.hash_access_key(credential_id)
            ref['credential'] = PROVIDERS.credential_api.get_credential(
                hashed_id)
    return ref
예제 #12
0
 def test_ec2_cannot_get_non_ec2_credential(self):
     access_key = uuid.uuid4().hex
     cred_id = utils.hash_access_key(access_key)
     non_ec2_cred = unit.new_credential_ref(user_id=self.user_id, project_id=self.project_id)
     non_ec2_cred["id"] = cred_id
     self.credential_api.create_credential(cred_id, non_ec2_cred)
     uri = "/".join([self._get_ec2_cred_uri(), access_key])
     # if access_key is not found, ec2 controller raises Unauthorized
     # exception
     self.get(uri, expected_status=http_client.UNAUTHORIZED)
예제 #13
0
 def test_ec2_cannot_get_non_ec2_credential(self):
     access_key = uuid.uuid4().hex
     cred_id = utils.hash_access_key(access_key)
     non_ec2_cred = unit.new_credential_ref(user_id=self.user_id,
                                            project_id=self.project_id)
     non_ec2_cred['id'] = cred_id
     self.credential_api.create_credential(cred_id, non_ec2_cred)
     uri = '/'.join([self._get_ec2_cred_uri(), access_key])
     # if access_key is not found, ec2 controller raises Unauthorized
     # exception
     self.get(uri, expected_status=http_client.UNAUTHORIZED)
예제 #14
0
    def _assert_owner(self, user_id, credential_id):
        """Ensure the provided user owns the credential.

        :param user_id: expected credential owner
        :param credential_id: id of credential object
        :raises keystone.exception.Forbidden: on failure

        """
        ec2_credential_id = utils.hash_access_key(credential_id)
        cred_ref = self.credential_api.get_credential(ec2_credential_id)
        if user_id != cred_ref['user_id']:
            raise exception.Forbidden(_('Credential belongs to another user'))
예제 #15
0
    def _get_credentials(self, credential_id):
        """Return credentials from an ID.

        :param credential_id: id of credential
        :raises exception.Unauthorized: when credential id is invalid
        :returns: credential: dict of ec2 credential.
        """
        ec2_credential_id = utils.hash_access_key(credential_id)
        creds = self.credential_api.get_credential(ec2_credential_id)
        if not creds:
            raise exception.Unauthorized(message='EC2 access key not found.')
        return self._convert_v3_to_ec2_credential(creds)
예제 #16
0
    def _get_credentials(self, credential_id):
        """Return credentials from an ID.

        :param credential_id: id of credential
        :raises exception.Unauthorized: when credential id is invalid
        :returns: credential: dict of ec2 credential.
        """
        ec2_credential_id = utils.hash_access_key(credential_id)
        creds = self.credential_api.get_credential(ec2_credential_id)
        if not creds:
            raise exception.Unauthorized(message='EC2 access key not found.')
        return self._convert_v3_to_ec2_credential(creds)
예제 #17
0
    def _assert_owner(self, user_id, credential_id):
        """Ensure the provided user owns the credential.

        :param user_id: expected credential owner
        :param credential_id: id of credential object
        :raises exception.Forbidden: on failure

        """
        ec2_credential_id = utils.hash_access_key(credential_id)
        cred_ref = self.credential_api.get_credential(ec2_credential_id)
        if user_id != cred_ref['user_id']:
            raise exception.Forbidden(_('Credential belongs to another user'))
예제 #18
0
    def get(self, user_id, credential_id):
        """Get a specific EC2 credential.

        GET/HEAD /users/{user_id}/credentials/OS-EC2/{credential_id}
        """
        func = _build_enforcer_target_data_owner_and_user_id_match
        ENFORCER.enforce_call(action='identity:ec2_get_credential',
                              build_target=func)
        PROVIDERS.identity_api.get_user(user_id)
        ec2_cred_id = utils.hash_access_key(credential_id)
        cred_data = self._get_cred_data(ec2_cred_id)
        return self.wrap_member(cred_data)
예제 #19
0
    def delete_credential(self, user_id, credential_id):
        """Delete a user's access/secret pair.

        Used to revoke a user's access/secret pair

        :param user_id: id of user
        :param credential_id: access key for credentials
        :returns: bool: success
        """
        self.identity_api.get_user(user_id)
        self._get_credentials(credential_id)
        ec2_credential_id = utils.hash_access_key(credential_id)
        return self.credential_api.delete_credential(ec2_credential_id)
예제 #20
0
    def _get_credentials(self, credential_id):
        """Return credentials from an ID.

        :param credential_id: id of credential
        :raises keystone.exception.Unauthorized: when credential id is invalid
            or when the credential type is not ec2
        :returns: credential: dict of ec2 credential.
        """
        ec2_credential_id = utils.hash_access_key(credential_id)
        cred = self.credential_api.get_credential(ec2_credential_id)
        if not cred or cred["type"] != CRED_TYPE_EC2:
            raise exception.Unauthorized(message=_("EC2 access key not found."))
        return self._convert_v3_to_ec2_credential(cred)
예제 #21
0
    def delete(self, user_id, credential_id):
        """Delete a specific EC2 credential.

        DELETE /users/{user_id}/credentials/OS-EC2/{credential_id}
        """
        func = _build_enforcer_target_data_owner_and_user_id_match
        ENFORCER.enforce_call(action='identity:ec2_delete_credential',
                              build_target=func)
        PROVIDERS.identity_api.get_user(user_id)
        ec2_cred_id = utils.hash_access_key(credential_id)
        self._get_cred_data(ec2_cred_id)
        PROVIDERS.credential_api.delete_credential(ec2_cred_id)
        return None, http_client.NO_CONTENT
예제 #22
0
파일: users.py 프로젝트: mahak/keystone
    def get(self, user_id, credential_id):
        """Get a specific EC2 credential.

        GET/HEAD /users/{user_id}/credentials/OS-EC2/{credential_id}
        """
        func = _build_enforcer_target_data_owner_and_user_id_match
        ENFORCER.enforce_call(
            action='identity:ec2_get_credential',
            build_target=func)
        PROVIDERS.identity_api.get_user(user_id)
        ec2_cred_id = utils.hash_access_key(credential_id)
        cred_data = self._get_cred_data(ec2_cred_id)
        return self.wrap_member(cred_data)
예제 #23
0
파일: users.py 프로젝트: mahak/keystone
    def delete(self, user_id, credential_id):
        """Delete a specific EC2 credential.

        DELETE /users/{user_id}/credentials/OS-EC2/{credential_id}
        """
        func = _build_enforcer_target_data_owner_and_user_id_match
        ENFORCER.enforce_call(action='identity:ec2_delete_credential',
                              build_target=func)
        PROVIDERS.identity_api.get_user(user_id)
        ec2_cred_id = utils.hash_access_key(credential_id)
        self._get_cred_data(ec2_cred_id)
        PROVIDERS.credential_api.delete_credential(ec2_cred_id)
        return None, http_client.NO_CONTENT
예제 #24
0
    def delete_credential(self, user_id, credential_id):
        """Delete a user's access/secret pair.

        Used to revoke a user's access/secret pair

        :param user_id: id of user
        :param credential_id: access key for credentials
        :returns: bool: success
        """
        self.identity_api.get_user(user_id)
        self._get_credentials(credential_id)
        ec2_credential_id = utils.hash_access_key(credential_id)
        return self.credential_api.delete_credential(ec2_credential_id)
예제 #25
0
 def _check_credential_owner_and_user_id_match(self, context, prep_info, user_id, credential_id):
     # NOTE(morganfainberg): this method needs to capture the arguments of
     # the method that is decorated with @controller.protected() (with
     # exception of the first argument ('context') since the protected
     # method passes in *args, **kwargs. In this case, it is easier to see
     # the expected input if the argspec is `user_id` and `credential_id`
     # explicitly (matching the :class:`.ec2_delete_credential()` method
     # below).
     ref = {}
     credential_id = utils.hash_access_key(credential_id)
     ref["credential"] = self.credential_api.get_credential(credential_id)
     # NOTE(morganfainberg): policy_api is required for this
     # check_protection to properly be able to perform policy enforcement.
     self.check_protection(context, prep_info, ref)
예제 #26
0
    def _get_credentials(self, credential_id):
        """Return credentials from an ID.

        :param credential_id: id of credential
        :raises keystone.exception.Unauthorized: when credential id is invalid
            or when the credential type is not ec2
        :returns: credential: dict of ec2 credential.
        """
        ec2_credential_id = utils.hash_access_key(credential_id)
        cred = self.credential_api.get_credential(ec2_credential_id)
        if not cred or cred['type'] != CRED_TYPE_EC2:
            raise exception.Unauthorized(
                message=_('EC2 access key not found.'))
        return self._convert_v3_to_ec2_credential(cred)
예제 #27
0
    def test_ec2_cannot_get_non_ec2_credential(self):
        access_key = uuid.uuid4().hex
        cred_id = utils.hash_access_key(access_key)
        non_ec2_cred = unit.new_credential_ref(
            user_id=self.user_id,
            project_id=self.project_id)
        non_ec2_cred['id'] = cred_id
        self.credential_api.create_credential(cred_id, non_ec2_cred)

        # if access_key is not found, ec2 controller raises Unauthorized
        # exception
        path = '/'.join([self._get_ec2_cred_uri(), access_key])
        self.public_request(method='GET', token=self.get_scoped_token(),
                            path=path,
                            expected_status=http_client.UNAUTHORIZED)
예제 #28
0
 def _check_credential_owner_and_user_id_match(self, request, prep_info,
                                               user_id, credential_id):
     # NOTE(morganfainberg): this method needs to capture the arguments of
     # the method that is decorated with @controller.protected() (with
     # exception of the first argument ('context') since the protected
     # method passes in *args, **kwargs. In this case, it is easier to see
     # the expected input if the argspec is `user_id` and `credential_id`
     # explicitly (matching the :class:`.ec2_delete_credential()` method
     # below).
     ref = {}
     credential_id = utils.hash_access_key(credential_id)
     ref['credential'] = self.credential_api.get_credential(credential_id)
     # NOTE(morganfainberg): policy_api is required for this
     # check_protection to properly be able to perform policy enforcement.
     self.check_protection(request, prep_info, ref)
예제 #29
0
    def test_ec2_cannot_get_non_ec2_credential(self):
        access_key = uuid.uuid4().hex
        cred_id = utils.hash_access_key(access_key)
        non_ec2_cred = unit.new_credential_ref(user_id=self.user_id,
                                               project_id=self.project_id)
        non_ec2_cred['id'] = cred_id
        PROVIDERS.credential_api.create_credential(cred_id, non_ec2_cred)

        # if access_key is not found, ec2 controller raises Unauthorized
        # exception
        path = '/'.join([self._get_ec2_cred_uri(), access_key])
        self.public_request(method='GET',
                            token=self.get_scoped_token(),
                            path=path,
                            expected_status=http_client.UNAUTHORIZED)
예제 #30
0
    def _migrate_ec2(self):
        for x in self._data["credentials"]:
            blob = {"access": x["key"], "secret": x["secret"]}
            credential_id = utils.hash_access_key(blob["access"])
            new_dict = {
                "user_id": x["user_id"],
                "blob": json.dumps(blob),
                "project_id": x["tenant_id"],
                "id": credential_id,
                "type": "ec2",
            }

            try:
                self.ec2_driver.create_credential(credential_id, new_dict)
            except exc.IntegrityError:
                LOG.exception(_("Cannot migrate EC2 credential: %s") % x)
예제 #31
0
    def _assert_owner(self, user_id, credential_id):
        """Ensure the provided user owns the credential.

        :param user_id: expected credential owner
        :param credential_id: id of credential object
        :raises exception.Forbidden: on failure

        """
        ec2_credential_id = utils.hash_access_key(credential_id)
        cred_ref = self.credential_api.get_credential(ec2_credential_id)
        if user_id != cred_ref['user_id']:
            raise exception.Forbidden(_('Credential belongs to another user'))

#class AccessKeyController(identity.controllers.UserV3):

#@controller.protected()
#def reset_access_key(self, context, user_id):
        '''token_id = context.get('token_id')
예제 #32
0
    def delete_credential(self, context, user_id, credential_id):
        """Delete a user's access/secret pair.

        Used to revoke a user's access/secret pair

        :param context: standard context
        :param user_id: id of user
        :param credential_id: access key for credentials
        :returns: bool: success
        """
        if not self._is_admin(context):
            self._assert_identity(context, user_id)
            self._assert_owner(user_id, credential_id)

        self._assert_valid_user_id(user_id)
        self._get_credentials(credential_id)
        ec2_credential_id = utils.hash_access_key(credential_id)
        return self.credential_api.delete_credential(ec2_credential_id)
예제 #33
0
    def delete_credential(self, context, user_id, credential_id):
        """Delete a user's access/secret pair.

        Used to revoke a user's access/secret pair

        :param context: standard context
        :param user_id: id of user
        :param credential_id: access key for credentials
        :returns: bool: success
        """
        if not self._is_admin(context):
            self._assert_identity(context, user_id)
            self._assert_owner(user_id, credential_id)

        self._assert_valid_user_id(user_id)
        self._get_credentials(credential_id)
        ec2_credential_id = utils.hash_access_key(credential_id)
        return self.credential_api.delete_credential(ec2_credential_id)
예제 #34
0
파일: nova.py 프로젝트: niuzhenguo/keystone
def _create_ec2_creds(ec2_api, assignment_api, ec2_creds, user_map):
    for ec2_cred in ec2_creds:
        user_id = user_map[ec2_cred['user_id']]
        for tenant_id in assignment_api.get_projects_for_user(user_id):
            blob = {
                'access': '%s:%s' % (tenant_id, ec2_cred['access_key']),
                'secret': ec2_cred['secret_key'],
            }
            credential_id = utils.hash_access_key(blob['access'])
            cred_dict = {
                'user_id': user_id,
                'blob': json.dumps(blob),
                'project_id': tenant_id,
                'id': credential_id,
                'type': 'ec2',
            }
            LOG.debug(_(
                'Creating ec2 cred for user %(user_id)s and tenant '
                '%(tenant_id)s') % {
                    'user_id': user_id, 'tenant_id': tenant_id})
            ec2_api.create_credential(credential_id, cred_dict)
예제 #35
0
    def create_credential(self, context, user_id, tenant_id):
        """Create a secret/access pair for use with ec2 style auth.

        Generates a new set of credentials that map the user/tenant
        pair.

        :param context: standard context
        :param user_id: id of user
        :param tenant_id: id of tenant
        :returns: credential: dict of ec2 credential
        """
        if not self._is_admin(context):
            self._assert_identity(context, user_id)

        self._assert_valid_user_id(user_id)
        self._assert_valid_project_id(tenant_id)
        trust_id = self._context_trust_id(context)
        blob = {"access": uuid.uuid4().hex, "secret": uuid.uuid4().hex, "trust_id": trust_id}
        credential_id = utils.hash_access_key(blob["access"])
        cred_ref = {"user_id": user_id, "project_id": tenant_id, "blob": blob, "id": credential_id, "type": "ec2"}
        self.credential_api.create_credential(credential_id, cred_ref)
        return {"credential": self._convert_v3_to_ec2_credential(cred_ref)}
예제 #36
0
    def create_credential(self, request, user_id, tenant_id):
        """Create a secret/access pair for use with ec2 style auth.

        Generates a new set of credentials that map the user/tenant
        pair.

        :param request: current request
        :param user_id: id of user
        :param tenant_id: id of tenant
        :returns: credential: dict of ec2 credential
        """
        self.identity_api.get_user(user_id)
        self.resource_api.get_project(tenant_id)
        blob = {'access': uuid.uuid4().hex,
                'secret': uuid.uuid4().hex,
                'trust_id': request.context.trust_id}
        credential_id = utils.hash_access_key(blob['access'])
        cred_ref = {'user_id': user_id,
                    'project_id': tenant_id,
                    'blob': jsonutils.dumps(blob),
                    'id': credential_id,
                    'type': CRED_TYPE_EC2}
        self.credential_api.create_credential(credential_id, cred_ref)
        return {'credential': self._convert_v3_to_ec2_credential(cred_ref)}
예제 #37
0
    def handle_authenticate(self):
        # TODO(morgan): convert this dirty check to JSON Schema validation
        # this mirrors the previous behavior of the webob system where an
        # empty request body for s3 and ec2 tokens would result in a BAD
        # REQUEST. Almost all other APIs use JSON Schema and therefore would
        # catch this early on. S3 and EC2 did not ever get json schema
        # implemented for them.
        if not self.request_body_json:
            msg = _('request must include a request body')
            raise ks_exceptions.ValidationError(msg)

        # NOTE(morgan): THIS IS SLOPPY! Apparently... keystone passed values
        # as "credential" and "credentials" in into the s3/ec2 authenticate
        # methods. There is no reason the multiple names should have worked
        # except that we totally did something wonky in the past... so now
        # there are 2 dirty "acceptable" body hacks for compatibility....
        # Try "credentials" then "credential" and THEN ec2Credentials. Final
        # default is {}
        credentials = (
            self.request_body_json.get('credentials') or
            self.request_body_json.get('credential') or
            self.request_body_json.get('ec2Credentials')
        )
        if not credentials:
            credentials = {}

        if 'access' not in credentials:
            raise ks_exceptions.Unauthorized(_('EC2 Signature not supplied'))

        # Load the credential from the backend
        credential_id = utils.hash_access_key(credentials['access'])
        cred = PROVIDERS.credential_api.get_credential(credential_id)
        if not cred or cred['type'] != CRED_TYPE_EC2:
            raise ks_exceptions.Unauthorized(_('EC2 access key not found.'))

        # load from json if needed
        try:
            loaded = jsonutils.loads(cred['blob'])
        except TypeError:
            loaded = cred['blob']

        # Convert to the legacy format
        cred_data = dict(
            user_id=cred.get('user_id'),
            project_id=cred.get('project_id'),
            access=loaded.get('access'),
            secret=loaded.get('secret'),
            trust_id=loaded.get('trust_id')
        )

        # validate the signature
        self._check_signature(cred_data, credentials)
        project_ref = PROVIDERS.resource_api.get_project(
            cred_data['project_id'])
        user_ref = PROVIDERS.identity_api.get_user(cred_data['user_id'])

        # validate that the auth info is valid and nothing is disabled
        try:
            PROVIDERS.identity_api.assert_user_enabled(
                user_id=user_ref['id'], user=user_ref)
            PROVIDERS.resource_api.assert_project_enabled(
                project_id=project_ref['id'], project=project_ref)
        except AssertionError as e:
            six.reraise(
                ks_exceptions.Unauthorized,
                ks_exceptions.Unauthorized(e),
                sys.exc_info()[2])

        roles = PROVIDERS.assignment_api.get_roles_for_user_and_project(
            user_ref['id'], project_ref['id'])

        if not roles:
            raise ks_exceptions.Unauthorized(_('User not valid for project.'))

        for r_id in roles:
            # Assert all roles exist.
            PROVIDERS.role_api.get_role(r_id)

        method_names = ['ec2credential']

        token = PROVIDERS.token_provider_api.issue_token(
            user_id=user_ref['id'], method_names=method_names,
            project_id=project_ref['id'])
        return token
예제 #38
0
    def handle_authenticate(self):
        # TODO(morgan): convert this dirty check to JSON Schema validation
        # this mirrors the previous behavior of the webob system where an
        # empty request body for s3 and ec2 tokens would result in a BAD
        # REQUEST. Almost all other APIs use JSON Schema and therefore would
        # catch this early on. S3 and EC2 did not ever get json schema
        # implemented for them.
        if not self.request_body_json:
            msg = _('request must include a request body')
            raise ks_exceptions.ValidationError(msg)

        # NOTE(morgan): THIS IS SLOPPY! Apparently... keystone passed values
        # as "credential" and "credentials" in into the s3/ec2 authenticate
        # methods. There is no reason the multiple names should have worked
        # except that we totally did something wonky in the past... so now
        # there are 2 dirty "acceptable" body hacks for compatibility....
        # Try "credentials" then "credential" and THEN ec2Credentials. Final
        # default is {}
        credentials = (self.request_body_json.get('credentials')
                       or self.request_body_json.get('credential')
                       or self.request_body_json.get('ec2Credentials'))
        if not credentials:
            credentials = {}

        if 'access' not in credentials:
            raise ks_exceptions.Unauthorized(_('EC2 Signature not supplied'))

        # Load the credential from the backend
        credential_id = utils.hash_access_key(credentials['access'])
        cred = PROVIDERS.credential_api.get_credential(credential_id)
        if not cred or cred['type'] != CRED_TYPE_EC2:
            raise ks_exceptions.Unauthorized(_('EC2 access key not found.'))

        # load from json if needed
        try:
            loaded = jsonutils.loads(cred['blob'])
        except TypeError:
            loaded = cred['blob']

        # Convert to the legacy format
        cred_data = dict(user_id=cred.get('user_id'),
                         project_id=cred.get('project_id'),
                         access=loaded.get('access'),
                         secret=loaded.get('secret'),
                         trust_id=loaded.get('trust_id'))

        # validate the signature
        self._check_signature(cred_data, credentials)
        project_ref = PROVIDERS.resource_api.get_project(
            cred_data['project_id'])
        user_ref = PROVIDERS.identity_api.get_user(cred_data['user_id'])

        # validate that the auth info is valid and nothing is disabled
        try:
            PROVIDERS.identity_api.assert_user_enabled(user_id=user_ref['id'],
                                                       user=user_ref)
            PROVIDERS.resource_api.assert_project_enabled(
                project_id=project_ref['id'], project=project_ref)
        except AssertionError as e:
            raise ks_exceptions.Unauthorized from e

        self._check_timestamp(credentials)
        roles = PROVIDERS.assignment_api.get_roles_for_user_and_project(
            user_ref['id'], project_ref['id'])

        if not roles:
            raise ks_exceptions.Unauthorized(_('User not valid for project.'))

        for r_id in roles:
            # Assert all roles exist.
            PROVIDERS.role_api.get_role(r_id)

        method_names = ['ec2credential']

        token = PROVIDERS.token_provider_api.issue_token(
            user_id=user_ref['id'],
            method_names=method_names,
            project_id=project_ref['id'])
        return token