def create_token(self, client_id, data, grant_type, scopes, user_id): if self.unique_token: if user_id is None: raise UserIdentifierMissingError try: access_token = self.access_token_store.\ fetch_existing_token_of_user( client_id, grant_type, user_id) if (access_token.scopes == scopes and access_token.is_expired() is False): token_data = { "access_token": access_token.token, "token_type": "Bearer" } if access_token.refresh_token is not None: token_data[ "refresh_token"] = access_token.refresh_token token_data["expires_in"] = access_token.expires_in return token_data except AccessTokenNotFound: pass token_data = self.token_generator.create_access_token_data(grant_type) access_token = AccessToken(client_id=client_id, data=data, grant_type=grant_type, token=token_data["access_token"], scopes=scopes, user_id=user_id) if "refresh_token" in token_data: expires_at = int(time.time()) + token_data["expires_in"] access_token.expires_at = expires_at access_token.refresh_token = token_data["refresh_token"] refresh_expires_in = self.token_generator.refresh_expires_in refresh_expires_at = int(time.time()) + refresh_expires_in access_token.refresh_expires_at = refresh_expires_at self.access_token_store.save_token(access_token) return token_data
def process(self, request, response, environ): body = {"token_type": "Bearer"} token = self.token_generator.generate() expires_in = self.token_generator.expires_in[ ClientCredentialsGrant.grant_type] expires_at = int(time.time()) + expires_in access_token = AccessToken( client_id=self.client.identifier, grant_type=ClientCredentialsGrant.grant_type, token=token, expires_at=expires_at, scopes=self.scope_handler.scopes) self.access_token_store.save_token(access_token) body["access_token"] = token if expires_in > 0: body["expires_in"] = expires_in if self.scope_handler.send_back: body["scope"] = encode_scopes(self.scope_handler.scopes) json_success_response(data=body, response=response) return response
def fetch_by_refresh_token(self, refresh_token): token_data = self.read(refresh_token) if token_data is None: raise AccessTokenNotFound return AccessToken(**token_data)
def test_save_token(self): data = { "client_id": "myclient", "token": "xyz", "data": { "name": "test" }, "scopes": ["foo_read", "foo_write"], "expires_at": None, "refresh_token": "mno", "refresh_expires_at": None, "grant_type": "authorization_code", "user_id": 123 } access_token = AccessToken(**data) cache_key = self._generate_test_cache_key(access_token.token) refresh_token_key = self._generate_test_cache_key( access_token.refresh_token) unique_token_key = self._generate_test_cache_key("{0}_{1}_{2}".format( access_token.client_id, access_token.grant_type, access_token.user_id)) mc_mock = Mock(spec=["set"]) store = TokenStore(mc=mc_mock, prefix=self.cache_prefix) store.save_token(access_token) mc_mock.set.assert_has_calls([ call(cache_key, data), call(unique_token_key, data), call(refresh_token_key, data) ])
def create_auth_server(): client_store = ClientStore() client_store.add_client( client_id="alexa.matsuoka", client_secret="xxxx", redirect_uris=[ "https://layla.amazon.com/api/skill/link/M2Q7FOC6AVxxxx", "https://pitangui.amazon.com/api/skill/link/M2Q7FOC6AVxxxx", "https://alexa.amazon.co.jp/api/skill/link/M2Q7FOC6AVxxxx" ]) token_store = TokenStore() token_store.save_token( AccessToken(client_id="alexa.matsuoka", grant_type="authorization_code", user_id="*****@*****.**", token="xxxx")) provider = Provider(access_token_store=token_store, auth_code_store=token_store, client_store=client_store, token_generator=Uuid4(), client_authentication_source=http_basic_auth) provider.add_grant( AuthorizationCodeGrant(site_adapter=TestSiteAdapter(), unique_token=True)) app = Application([ url(provider.authorize_path, OAuth2Handler, dict(provider=provider)), url(provider.token_path, OAuth2Handler, dict(provider=provider)), ], debug=False) return app
def test_expires_in_not_expired(self): access_token = AccessToken(client_id="abc", grant_type="client_credentials", token="def", expires_at=1100) self.assertEqual(access_token.expires_in, 100)
def save_token( client_id, grant_type, user_id, scopes=[], expires_at=int(time.time()) + token_generator.expires_in[oauth2.grant.ClientCredentialsGrant.grant_type] ): coll = token_store.collection access_token_store = token_store token_str = token_generator.generate() token = AccessToken(client_id=client_id, grant_type=grant_type, token=token_str, data={}, expires_at=expires_at, refresh_token=None, refresh_expires_at=None, scopes=scopes, user_id=user_id) coll.remove({"client_id": client_id}) if access_token_store.save_token(token): return token_str else: raise ValueError(u"生成token失败")
def fetch_by_refresh_token(self, refresh_token): token_data = self.fetch_data_for_key(refresh_token, key_type='refresh') user_id = token_data.get('user_id') user_data = self.fetch_data_for_key(user_id) if refresh_token == user_data.get('refresh_token'): return AccessToken(**token_data) raise AccessTokenNotFound()
def fetch_existing_token_of_user(self, client_id, grant_type, user_id): data = self.mc.get( self._unique_token_key(client_id, grant_type, user_id)) if data is None: raise AccessTokenNotFound return AccessToken(**data)
def test_save_token(self): access_token = AccessToken(**self.access_token_data) collection_mock = Mock(spec=["insert"]) store = AccessTokenStore(collection=collection_mock) store.save_token(access_token) collection_mock.insert.assert_called_with(self.access_token_data)
def test_save_token_and_fetch_by_token(self): access_token = AccessToken(**self.access_token_data) success = self.test_store.save_token(access_token) self.assertTrue(success) result = self.test_store.fetch_by_token(access_token.token) self.assertEqual(result, access_token)
def fetch_data_for_access_token(cls, access_token, return_type='dict', user_data_dict=None): token_data_dict = cls.fetch_data_for_key(access_token, key_type='access') user_id = token_data_dict.get('user_id') user_data = user_data_dict or cls.fetch_data_for_key(user_id) if user_data.get('token') == access_token: return cls.format_data_for_response(token_data_dict) \ if return_type == 'dict' \ else AccessToken(**token_data_dict) raise AccessTokenNotFound()
def create_token(self, client_id, data, grant_type, scopes, user_id): if self.unique_token: if user_id is None: raise UserIdentifierMissingError try: access_token = self.access_token_store.\ fetch_existing_token_of_user( client_id, grant_type, user_id) if (access_token.scopes == scopes and access_token.is_expired() is False): token_data = {"access_token": access_token.token, "token_type": "Bearer"} if access_token.refresh_token is not None: token_data["refresh_token"] = access_token.refresh_token token_data["expires_in"] = access_token.expires_in return token_data except AccessTokenNotFound: pass token_data = self.token_generator.create_access_token_data(grant_type) access_token = AccessToken(client_id=client_id, data=data, grant_type=grant_type, token=token_data["access_token"], scopes=scopes, user_id=user_id) if "refresh_token" in token_data: expires_at = int(time.time()) + token_data["expires_in"] access_token.expires_at = expires_at access_token.refresh_token = token_data["refresh_token"] refresh_expires_in = self.token_generator.refresh_expires_in refresh_expires_at = int(time.time()) + refresh_expires_in access_token.refresh_expires_at = refresh_expires_at self.access_token_store.save_token(access_token) return token_data
def fetch_existing_token_of_user(self, client_id, grant_type, user_id): unique_token_key = self._unique_token_key(client_id=client_id, grant_type=grant_type, user_id=user_id) token_data = self.read(unique_token_key) if token_data is None: raise AccessTokenNotFound return AccessToken(**token_data)
def _access_token_from_orm(self, orm_token): """Transform an ORM AccessToken record into an oauth2 AccessToken instance""" return AccessToken( client_id=orm_token.client_id, grant_type=orm_token.grant_type, expires_at=orm_token.expires_at, refresh_token=orm_token.refresh_token, refresh_expires_at=orm_token.refresh_expires_at, user_id=orm_token.user_id, )
def process(self, request, response, environ): """ Create a new access token. :param request: The incoming :class:`oauth2.web.Request`. :param response: The :class:`oauth2.web.Response` that will be returned to the client. :param environ: A ``dict`` containing data of the environment. :return: :class:`oauth2.web.Response` """ token_data = self.token_generator.create_access_token_data( self.refresh_grant_type) expires_at = int(time.time()) + token_data["expires_in"] access_token = AccessToken(client_id=self.client.identifier, token=token_data["access_token"], grant_type=self.refresh_grant_type, data=self.data, expires_at=expires_at, scopes=self.scope_handler.scopes, user_id=self.user_id) #refresh token scope setting if access_token.scopes: token_data["scope"] = encode_scopes(access_token.scopes) if self.reissue_refresh_tokens: self.access_token_store.delete_refresh_token(self.refresh_token) access_token.refresh_token = token_data["refresh_token"] refresh_expires_in = self.token_generator.refresh_expires_in refresh_expires_at = int(time.time()) + refresh_expires_in access_token.refresh_expires_at = refresh_expires_at else: del token_data["refresh_token"] self.access_token_store.save_token(access_token) json_success_response(data=token_data, response=response) return response
def test_save_token(self, store_class): first_cursor = Mock(spec=["close", "execute"]) first_cursor.lastrowid = 1 second_cursor = Mock() third_cursor = Mock() fourth_cursor = Mock() connection_mock = Mock(spec=["commit", "cursor"]) connection_mock.cursor.side_effect = [ first_cursor, second_cursor, third_cursor, fourth_cursor ] access_token = AccessToken(client_id="abc", grant_type="test", token="abc123", data={"test": "data"}, expires_at=1000, refresh_token="xyz789", refresh_expires_at=2000, scopes=["foo", "bar"], user_id=1) store = store_class(connection=connection_mock) result = store.save_token(access_token) self.assertTrue(result) self.assertEqual(connection_mock.commit.call_count, 4) first_cursor.execute.\ assert_called_with(store_class.create_access_token_query, (access_token.client_id, access_token.grant_type, access_token.token, access_token.expires_at, access_token.refresh_token, access_token.refresh_expires_at, access_token.user_id)) first_cursor.close.assert_called_with() second_cursor.execute.\ assert_called_with(store_class.create_data_query, ("test", "data", 1)) second_cursor.close.assert_called_with() third_cursor.execute.\ assert_called_with(store_class.create_scope_query, ("foo", 1)) third_cursor.close.assert_called_with() fourth_cursor.execute.\ assert_called_with(store_class.create_scope_query, ("bar", 1)) fourth_cursor.close.assert_called_with()
def fetch_by_refresh_token(self, refresh_token): data = self.collection.find_one({"refresh_token": refresh_token}) if data is None: raise AccessTokenNotFound return AccessToken(client_id=data.get("client_id"), grant_type=data.get("grant_type"), token=data.get("token"), data=data.get("data"), expires_at=data.get("expires_at"), refresh_token=data.get("refresh_token"), refresh_expires_at=data.get("refresh_expires_at"), scopes=data.get("scopes"))
def test_delete_refresh_token(self): refresh_token_id = "def" access_token = AccessToken(client_id="abc", grant_type="token", token="xyz") redisdb_mock = Mock(spec=["delete", "get"]) redisdb_mock.get.return_value = bytes( json.dumps(access_token.__dict__).encode('utf-8')) store = TokenStore(rs=redisdb_mock) store.delete_refresh_token(refresh_token_id) self.assertEqual(1, redisdb_mock.delete.call_count)
def process(self, request, response, environ): """ Create a new access token. :param request: The incoming :class:`oauth2.web.Request`. :param response: The :class:`oauth2.web.Response` that will be returned to the client. :param environ: A ``dict`` containing data of the environment. :return: :class:`oauth2.web.Response` """ token_data = self.token_generator.create_access_token_data(self.refresh_grant_type) expires_at = int(time.time()) + token_data["expires_in"] access_token = AccessToken(client_id=self.client_id, token=token_data["access_token"], grant_type=self.refresh_grant_type, data=self.data, expires_at=expires_at, scopes=self.scope_handler.scopes, user_id=self.user_id) if self.reissue_refresh_tokens: self.access_token_store.delete_refresh_token(self.refresh_token) access_token.refresh_token = token_data["refresh_token"] refresh_expires_in = self.token_generator.refresh_expires_in refresh_expires_at = int(time.time()) + refresh_expires_in access_token.refresh_expires_at = refresh_expires_at else: del token_data["refresh_token"] self.access_token_store.save_token(access_token) json_success_response(data=token_data, response=response) return response
def process(self, request, response, environ): data = self.authorize(request, response, environ, self.scope_handler.scopes) if isinstance(data, Response): return data token = self.token_generator.generate() access_token = AccessToken(client_id=self.client.identifier, grant_type=ImplicitGrant.grant_type, token=token, data=data[0], scopes=self.scope_handler.scopes) self.access_token_store.save_token(access_token) return self._redirect_access_token(response, token)
def process(self, request, response, environ): """ Process a request for an access token. :param request: The request that was received. :type request: :class:`oauth2.web.wsgi.Request` :param response: The response that is being constructed. :type response: :class:`oauth2.web.Response` :param environ: The request parameters. :type environ: dict :return: The processed response. :rtype: :class:`oauth2.web.Response` """ body = {"token_type": "Bearer"} token = self.token_generator.generate() expires_in = self.token_generator.expires_in.get( ClientCredentialsGrant.grant_type, None) if expires_in is None: expires_at = None else: expires_at = int(time.time()) + expires_in access_token = AccessToken( client_id=self.client.identifier, grant_type=ClientCredentialsGrant.grant_type, token=token, expires_at=expires_at, scopes=self.scope_handler.scopes, user_id=self.user_id) self.access_token_store.save_token(access_token) body["access_token"] = token if expires_in is not None: body["expires_in"] = expires_in if self.scope_handler.send_back: body["scope"] = encode_scopes(self.scope_handler.scopes) json_success_response(data=body, response=response) return response
def fetch_existing_token_of_user(self, client_id, grant_type, user_id): data = self.collection.find_one( { "client_id": client_id, "grant_type": grant_type, "user_id": user_id }, sort=[("expires_at", pymongo.DESCENDING)]) if data is None: raise AccessTokenNotFound return AccessToken(client_id=data.get("client_id"), grant_type=data.get("grant_type"), token=data.get("token"), data=data.get("data"), expires_at=data.get("expires_at"), refresh_token=data.get("refresh_token"), refresh_expires_at=data.get("refresh_expires_at"), scopes=data.get("scopes"), user_id=data.get("user_id"))
def test_is_expired_expired_at_not_set(self): access_token = AccessToken(client_id="abc", grant_type="client_credentials", token="def") self.assertFalse(access_token.is_expired())
def _row_to_token(self, data, scopes, row): return AccessToken(client_id=row[1], grant_type=row[2], token=row[3], data=data, expires_at=row[4], refresh_token=row[5], refresh_expires_at=row[6], scopes=scopes, user_id=row[7])