def test_token_expire_timezone(self):

        @test_utils.timezone
        def _create_token(expire_time):
            token_id = uuid.uuid4().hex
            user_id = six.text_type(uuid.uuid4().hex)
            data = {'id': token_id, 'a': 'b', 'user': {'id': user_id},
                    'expires': expire_time
                    }
            self.token_api.create_token(token_id, data)
            return data

        for d in ['+0', '-11', '-8', '-5', '+5', '+8', '+14']:
            test_utils.TZ = 'UTC' + d
            expire_time = timeutils.utcnow() + \
                datetime.timedelta(minutes=1)
            data_in = _create_token(expire_time)
            data_get = None
            data_get = self.token_api.get_token(data_in['id'])

            self.assertIsNotNone(data_get, "TZ=%s" % test_utils.TZ)
            self.assertEqual(data_in['id'], data_get['id'],
                             "TZ=%s" % test_utils.TZ)

            expire_time_expired = timeutils.utcnow() + \
                datetime.timedelta(minutes=-1)
            data_in = _create_token(expire_time_expired)
            self.assertRaises(exception.TokenNotFound,
                              self.token_api.get_token, data_in['id'])
Beispiel #2
0
        def _inner():
            if initial_delay:
                greenthread.sleep(initial_delay)

            try:
                while self._running:
                    start = timeutils.utcnow()
                    self.f(*self.args, **self.kw)
                    end = timeutils.utcnow()
                    if not self._running:
                        break
                    delay = interval - timeutils.delta_seconds(start, end)
                    if delay <= 0:
                        LOG.warn(_LW('task run outlasted interval by %s sec') %
                                 -delay)
                    greenthread.sleep(delay if delay > 0 else 0)
            except LoopingCallDone as e:
                self.stop()
                done.send(e.retvalue)
            except Exception:
                LOG.exception(_LE('in fixed duration looping call'))
                done.send_exception(*sys.exc_info())
                return
            else:
                done.send(True)
Beispiel #3
0
 def _get_doc_date(self):
     if self.ttl_seconds > 0:
         expire_delta = datetime.timedelta(seconds=self.ttl_seconds)
         doc_date = timeutils.utcnow() + expire_delta
     else:
         doc_date = timeutils.utcnow()
     return doc_date
Beispiel #4
0
 def test_list_since(self):
     self.revoke_api.revoke_by_user(user_id=1)
     self.revoke_api.revoke_by_user(user_id=2)
     past = timeutils.utcnow() - datetime.timedelta(seconds=1000)
     self.assertEqual(2, len(self.revoke_api.get_events(past)))
     future = timeutils.utcnow() + datetime.timedelta(seconds=1000)
     self.assertEqual(0, len(self.revoke_api.get_events(future)))
Beispiel #5
0
 def _format_token(self, token_ref, roles_ref, catalog_ref=None):
     user_ref = token_ref['user']
     metadata_ref = token_ref['metadata']
     expires = token_ref['expires']
     issue_time = timeutils.utcnow().time().isoformat()
     if expires is not None:
         if not isinstance(expires, unicode):
             expires = timeutils.isotime(expires)
     o = {'access': {'token': {'id': token_ref['id'],
                               'expires': expires,
                               'issued_at': issue_time
                               },
                     'user': {'id': user_ref['id'],
                              'name': user_ref['name'],
                              'username': user_ref['name'],
                              'roles': roles_ref,
                              'roles_links': metadata_ref.get('roles_links',
                                                              [])
                              }
                     }
          }
     if 'tenant' in token_ref and token_ref['tenant']:
         token_ref['tenant']['enabled'] = True
         o['access']['token']['tenant'] = token_ref['tenant']
     if catalog_ref is not None:
         o['access']['serviceCatalog'] = self._format_catalog(catalog_ref)
     if metadata_ref:
         if 'is_admin' in metadata_ref:
             o['access']['metadata'] = {'is_admin':
                                        metadata_ref['is_admin']}
         else:
             o['access']['metadata'] = {'is_admin': 0}
     if 'roles' in metadata_ref:
             o['access']['metadata']['roles'] = metadata_ref['roles']
     return o
Beispiel #6
0
def _filter_trust(ref):
    if ref["deleted"]:
        return None
    if ref.get("expires_at") and timeutils.utcnow() > ref["expires_at"]:
        return None
    ref = copy.deepcopy(ref)
    return ref
Beispiel #7
0
def _filter_trust(ref):
    if ref['deleted']:
        return None
    if ref.get('expires_at') and timeutils.utcnow() > ref['expires_at']:
        return None
    ref = copy.deepcopy(ref)
    return ref
Beispiel #8
0
    def authenticate(self, context, auth_info, auth_context):
        """Turn a signed request with an access key into a keystone token."""

        if not self.oauth_api:
            raise exception.Unauthorized(_("%s not supported") % self.method)

        headers = context["headers"]
        oauth_headers = oauth.get_oauth_headers(headers)
        access_token_id = oauth_headers.get("oauth_token")

        if not access_token_id:
            raise exception.ValidationError(attribute="oauth_token", target="request")

        acc_token = self.oauth_api.get_access_token(access_token_id)

        expires_at = acc_token["expires_at"]
        if expires_at:
            now = timeutils.utcnow()
            expires = timeutils.normalize_time(timeutils.parse_isotime(expires_at))
            if now > expires:
                raise exception.Unauthorized(_("Access token is expired"))

        url = controller.V3Controller.base_url(context, context["path"])
        access_verifier = oauth.ResourceEndpoint(
            request_validator=validator.OAuthValidator(), token_generator=oauth.token_generator
        )
        result, request = access_verifier.validate_protected_resource_request(
            url, http_method="POST", body=context["query_string"], headers=headers, realms=None
        )
        if not result:
            msg = _("Could not validate the access token")
            raise exception.Unauthorized(msg)
        auth_context["user_id"] = acc_token["authorizing_user_id"]
        auth_context["access_token_id"] = access_token_id
        auth_context["project_id"] = acc_token["project_id"]
Beispiel #9
0
    def _is_valid_token(self, token):
        """Verify the token is valid format and has not expired."""

        current_time = timeutils.normalize_time(timeutils.utcnow())

        try:
            # Get the data we need from the correct location (V2 and V3 tokens
            # differ in structure, Try V3 first, fall back to V2 second)
            token_data = token.get('token', token.get('access'))
            expires_at = token_data.get('expires_at',
                                        token_data.get('expires'))
            if not expires_at:
                expires_at = token_data['token']['expires']
            expiry = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
        except Exception:
            LOG.exception(_('Unexpected error or malformed token determining '
                            'token expiry: %s'), token)
            raise exception.TokenNotFound(_('Failed to validate token'))

        if current_time < expiry:
            self.check_revocation(token)
            # Token has not expired and has not been revoked.
            return None
        else:
            raise exception.TokenNotFound(_('Failed to validate token'))
    def test_cleanup_user_index_on_create(self):
        valid_token_id = uuid.uuid4().hex
        second_valid_token_id = uuid.uuid4().hex
        expired_token_id = uuid.uuid4().hex
        user_id = unicode(uuid.uuid4().hex)

        expire_delta = datetime.timedelta(seconds=86400)

        valid_data = {'id': valid_token_id, 'a': 'b',
                      'user': {'id': user_id}}
        second_valid_data = {'id': second_valid_token_id, 'a': 'b',
                             'user': {'id': user_id}}
        expired_data = {'id': expired_token_id, 'a': 'b',
                        'user': {'id': user_id}}
        self.token_api.create_token(valid_token_id, valid_data)
        self.token_api.create_token(expired_token_id, expired_data)
        # NOTE(morganfainberg): Directly access the data cache since we need to
        # get expired tokens as well as valid tokens. token_api.list_tokens()
        # will not return any expired tokens in the list.
        user_key = self.token_api.driver._prefix_user_id(user_id)
        user_record = self.token_api.driver.client.get(user_key)
        user_token_list = jsonutils.loads('[%s]' % user_record)
        self.assertEquals(len(user_token_list), 2)
        expired_token_ptk = self.token_api.driver._prefix_token_id(
            expired_token_id)
        expired_token = self.token_api.driver.client.get(expired_token_ptk)
        expired_token['expires'] = (timeutils.utcnow() - expire_delta)
        self.token_api.driver.client.set(expired_token_ptk, expired_token)

        self.token_api.create_token(second_valid_token_id, second_valid_data)
        user_record = self.token_api.driver.client.get(user_key)
        user_token_list = jsonutils.loads('[%s]' % user_record)
        self.assertEquals(len(user_token_list), 2)
Beispiel #11
0
    def _convert_user_index_from_json(self, token_list, user_key):
        try:
            # NOTE(morganfainberg): Try loading in the old format
            # of the list.
            token_list = jsonutils.loads('[%s]' % token_list)

            # NOTE(morganfainberg): Build a delta based upon the
            # token TTL configured. Since we are using the old
            # format index-list, we will create a "fake" expiration
            # that should be further in the future than the actual
            # expiry. To avoid locking up keystone trying to
            # communicate to memcached, it is better to use a fake
            # value. The logic that utilizes this list already
            # knows how to handle the case of tokens that are
            # no longer valid being included.
            delta = datetime.timedelta(
                seconds=CONF.token.expiration)
            new_expiry = timeutils.normalize_time(
                timeutils.utcnow()) + delta

            for idx, token_id in enumerate(token_list):
                token_list[idx] = (token_id, new_expiry)

        except Exception:
            # NOTE(morganfainberg): Catch any errors thrown here. There is
            # nothing the admin or operator needs to do in this case, but
            # it should be logged that there was an error and some action was
            # taken to correct it
            LOG.exception(_('Error converting user-token-index to new format; '
                            'clearing user token index record "%s".'),
                          user_key)
            token_list = []
        return token_list
Beispiel #12
0
    def create_access_token(self, request_token_id, token_duration,
                            access_token_id=None, access_token_secret=None):
        if access_token_id is None:
            access_token_id = uuid.uuid4().hex
        if access_token_secret is None:
            access_token_secret = uuid.uuid4().hex
        session = sql.get_session()
        with session.begin():
            req_token_ref = self._get_request_token(session, request_token_id)
            token_dict = req_token_ref.to_dict()

            expiry_date = None
            if token_duration:
                now = timeutils.utcnow()
                future = now + datetime.timedelta(seconds=token_duration)
                expiry_date = timeutils.isotime(future, subsecond=True)

            # add Access Token
            ref = {}
            ref['id'] = access_token_id
            ref['access_secret'] = access_token_secret
            ref['authorizing_user_id'] = token_dict['authorizing_user_id']
            ref['project_id'] = token_dict['requested_project_id']
            ref['role_ids'] = token_dict['role_ids']
            ref['consumer_id'] = token_dict['consumer_id']
            ref['expires_at'] = expiry_date
            token_ref = AccessToken.from_dict(ref)
            session.add(token_ref)

            # remove request token, it's been used
            session.delete(req_token_ref)

        return token_ref.to_dict()
Beispiel #13
0
    def new_trust_ref(self, trustor_user_id, trustee_user_id, project_id=None,
                      impersonation=None, expires=None, role_ids=None,
                      role_names=None, remaining_uses=None):
        ref = self.new_ref()

        ref['trustor_user_id'] = trustor_user_id
        ref['trustee_user_id'] = trustee_user_id
        ref['impersonation'] = impersonation or False
        ref['project_id'] = project_id
        ref['remaining_uses'] = remaining_uses

        if isinstance(expires, six.string_types):
            ref['expires_at'] = expires
        elif isinstance(expires, dict):
            ref['expires_at'] = timeutils.strtime(
                timeutils.utcnow() + datetime.timedelta(**expires),
                fmt=TIME_FORMAT)
        elif expires is None:
            pass
        else:
            raise NotImplementedError('Unexpected value for "expires"')

        role_ids = role_ids or []
        role_names = role_names or []
        if role_ids or role_names:
            ref['roles'] = []
            for role_id in role_ids:
                ref['roles'].append({'id': role_id})
            for role_name in role_names:
                ref['roles'].append({'name': role_name})

        return ref
Beispiel #14
0
    def create_access_token(self, request_token_id, token_duration):
        session = self.get_session()
        with session.begin():
            req_token_ref = self._get_request_token(session, request_token_id)
            token_dict = req_token_ref.to_dict()

            expiry_date = None
            if token_duration:
                now = timeutils.utcnow()
                future = now + datetime.timedelta(seconds=token_duration)
                expiry_date = timeutils.isotime(future, subsecond=True)

            # add Access Token
            ref = {}
            access_token_id = uuid.uuid4().hex
            ref['id'] = access_token_id
            ref['access_secret'] = uuid.uuid4().hex
            ref['authorizing_user_id'] = token_dict['authorizing_user_id']
            ref['project_id'] = token_dict['requested_project_id']
            ref['requested_roles'] = token_dict['requested_roles']
            ref['consumer_id'] = token_dict['consumer_id']
            ref['expires_at'] = expiry_date
            token_ref = AccessToken.from_dict(ref)
            session.add(token_ref)

            # remove request token, it's been used
            q = session.query(RequestToken)
            q = q.filter_by(id=request_token_id)
            q.delete(False)
            session.delete(req_token_ref)

            session.flush()
        return token_ref.to_dict()
Beispiel #15
0
    def _is_valid_token(self, token):
         # Verify the token has not expired.
        current_time = timeutils.normalize_time(timeutils.utcnow())

        try:
            # Get the data we need from the correct location (V2 and V3 tokens
            # differ in structure, Try V3 first, fall back to V2 second)
            token_data = token.get('token', token.get('access'))
            expires_at = token_data.get('expires_at',
                                        token_data.get('expires'))
            if not expires_at:
                expires_at = token_data['token']['expires']
            expiry = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
            if current_time < expiry:
                # Token is has not expired and has not been revoked.
                return None
        except Exception:
            LOG.exception(_('Unexpected error or malformed token determining '
                            'token expiry: %s') % token)

        # FIXME(morganfainberg): This error message needs to be updated to
        # reflect the token couldn't be found, but this change needs to wait
        # until Icehouse due to string freeze in Havana.  This should be:
        # "Failed to find valid token" or something similar.
        raise exception.TokenNotFound(_('Failed to validate token'))
Beispiel #16
0
    def delete_tokens(self, user_id, tenant_id=None, trust_id=None):
        """Deletes all tokens in one session

        The user_id will be ignored if the trust_id is specified. user_id
        will always be specified.
        If using a trust, the token's user_id is set to the trustee's user ID
        or the trustor's user ID, so will use trust_id to query the tokens.

        """
        session = self.get_session()
        with session.begin():
            now = timeutils.utcnow()
            query = session.query(TokenModel)
            query = query.filter_by(valid=True)
            query = query.filter(TokenModel.expires > now)
            if trust_id:
                query = query.filter(TokenModel.trust_id == trust_id)
            else:
                query = query.filter(TokenModel.user_id == user_id)

            for token_ref in query.all():
                if tenant_id:
                    token_ref_dict = token_ref.to_dict()
                    if not self._tenant_matches(tenant_id, token_ref_dict):
                        continue
                token_ref.valid = False

            session.flush()
    def test_cleanup_user_index_on_create(self):
        valid_token_id = uuid.uuid4().hex
        second_valid_token_id = uuid.uuid4().hex
        expired_token_id = uuid.uuid4().hex
        user_id = six.text_type(uuid.uuid4().hex)

        expire_delta = datetime.timedelta(seconds=CONF.token.expiration)

        valid_data = {'id': valid_token_id, 'a': 'b',
                      'user': {'id': user_id}}
        second_valid_data = {'id': second_valid_token_id, 'a': 'b',
                             'user': {'id': user_id}}
        expired_data = {'id': expired_token_id, 'a': 'b',
                        'user': {'id': user_id}}
        self.token_api.create_token(valid_token_id, valid_data)
        self.token_api.create_token(expired_token_id, expired_data)
        # NOTE(morganfainberg): Directly access the data cache since we need to
        # get expired tokens as well as valid tokens. token_api._list_tokens()
        # will not return any expired tokens in the list.
        user_key = self.token_api.driver._prefix_user_id(user_id)
        user_token_list = self.token_api.driver.client.get(user_key)
        self.assertEqual(len(user_token_list), 2)
        # user_token_list is a list of (token, expiry) tuples
        expired_idx = [i[0] for i in user_token_list].index(expired_token_id)
        # set the token as expired.
        user_token_list[expired_idx] = (user_token_list[expired_idx][0],
                                        timeutils.utcnow() - expire_delta)
        self.token_api.driver.client.set(user_key, user_token_list)

        self.token_api.create_token(second_valid_token_id, second_valid_data)
        user_token_list = self.token_api.driver.client.get(user_key)
        self.assertEqual(len(user_token_list), 2)
Beispiel #18
0
 def test_expired_token(self):
     token_id = uuid.uuid4().hex
     expire_time = timeutils.utcnow() - datetime.timedelta(minutes=1)
     data = {"id_hash": token_id, "id": token_id, "a": "b", "expires": expire_time, "user": {"id": "testuserid"}}
     data_ref = self.token_api.create_token(token_id, data)
     self.assertDictEqual(data_ref, data)
     self.assertRaises(exception.TokenNotFound, self.token_api.get_token, token_id)
Beispiel #19
0
 def delete_trust(self, trust_id):
     session = db_session.get_session()
     with session.begin():
         trust_ref = session.query(TrustModel).get(trust_id)
         if not trust_ref:
             raise exception.TrustNotFound(trust_id=trust_id)
         trust_ref.deleted_at = timeutils.utcnow()
Beispiel #20
0
    def setUp(self):
        super(AuthWithTrust, self).setUp()
        self.opt_in_group('trust', enabled=True)

        trust.Manager()
        self.trust_controller = trust.controllers.TrustV3()
        self.auth_v3_controller = auth.controllers.Auth()
        self.trustor = self.user_foo
        self.trustee = self.user_two
        self.assigned_roles = [self.role_member['id'],
                               self.role_browser['id']]
        for assigned_role in self.assigned_roles:
            self.assignment_api.add_role_to_user_and_project(
                self.trustor['id'], self.tenant_bar['id'], assigned_role)

        self.sample_data = {'trustor_user_id': self.trustor['id'],
                            'trustee_user_id': self.trustee['id'],
                            'project_id': self.tenant_bar['id'],
                            'impersonation': True,
                            'roles': [{'id': self.role_browser['id']},
                                      {'name': self.role_member['name']}]}
        expires_at = timeutils.strtime(timeutils.utcnow() +
                                       datetime.timedelta(minutes=10),
                                       fmt=TIME_FORMAT)
        self.create_trust(expires_at=expires_at)
 def get(self, key):
     """Retrieves the value for a key or None."""
     self.check_key(key)
     obj = self.cache.get(key)
     now = utils.unixtime(timeutils.utcnow())
     if obj and (obj[1] == 0 or obj[1] > now):
         return obj[0]
Beispiel #22
0
    def create_request_token(self, consumer_id, roles,
                             project_id, token_duration):
        expiry_date = None
        if token_duration:
            now = timeutils.utcnow()
            future = now + datetime.timedelta(seconds=token_duration)
            expiry_date = timeutils.isotime(future, subsecond=True)

        ref = {}
        request_token_id = uuid.uuid4().hex
        ref['id'] = request_token_id
        ref['request_secret'] = uuid.uuid4().hex
        ref['verifier'] = None
        ref['authorizing_user_id'] = None
        ref['requested_project_id'] = project_id
        ref['requested_roles'] = roles
        ref['consumer_id'] = consumer_id
        ref['expires_at'] = expiry_date
        self.db.set('request_token-%s' % request_token_id, ref)

        # add req token to the list that containers the consumers req tokens
        consumer_requests = set(self.db.get('consumer-%s-requests' %
                                            consumer_id, []))
        consumer_requests.add(request_token_id)
        self.db.set('consumer-%s-requests' %
                    consumer_id, list(consumer_requests))
        return ref
Beispiel #23
0
    def create_request_token(self, consumer_id, project_id, token_duration,
                             request_token_id=None, request_token_secret=None):
        if request_token_id is None:
            request_token_id = uuid.uuid4().hex
        if request_token_secret is None:
            request_token_secret = uuid.uuid4().hex
        expiry_date = None
        if token_duration:
            now = timeutils.utcnow()
            future = now + datetime.timedelta(seconds=token_duration)
            expiry_date = timeutils.isotime(future, subsecond=True)

        ref = {}
        ref['id'] = request_token_id
        ref['request_secret'] = request_token_secret
        ref['verifier'] = None
        ref['authorizing_user_id'] = None
        ref['requested_project_id'] = project_id
        ref['role_ids'] = None
        ref['consumer_id'] = consumer_id
        ref['expires_at'] = expiry_date
        session = sql.get_session()
        with session.begin():
            token_ref = RequestToken.from_dict(ref)
            session.add(token_ref)
        return token_ref.to_dict()
Beispiel #24
0
    def flush_expired_tokens(self):
        session = self.get_session()

        query = session.query(TokenModel)
        query = query.filter(TokenModel.expires < timeutils.utcnow())
        query.delete(synchronize_session=False)

        session.flush()
def create_v3_token():
    return {
        "token": {
            "methods": [],
            "expires_at": timeutils.isotime(timeutils.utcnow() + FUTURE_DELTA),
            "issued_at": "2013-05-21T00:02:43.941473Z",
        }
    }
Beispiel #26
0
    def _get_default_expire_time(self):
        """Determine when a token should expire based on the config.

        :returns: a naive utc datetime.datetime object

        """
        expire_delta = datetime.timedelta(seconds=CONF.token.expiration)
        return timeutils.utcnow() + expire_delta
Beispiel #27
0
 def get_token(self, token_id):
     session = self.get_session()
     token_ref = session.query(TokenModel).filter_by(id=token_id).first()
     now = timeutils.utcnow()
     if token_ref and (not token_ref.expires or now < token_ref.expires):
         return token_ref.to_dict()
     else:
         raise exception.TokenNotFound(token_id=token_id)
Beispiel #28
0
 def __init__(self, **kwargs):
     for k in REVOKE_KEYS:
         v = kwargs.get(k, None)
         setattr(self, k, v)
     if self.revoked_at is None:
         self.revoked_at = timeutils.utcnow()
     if self.issued_before is None:
         self.issued_before = self.revoked_at
Beispiel #29
0
def will_expire_soon(expiry):
    """ Determines if expiration is about to occur.

    :param expiry: a datetime of the expected expiration
    :returns: boolean : true if expiration is within 30 seconds
    """
    soon = (timeutils.utcnow() + datetime.timedelta(seconds=30))
    return expiry < soon
Beispiel #30
0
 def test_expired_token(self):
     token_id = uuid.uuid4().hex
     expire_time = timeutils.utcnow() - datetime.timedelta(minutes=1)
     data = {'id': token_id, 'a': 'b', 'expires': expire_time}
     data_ref = self.token_api.create_token(token_id, data)
     self.assertDictEqual(data_ref, data)
     self.assertRaises(exception.TokenNotFound,
                       self.token_api.get_token, token_id)
Beispiel #31
0
    def get_trust(self, trust_id):
        session = db_session.get_session()
        ref = (session.query(TrustModel).
               filter_by(deleted_at=None).
               filter_by(id=trust_id).first())
        if ref is None:
            return None
        if ref.expires_at is not None:
            now = timeutils.utcnow()
            if now > ref.expires_at:
                return None
        # Do not return trusts that can't be used anymore
        if ref.remaining_uses is not None:
            if ref.remaining_uses <= 0:
                return None
        trust_dict = ref.to_dict()

        self._add_roles(trust_id, session, trust_dict)
        return trust_dict
Beispiel #32
0
    def test_by_user_expiration(self):
        future_time = _future_time()

        user_id = 1
        event = self._revoke_by_expiration(user_id, future_time)
        token_data_1 = _sample_blank_token()
        token_data_1['user_id'] = user_id
        token_data_1['expires_at'] = future_time
        self._assertTokenRevoked(token_data_1)

        token_data_2 = _sample_blank_token()
        token_data_2['user_id'] = user_id
        expire_delta = datetime.timedelta(seconds=2000)
        future_time = timeutils.utcnow() + expire_delta
        token_data_2['expires_at'] = future_time
        self._assertTokenNotRevoked(token_data_2)

        self.removeEvent(event)
        self._assertTokenNotRevoked(token_data_1)
Beispiel #33
0
 def list_tokens(self, user_id, tenant_id=None):
     tokens = []
     now = timeutils.utcnow()
     for token, ref in self.db.items():
         if not token.startswith('token-'):
             continue
         if 'user' not in ref:
             continue
         if ref['user'].get('id') != user_id:
             continue
         if ref.get('expires') and ref.get('expires') < now:
             continue
         if tenant_id is not None:
             if 'tenant' not in ref:
                 continue
             if ref['tenant'].get('id') != tenant_id:
                 continue
         tokens.append(token.split('-', 1)[1])
     return tokens
Beispiel #34
0
    def _list_tokens_for_user(self, user_id, tenant_id=None):
        def user_matches(user_id, ref):
            return ref.get('user') and ref['user'].get('id') == user_id

        def tenant_matches(tenant_id, ref):
            return ((tenant_id is None) or
                    (ref.get('tenant') and
                     ref['tenant'].get('id') == tenant_id))

        tokens = []
        now = timeutils.utcnow()
        for token, ref in self.db.items():
            if not token.startswith('token-') or self.is_expired(now, ref):
                continue
            else:
                if (user_matches(user_id, ref) and
                        tenant_matches(tenant_id, ref)):
                        tokens.append(token.split('-', 1)[1])
        return tokens
Beispiel #35
0
    def _list_tokens_for_user(self, user_id, tenant_id=None):
        def tenant_matches(tenant_id, token_ref_dict):
            return ((tenant_id is None) or
                    (token_ref_dict.get('tenant') and
                     token_ref_dict['tenant'].get('id') == tenant_id))

        session = self.get_session()
        tokens = []
        now = timeutils.utcnow()
        query = session.query(TokenModel)
        query = query.filter(TokenModel.expires > now)
        query = query.filter(TokenModel.user_id == user_id)

        token_references = query.filter_by(valid=True)
        for token_ref in token_references:
            token_ref_dict = token_ref.to_dict()
            if tenant_matches(tenant_id, token_ref_dict):
                tokens.append(token_ref['id'])
        return tokens
Beispiel #36
0
    def test_cleanup_user_index_on_create(self):
        valid_token_id = uuid.uuid4().hex
        second_valid_token_id = uuid.uuid4().hex
        expired_token_id = uuid.uuid4().hex
        user_id = unicode(uuid.uuid4().hex)

        expire_delta = datetime.timedelta(seconds=86400)

        valid_data = {'id': valid_token_id, 'a': 'b', 'user': {'id': user_id}}
        second_valid_data = {
            'id': second_valid_token_id,
            'a': 'b',
            'user': {
                'id': user_id
            }
        }
        expired_data = {
            'id': expired_token_id,
            'a': 'b',
            'user': {
                'id': user_id
            }
        }
        self.token_api.create_token(valid_token_id, valid_data)
        self.token_api.create_token(expired_token_id, expired_data)
        # NOTE(morganfainberg): Directly access the data cache since we need to
        # get expired tokens as well as valid tokens. token_api.list_tokens()
        # will not return any expired tokens in the list.
        user_key = self.token_api.driver._prefix_user_id(user_id)
        user_record = self.token_api.driver.client.get(user_key)
        user_token_list = jsonutils.loads('[%s]' % user_record)
        self.assertEquals(len(user_token_list), 2)
        expired_token_ptk = self.token_api.driver._prefix_token_id(
            expired_token_id)
        expired_token = self.token_api.driver.client.get(expired_token_ptk)
        expired_token['expires'] = (timeutils.utcnow() - expire_delta)
        self.token_api.driver.client.set(expired_token_ptk, expired_token)

        self.token_api.create_token(second_valid_token_id, second_valid_data)
        user_record = self.token_api.driver.client.get(user_key)
        user_token_list = jsonutils.loads('[%s]' % user_record)
        self.assertEquals(len(user_token_list), 2)
Beispiel #37
0
    def _prune_expired_events_and_get(self, last_fetch=None, new_event=None):
        pruned = []
        results = []
        expire_delta = datetime.timedelta(seconds=CONF.token.expiration)
        oldest = timeutils.utcnow() - expire_delta
        # TODO(ayoung): Store the time of the oldest event so that the
        # prune process can be skipped if none of the events have timed out.
        with self._store.get_lock(_EVENT_KEY) as lock:
            events = self._get_event()
            if new_event is not None:
                events.append(new_event)

            for event in events:
                revoked_at = event.revoked_at
                if revoked_at > oldest:
                    pruned.append(event)
                    if last_fetch is None or revoked_at > last_fetch:
                        results.append(event)
            self._store.set(_EVENT_KEY, pruned, lock)
        return results
Beispiel #38
0
    def authenticate(self, context, auth_info, auth_context):
        """Turn a signed request with an access key into a keystone token."""

        if not self.oauth_api:
            raise exception.Unauthorized(_('%s not supported') % self.method)

        headers = context['headers']
        oauth_headers = oauth.get_oauth_headers(headers)
        access_token_id = oauth_headers.get('oauth_token')

        if not access_token_id:
            raise exception.ValidationError(attribute='oauth_token',
                                            target='request')

        acc_token = self.oauth_api.get_access_token(access_token_id)

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

        url = controller.V3Controller.base_url(context, context['path'])
        access_verifier = oauth.ResourceEndpoint(
            request_validator=validator.OAuthValidator(),
            token_generator=oauth.token_generator)
        result, request = access_verifier.validate_protected_resource_request(
            url,
            http_method='POST',
            body=context['query_string'],
            headers=headers,
            realms=None)
        if not result:
            msg = _('Could not validate the access token')
            raise exception.Unauthorized(msg)
        auth_context['user_id'] = acc_token['authorizing_user_id']
        auth_context['access_token_id'] = access_token_id
        auth_context['project_id'] = acc_token['project_id']
Beispiel #39
0
    def __init__(self, **kwargs):
        for k in REVOKE_KEYS:
            v = kwargs.get(k, None)
            setattr(self, k, v)

        if self.domain_id and self.expires_at:
            # This is revoking a domain-scoped token.
            self.domain_scope_id = self.domain_id
            self.domain_id = None
        else:
            # This is revoking all tokens for a domain.
            self.domain_scope_id = None

        if self.expires_at is not None:
            # Trim off the expiration time because MySQL timestamps are only
            # accurate to the second.
            self.expires_at = self.expires_at.replace(microsecond=0)

        if self.revoked_at is None:
            self.revoked_at = timeutils.utcnow()
        if self.issued_before is None:
            self.issued_before = self.revoked_at
Beispiel #40
0
    def create_access_token(self,
                            request_token_id,
                            token_duration,
                            access_token_id=None,
                            access_token_secret=None):
        if access_token_id is None:
            access_token_id = uuid.uuid4().hex
        if access_token_secret is None:
            access_token_secret = uuid.uuid4().hex
        session = sql.get_session()
        with session.begin():
            req_token_ref = self._get_request_token(session, request_token_id)
            token_dict = req_token_ref.to_dict()

            expiry_date = None
            if token_duration:
                now = timeutils.utcnow()
                future = now + datetime.timedelta(seconds=token_duration)
                expiry_date = timeutils.isotime(future, subsecond=True)

            # add Access Token
            ref = {}
            ref['id'] = access_token_id
            ref['access_secret'] = access_token_secret
            ref['authorizing_user_id'] = token_dict['authorizing_user_id']
            ref['project_id'] = token_dict['requested_project_id']
            ref['role_ids'] = token_dict['role_ids']
            ref['consumer_id'] = token_dict['consumer_id']
            ref['expires_at'] = expiry_date
            token_ref = AccessToken.from_dict(ref)
            session.add(token_ref)

            # remove request token, it's been used
            q = session.query(RequestToken)
            q = q.filter_by(id=request_token_id)
            q.delete(False)
            session.delete(req_token_ref)

        return token_ref.to_dict()
Beispiel #41
0
 def list_tokens(self, user_id, tenant_id=None):
     session = self.get_session()
     tokens = []
     now = timeutils.utcnow()
     query = session.query(TokenModel)
     query = query.filter(TokenModel.expires > now)
     token_references = query.filter_by(valid=True)
     for token_ref in token_references:
         token_ref_dict = token_ref.to_dict()
         user = token_ref_dict.get('user')
         if not user:
             continue
         if user.get('id') != user_id:
             continue
         if tenant_id is not None:
             tenant = token_ref_dict.get('tenant')
             if not tenant:
                 continue
             if tenant.get('id') != tenant_id:
                 continue
         tokens.append(token_ref['id'])
     return tokens
Beispiel #42
0
    def new_trust_ref(self,
                      trustor_user_id,
                      trustee_user_id,
                      project_id=None,
                      impersonation=None,
                      expires=None,
                      role_ids=None,
                      role_names=None,
                      remaining_uses=None):
        ref = self.new_ref()

        ref['trustor_user_id'] = trustor_user_id
        ref['trustee_user_id'] = trustee_user_id
        ref['impersonation'] = impersonation or False
        ref['project_id'] = project_id
        ref['remaining_uses'] = remaining_uses

        if isinstance(expires, six.string_types):
            ref['expires_at'] = expires
        elif isinstance(expires, dict):
            ref['expires_at'] = timeutils.strtime(
                timeutils.utcnow() + datetime.timedelta(**expires),
                fmt=TIME_FORMAT)
        elif expires is None:
            pass
        else:
            raise NotImplementedError('Unexpected value for "expires"')

        role_ids = role_ids or []
        role_names = role_names or []
        if role_ids or role_names:
            ref['roles'] = []
            for role_id in role_ids:
                ref['roles'].append({'id': role_id})
            for role_name in role_names:
                ref['roles'].append({'name': role_name})

        return ref
Beispiel #43
0
    def create_request_token(self, consumer_id, project_id, token_duration):
        expiry_date = None
        if token_duration:
            now = timeutils.utcnow()
            future = now + datetime.timedelta(seconds=token_duration)
            expiry_date = timeutils.isotime(future, subsecond=True)

        ref = {}
        request_token_id = uuid.uuid4().hex
        ref['id'] = request_token_id
        ref['request_secret'] = uuid.uuid4().hex
        ref['verifier'] = None
        ref['authorizing_user_id'] = None
        ref['requested_project_id'] = project_id
        ref['role_ids'] = None
        ref['consumer_id'] = consumer_id
        ref['expires_at'] = expiry_date
        session = self.get_session()
        with session.begin():
            token_ref = RequestToken.from_dict(ref)
            session.add(token_ref)
            session.flush()
        return token_ref.to_dict()
Beispiel #44
0
    def delete_tokens(self,
                      user_id,
                      tenant_id=None,
                      trust_id=None,
                      consumer_id=None):
        """Deletes all tokens in one session

        The user_id will be ignored if the trust_id is specified. user_id
        will always be specified.
        If using a trust, the token's user_id is set to the trustee's user ID
        or the trustor's user ID, so will use trust_id to query the tokens.

        """
        session = self.get_session()
        with session.begin():
            now = timeutils.utcnow()
            query = session.query(TokenModel)
            query = query.filter_by(valid=True)
            query = query.filter(TokenModel.expires > now)
            if trust_id:
                query = query.filter(TokenModel.trust_id == trust_id)
            else:
                query = query.filter(TokenModel.user_id == user_id)

            for token_ref in query.all():
                if tenant_id:
                    token_ref_dict = token_ref.to_dict()
                    if not self._tenant_matches(tenant_id, token_ref_dict):
                        continue
                if consumer_id:
                    token_ref_dict = token_ref.to_dict()
                    if not self._consumer_matches(consumer_id, token_ref_dict):
                        continue

                token_ref.valid = False

            session.flush()
Beispiel #45
0
    def __call__(self, request):
        data = {
            'remote_addr': request.remote_addr,
            'remote_user': request.remote_user or '-',
            'method': request.method,
            'url': request.url,
            'http_version': request.http_version,
            'status': 500,
            'content_length': '-'}

        try:
            response = request.get_response(self.application)
            data['status'] = response.status_int
            data['content_length'] = len(response.body) or '-'
        finally:
            # must be calculated *after* the application has been called
            now = timeutils.utcnow()

            # timeutils may not return UTC, so we can't hardcode +0000
            data['datetime'] = '%s %s' % (now.strftime(APACHE_TIME_FORMAT),
                                          now.strftime('%z') or '+0000')

            LOG.info(APACHE_LOG_FORMAT, data)
        return response
Beispiel #46
0
    def _is_valid_token(self, token):
        """Verify the token is valid format and has not expired."""

        current_time = timeutils.normalize_time(timeutils.utcnow())

        try:
            # Get the data we need from the correct location (V2 and V3 tokens
            # differ in structure, Try V3 first, fall back to V2 second)
            token_data = token.get('token', token.get('access'))
            expires_at = token_data.get('expires_at',
                                        token_data.get('expires'))
            if not expires_at:
                expires_at = token_data['token']['expires']
            expiry = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
            if current_time < expiry:
                # Token is has not expired and has not been revoked.
                return None
        except Exception:
            LOG.exception(
                _('Unexpected error or malformed token determining '
                  'token expiry: %s'), token)

        raise exception.TokenNotFound(_("The token is malformed or expired."))
Beispiel #47
0
    def create_access_token(self, context):
        headers = context['headers']
        oauth_headers = oauth1.get_oauth_headers(headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        request_token_id = oauth_headers.get('oauth_token')
        oauth_verifier = oauth_headers.get('oauth_verifier')

        if not consumer_id:
            raise exception.ValidationError(attribute='oauth_consumer_key',
                                            target='request')
        if not request_token_id:
            raise exception.ValidationError(attribute='oauth_token',
                                            target='request')
        if not oauth_verifier:
            raise exception.ValidationError(attribute='oauth_verifier',
                                            target='request')

        consumer = self.oauth_api._get_consumer(consumer_id)
        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'))

        consumer_obj = oauth1.Consumer(key=consumer['id'],
                                       secret=consumer['secret'])
        req_token_obj = oauth1.Token(key=req_token['id'],
                                     secret=req_token['request_secret'])
        req_token_obj.set_verifier(oauth_verifier)

        url = oauth1.rebuild_url(context['path'])
        oauth_request = oauth1.Request.from_request(
            http_method='POST',
            http_url=url,
            headers=context['headers'],
            query_string=context['query_string'])
        oauth_server = oauth1.Server()
        oauth_server.add_signature_method(oauth1.SignatureMethod_HMAC_SHA1())
        params = oauth_server.verify_request(oauth_request,
                                             consumer_obj,
                                             token=req_token_obj)

        if len(params) != 0:
            msg = _('There should not be any non-oauth parameters')
            raise exception.Unauthorized(message=msg)

        if req_token['consumer_id'] != consumer_id:
            msg = _('provided consumer key does not match stored consumer key')
            raise exception.Unauthorized(message=msg)

        if req_token['verifier'] != oauth_verifier:
            msg = _('provided verifier does not match stored verifier')
            raise exception.Unauthorized(message=msg)

        if req_token['id'] != request_token_id:
            msg = _('provided request key does not match stored request key')
            raise exception.Unauthorized(message=msg)

        if not req_token.get('authorizing_user_id'):
            msg = _('Request Token does not have an authorizing user id')
            raise exception.Unauthorized(message=msg)

        access_token_duration = CONF.oauth1.access_token_duration
        token_ref = self.oauth_api.create_access_token(request_token_id,
                                                       access_token_duration)

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s' % {
            'key': token_ref['id'],
            'secret': token_ref['access_secret']
        })

        if CONF.oauth1.access_token_duration:
            expiry_bit = '&oauth_expires_at=%s' % (token_ref['expires_at'])
            result += expiry_bit

        headers = [('Content-Type', 'application/x-www-urlformencoded')]
        response = wsgi.render_response(result,
                                        status=(201, 'Created'),
                                        headers=headers)

        return response
Beispiel #48
0
 def _validate_expiration(self, token_ref):
     if timeutils.utcnow() > token_ref['expires']:
         raise exception.Unauthorized(_('Federation token is expired'))
Beispiel #49
0
def _future_time():
    expire_delta = datetime.timedelta(seconds=1000)
    future_time = timeutils.utcnow() + expire_delta
    return future_time
Beispiel #50
0
 def flush_expired_tokens(self):
     now = timeutils.utcnow()
     for token, token_ref in self.db.items():
         if self.is_expired(now, token_ref):
             self.db.delete(token)
Beispiel #51
0
def _sample_blank_token():
    issued_delta = datetime.timedelta(minutes=-2)
    issued_at = timeutils.utcnow() + issued_delta
    token_data = model.blank_token_data(issued_at)
    return token_data
Beispiel #52
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 = self.token_api.get_token(context['token_id'])
        user_id = user_token['user'].get('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
Beispiel #53
0
 def soft_delete(self, session=None):
     """Mark this object as deleted."""
     self.deleted = self.id
     self.deleted_at = timeutils.utcnow()
     self.save(session=session)
Beispiel #54
0
def _future_time_string():
    expire_delta = datetime.timedelta(seconds=1000)
    future_time = timeutils.utcnow() + expire_delta
    return timeutils.isotime(future_time)
Beispiel #55
0
 def _assert_valid(self, token_id, token_ref):
     """Raise TokenNotFound if the token is expired."""
     current_time = timeutils.normalize_time(timeutils.utcnow())
     expires = token_ref.get('expires')
     if not expires or current_time > timeutils.normalize_time(expires):
         raise exception.TokenNotFound(token_id=token_id)
Beispiel #56
0
 def _determine_expiration_time(self, expires_in):
     if expires_in is None:
         expires_in = CONF.saml.assertion_expiration_time
     now = timeutils.utcnow()
     future = now + datetime.timedelta(seconds=expires_in)
     return timeutils.isotime(future, subsecond=True)
Beispiel #57
0
def _past_time():
    expire_delta = datetime.timedelta(days=-1000)
    past_time = timeutils.utcnow() + expire_delta
    return past_time
import datetime

from keystone import config
from keystone import exception
from keystone.openstack.common import timeutils
from keystone import tests
from keystone.tests import default_fixtures
from keystone import token
from keystone.token.providers import pki


CONF = config.CONF

FUTURE_DELTA = datetime.timedelta(seconds=CONF.token.expiration)
CURRENT_DATE = timeutils.utcnow()

SAMPLE_V2_TOKEN = {
    "access": {
        "trust": {
            "id": "abc123",
            "trustee_user_id": "123456"
        },
        "serviceCatalog": [
            {
                "endpoints": [
                    {
                        "adminURL": "http://localhost:8774/v1.1/01257",
                        "id": "51934fe63a5b4ac0a32664f64eb462c3",
                        "internalURL": "http://localhost:8774/v1.1/01257",
                        "publicURL": "http://localhost:8774/v1.1/01257",
Beispiel #59
0
    def create_access_token(self, context):
        headers = context['headers']
        oauth_headers = oauth1.get_oauth_headers(headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        request_token_id = oauth_headers.get('oauth_token')
        oauth_verifier = oauth_headers.get('oauth_verifier')

        if not consumer_id:
            raise exception.ValidationError(
                attribute='oauth_consumer_key', target='request')
        if not request_token_id:
            raise exception.ValidationError(
                attribute='oauth_token', target='request')
        if not oauth_verifier:
            raise exception.ValidationError(
                attribute='oauth_verifier', target='request')

        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'))

        url = oauth1.rebuild_url(context['path'])

        access_verifier = oauth1.AccessTokenEndpoint(
            request_validator=validator.OAuthValidator(),
            token_generator=oauth1.token_generator)
        h, b, s = access_verifier.create_access_token_response(
            url,
            http_method='POST',
            body=context['query_string'],
            headers=headers)
        params = oauth1.extract_non_oauth_params(b)
        if len(params) != 0:
            msg = _('There should not be any non-oauth parameters')
            raise exception.Unauthorized(message=msg)

        if req_token['consumer_id'] != consumer_id:
            msg = _('provided consumer key does not match stored consumer key')
            raise exception.Unauthorized(message=msg)

        if req_token['verifier'] != oauth_verifier:
            msg = _('provided verifier does not match stored verifier')
            raise exception.Unauthorized(message=msg)

        if req_token['id'] != request_token_id:
            msg = _('provided request key does not match stored request key')
            raise exception.Unauthorized(message=msg)

        if not req_token.get('authorizing_user_id'):
            msg = _('Request Token does not have an authorizing user id')
            raise exception.Unauthorized(message=msg)

        access_token_duration = CONF.oauth1.access_token_duration
        token_ref = self.oauth_api.create_access_token(request_token_id,
                                                       access_token_duration)

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s'
                  % {'key': token_ref['id'],
                     'secret': token_ref['access_secret']})

        if CONF.oauth1.access_token_duration:
            expiry_bit = '&oauth_expires_at=%s' % (token_ref['expires_at'])
            result += expiry_bit

        headers = [('Content-Type', 'application/x-www-urlformencoded')]
        response = wsgi.render_response(result,
                                        status=(201, 'Created'),
                                        headers=headers)

        return response
Beispiel #60
0
 def soft_delete(self, synchronize_session='evaluate'):
     return self.update({'deleted': literal_column('id'),
                         'updated_at': literal_column('updated_at'),
                         'deleted_at': timeutils.utcnow()},
                        synchronize_session=synchronize_session)