def bootstrap_user_new(self, client_name=None, scopes=None, ratelimit=1.0): """ Create a OAuthClient owned by the authenticated real user. Similar logic performed for the OAuthToken. :return: OAuthToken instance """ assert current_user.email != current_app.config['BOOTSTRAP_USER_EMAIL'] self._check_ratelimit(ratelimit) uid = current_user.get_id() client_name = client_name or current_app.config.get( 'BOOTSTRAP_CLIENT_NAME', 'BB client') client = OAuthClient( user_id=current_user.get_id(), name=client_name, description=client_name, is_confidential=True, is_internal=True, _default_scopes=scopes or ' '.join(current_app.config['USER_DEFAULT_SCOPES']), ratelimit=ratelimit) client.gen_salt() db.session.add(client) token = Bootstrap.create_user_token(client) db.session.add(token) current_app.logger.info("Created OAuth client for {email}".format( email=current_user.email)) db.session.commit() return client, token
def bootstrap_bumblebee(): """ Return or create a OAuthClient owned by the "bumblebee" user. Re-uses an existing client if "oauth_client" is encoded into the session cookie, otherwise writes a new client to the database. Similar logic performed for the OAuthToken. :return: OAuthToken instance """ assert current_user.email == current_app.config['BOOTSTRAP_USER_EMAIL'] client_name = current_app.config.get('BOOTSTRAP_CLIENT_NAME', 'BB client') scopes = ' '.join(current_app.config.get('BOOTSTRAP_SCOPES', [])) client = OAuthClient(user_id=current_user.get_id(), name=client_name, description=client_name, is_confidential=False, is_internal=True, _default_scopes=scopes, ratelimit=1.0) client.gen_salt() db.session.add(client) token = Bootstrap.create_temporary_token(client) db.session.add(token) db.session.commit() return client, token
def bootstrap_user(self, client_name=None, scopes=None, ratelimit=1.0, expires=datetime.datetime(2500, 1, 1)): """ Return or create a OAuthClient owned by the authenticated real user. Re-uses an existing client if "oauth_client" is found in the database for this user, otherwise writes a new client to the database. Similar logic performed for the OAuthToken. :return: OAuthToken instance """ assert current_user.email != current_app.config['BOOTSTRAP_USER_EMAIL'] uid = current_user.get_id() client_name = client_name or current_app.config.get( 'BOOTSTRAP_CLIENT_NAME', 'BB client') client = OAuthClient.query.filter_by( user_id=uid, name=client_name, ).order_by(OAuthClient.created.desc()).first() if client is None: self._check_ratelimit(ratelimit) client = OAuthClient( user_id=current_user.get_id(), name=client_name, description=client_name, is_confidential=True, is_internal=True, _default_scopes=scopes or ' '.join(current_app.config['USER_DEFAULT_SCOPES']), ratelimit=ratelimit) client.gen_salt() db.session.add(client) token = Bootstrap.create_user_token(client, expires=expires) db.session.add(token) current_app.logger.info("Created BB client for {email}".format( email=current_user.email)) else: token = OAuthToken.query.filter_by( client_id=client.client_id, user_id=current_user.get_id(), ).first() if token is None: # the token was not created yet token = Bootstrap.create_user_token(client, expires=expires) db.session.add(token) current_app.logger.info("Created BB client for {email}".format( email=current_user.email)) db.session.commit() return client, token
def bootstrap_user(): """ Return or create a OAuthClient owned by the authenticated real user. Re-uses an existing client if "oauth_client" is found in the database for this user, otherwise writes a new client to the database. Similar logic performed for the OAuthToken. :return: OAuthToken instance """ assert current_user.email != current_app.config['BOOTSTRAP_USER_EMAIL'] uid = current_user.get_id() client_name = current_app.config.get('BOOTSTRAP_CLIENT_NAME', 'BB client') client = OAuthClient.query.filter_by( user_id=uid, name=client_name, ).first() if client is None: scopes = ' '.join(current_app.config['USER_DEFAULT_SCOPES']) salt_length = current_app.config.get('OAUTH2_CLIENT_ID_SALT_LEN', 40) client = OAuthClient( user_id=current_user.get_id(), name=client_name, description=client_name, is_confidential=True, is_internal=True, _default_scopes=scopes, ) client.gen_salt() db.session.add(client) token = OAuthToken( client_id=client.client_id, user_id=uid, access_token=gen_salt(salt_length), refresh_token=gen_salt(salt_length), expires=datetime.datetime(2500, 1, 1), _scopes=scopes, is_personal=False, is_internal=True, ) db.session.add(token) db.session.commit() current_app.logger.info( "Created BB client for {email}".format(email=current_user.email) ) else: token = OAuthToken.query.filter_by( client_id=client.client_id, user_id=current_user.get_id(), ).first() return client, token
def bootstrap_bumblebee(): """ Return or create a OAuthClient owned by the "bumblebee" user. Re-uses an existing client if "oauth_client" is encoded into the session cookie, otherwise writes a new client to the database. Similar logic performed for the OAuthToken. :return: OAuthToken instance """ assert current_user.email == current_app.config['BOOTSTRAP_USER_EMAIL'] salt_length = current_app.config.get('OAUTH2_CLIENT_ID_SALT_LEN', 40) scopes = ' '.join(current_app.config.get('BOOTSTRAP_SCOPES', [])) expires = current_app.config.get('BOOTSTRAP_TOKEN_EXPIRES', 3600 * 24) client_name = current_app.config.get('BOOTSTRAP_CLIENT_NAME', 'BB client') uid = current_user.get_id() client = OAuthClient( user_id=uid, name=client_name, description=client_name, is_confidential=False, is_internal=True, _default_scopes=scopes, ) client.gen_salt() db.session.add(client) if isinstance(expires, int): expires = datetime.datetime.utcnow() + datetime.timedelta( seconds=expires) token = OAuthToken( client_id=client.client_id, user_id=uid, expires=expires, _scopes=scopes, access_token=gen_salt(salt_length), refresh_token=gen_salt(salt_length), is_personal=False, is_internal=True, ) db.session.add(token) db.session.commit() return client, token
def put(self): """ Generates a new API key :return: dict containing the API key data structure """ client = OAuthClient.query.filter_by( user_id=current_user.get_id(), name=u'ADS API client', ).first() if client is None: # If no client exists, create a new one client = OAuthClient( user_id=current_user.get_id(), name=u'ADS API client', description=u'ADS API client', is_confidential=False, is_internal=True, _default_scopes=' '.join( current_app.config['USER_API_DEFAULT_SCOPES'] ), ratelimit=1.0 ) client.gen_salt() token = OAuthToken( client_id=client.client_id, user_id=current_user.get_id(), access_token=gen_salt(40), refresh_token=gen_salt(40), expires=datetime.datetime(2500, 1, 1), _scopes=' '.join( current_app.config['USER_API_DEFAULT_SCOPES'] ), is_personal=False, ) db.session.add(client) db.session.add(token) try: db.session.commit() except Exception, e: current_app.logger.error("Unknown DB error: {0}".format(e)) abort(503) current_app.logger.info( "Created ADS API client+token for {0}".format( current_user.email ) )
def bootstrap_bumblebee(): """ Return or create a OAuthClient owned by the "bumblebee" user. Re-uses an existing client if "oauth_client" is encoded into the session cookie, otherwise writes a new client to the database. Similar logic performed for the OAuthToken. :return: OAuthToken instance """ assert current_user.email == current_app.config['BOOTSTRAP_USER_EMAIL'] salt_length = current_app.config.get('OAUTH2_CLIENT_ID_SALT_LEN', 40) scopes = ' '.join(current_app.config.get('BOOTSTRAP_SCOPES', [])) expires = current_app.config.get('BOOTSTRAP_TOKEN_EXPIRES', 3600*24) client_name = current_app.config.get('BOOTSTRAP_CLIENT_NAME', 'BB client') uid = current_user.get_id() client = OAuthClient( user_id=uid, name=client_name, description=client_name, is_confidential=False, is_internal=True, _default_scopes=scopes, ) client.gen_salt() db.session.add(client) if isinstance(expires, int): expires = datetime.datetime.utcnow() + datetime.timedelta( seconds=expires) token = OAuthToken( client_id=client.client_id, user_id=uid, expires=expires, _scopes=scopes, access_token=gen_salt(salt_length), refresh_token=gen_salt(salt_length), is_personal=False, is_internal=True, ) db.session.add(token) db.session.commit() return client, token
def put(self): """ Generates a new API key :return: dict containing the API key data structure """ client = OAuthClient.query.filter_by( user_id=current_user.get_id(), name=u'ADS API client', ).first() if client is None: # If no client exists, create a new one client = OAuthClient( user_id=current_user.get_id(), name=u'ADS API client', description=u'ADS API client', is_confidential=False, is_internal=True, _default_scopes=' '.join( current_app.config['USER_API_DEFAULT_SCOPES'] ), ) client.gen_salt() token = OAuthToken( client_id=client.client_id, user_id=current_user.get_id(), access_token=gen_salt(40), refresh_token=gen_salt(40), expires=datetime.datetime(2500, 1, 1), _scopes=' '.join( current_app.config['USER_API_DEFAULT_SCOPES'] ), is_personal=False, ) db.session.add(client) db.session.add(token) try: db.session.commit() except Exception, e: current_app.logger.error("Unknown DB error: {0}".format(e)) abort(503) current_app.logger.info( "Created ADS API client+token for {0}".format( current_user.email ) )
def _create_client(self, client_id='test', user_id=0, scopes='adsws:internal'): # create a client in the database c1 = OAuthClient( client_id=client_id, client_secret='client secret %s' % random.random(), name='bumblebee', description='', is_confidential=False, user_id=user_id, _redirect_uris='%s/client/authorized' % self.app.config.get('SITE_SECURE_URL'), _default_scopes=scopes ) db.session.add(c1) db.session.commit() return OAuthClient.query.filter_by(client_secret=c1.client_secret).one()
def setUp(self): @self.app.route('/postlogin') def username(): if current_user.is_authenticated(): return current_user.email return u'Anonymous' @self.app.errorhandler(404) def handle_404(e): raise e db.create_all(app=self.app) FlaskAppTestCase.setUp(self) user = user_manipulator.create(email='montysolr', password='******', active=True) self.user = user from adsws.modules.oauth2server.models import OAuthClient, Scope, OAuthToken from adsws.modules.oauth2server.registry import scopes as scopes_registry # Register a test scope scopes_registry.register(Scope('adsws:internal')) self.base_url = self.app.config.get('SITE_SECURE_URL') # create a client in the database c1 = OAuthClient( client_id='bumblebee', client_secret='client secret', name='bumblebee', description='', is_confidential=False, user_id=user.id, _redirect_uris='%s/client/authorized' % self.base_url, _default_scopes="adsws:internal", ratelimit=1.0 ) db.session.add(c1) db.session.commit() self.oauth = OAuth(self.app) # have the remote app ready self.authenticate()
def bootstrap_user(): """ Return or create a OAuthClient owned by the authenticated real user. Re-uses an existing client if "oauth_client" is found in the database for this user, otherwise writes a new client to the database. Similar logic performed for the OAuthToken. :return: OAuthToken instance """ assert current_user.email != current_app.config['BOOTSTRAP_USER_EMAIL'] uid = current_user.get_id() client_name = current_app.config.get('BOOTSTRAP_CLIENT_NAME', 'BB client') client = OAuthClient.query.filter_by( user_id=uid, name=client_name, ).first() scopes = ' '.join(current_app.config['USER_DEFAULT_SCOPES']) salt_length = current_app.config.get('OAUTH2_CLIENT_ID_SALT_LEN', 40) if client is None: client = OAuthClient( user_id=current_user.get_id(), name=client_name, description=client_name, is_confidential=True, is_internal=True, _default_scopes=scopes, ) client.gen_salt() db.session.add(client) token = OAuthToken( client_id=client.client_id, user_id=uid, access_token=gen_salt(salt_length), refresh_token=gen_salt(salt_length), expires=datetime.datetime(2500, 1, 1), _scopes=scopes, is_personal=False, is_internal=True, ) db.session.add(token) current_app.logger.info("Created BB client for {email}".format( email=current_user.email)) else: token = OAuthToken.query.filter_by( client_id=client.client_id, user_id=current_user.get_id(), ).first() if token is None: # the token was not created yet token = OAuthToken( client_id=client.client_id, user_id=uid, access_token=gen_salt(salt_length), refresh_token=gen_salt(salt_length), expires=datetime.datetime(2500, 1, 1), _scopes=scopes, is_personal=False, is_internal=True, ) db.session.add(token) current_app.logger.info("Created BB client for {email}".format( email=current_user.email)) db.session.commit() return client, token
def get_token(): parser = argparse.ArgumentParser() add_arguments(parser) args = parser.parse_args() app = create_app('manual_client_registration', EXTENSIONS = ['adsws.ext.sqlalchemy', 'adsws.ext.security',], PACKAGES=['adsws.modules.oauth2server',]) with app.app_context() as context: try: u = db.session.query(User).filter_by(email=args.user_email).one() except NoResultFound: if not args.create_user: sys.exit("User with email [%s] not found, and --create-user was not specified. Exiting." % args.user_email) u = User(email=args.user_email) db.session.add(u) db.session.commit() except MultipleResultsFound: raise DatabaseIntegrityError try: client = db.session.query(OAuthClient).filter_by(user_id=u.id,name=args.name).one() except MultipleResultsFound: raise DatabaseIntegrityError("Multiple oauthclients found for that user and name") except NoResultFound: client = OAuthClient( user_id = u.id, description=args.description, name=args.name, is_confidential=True, is_internal=True,) client.gen_salt() db.session.add(client) db.session.commit() try: tokens = db.session.query(OAuthToken).filter_by( client_id=client.client_id, user_id=u.id, is_personal=args.is_personal).all() #Iterate through each result and compare scopes matching_tokens = [] for t in tokens: if set(args.scopes) == set(t.scopes): matching_tokens.append(t) if not matching_tokens: raise NoResultFound print "%s tokens with those definitions found, returning the first" % len(matching_tokens) token = matching_tokens[0] except NoResultFound: token = OAuthToken( client_id=client.client_id, user_id=u.id, access_token=gen_salt(current_app.config.get('OAUTH2_TOKEN_PERSONAL_SALT_LEN', 40)), refresh_token=gen_salt(current_app.config.get('OAUTH2_TOKEN_PERSONAL_SALT_LEN', 40)), _scopes=' '.join(args.scopes), expires=datetime.datetime(2050,1,1) if args.is_personal else None, is_personal=args.is_personal, is_internal=True,) db.session.add(token) db.session.commit() return { 'access_token': token.access_token, 'refresh_token': token.refresh_token, 'username': u.email, 'expires_in': token.expires.isoformat() if token.expires else None, 'token_type': 'Bearer'}
def test_cleanup_client(self): """ Tests that oauth2clients whose last_activity attribute are properly removed from the database as a result of the cleanup_client procedure """ original_clients = db.session.query(OAuthClient).all() self.assertEqual(5, len(original_clients)) self.assertItemsEqual( filter(None, [i.last_activity for i in original_clients]), self.times, ) # No clients should be cleaned cleanup_clients(app_override=self.app, timedelta="days=365") current_clients = db.session.query(OAuthClient).all() self.assertEqual(5, len(current_clients)) # Cleanup all clients that are older than 0 seconds from now() cleanup_clients(app_override=self.app, timedelta="seconds=0") current_clients = db.session.query(OAuthClient).all() self.assertEqual(3, len(current_clients)) # Wait 3 seconds, then perform the same cleanup. Should have one less # client after this operation. time.sleep(3.1) cleanup_clients(app_override=self.app, timedelta="seconds=0.1") current_clients = db.session.query(OAuthClient).all() self.assertEqual(2, len(current_clients)) # Cleanup the client whose last_activity was set to 1 hour # into the future. This case should never happen in practice! cleanup_clients(app_override=self.app, timedelta="hours=-1") current_clients = db.session.query(OAuthClient).all() self.assertEqual(1, len(current_clients)) # Only the client with last_activity=None should remain current_clients = db.session.query(OAuthClient).all() self.assertEqual(1, len(current_clients)) self.assertIsNone(current_clients[0].last_activity) # test they can be cleaned up by userid db.session.add(OAuthClient( user_id=99, client_id=gen_salt(20), client_secret=gen_salt(20), is_confidential=False, is_internal=True, _default_scopes="", last_activity=datetime.datetime.now() )) db.session.add(OAuthClient( user_id=1, client_id=gen_salt(20), client_secret=gen_salt(20), is_confidential=False, is_internal=True, _default_scopes="", last_activity=datetime.datetime.now() )) db.session.commit() self.assertEqual(3, len(db.session.query(OAuthClient).all())) time.sleep(1.1) cleanup_clients(app_override=self.app, timedelta="seconds=0.1", userid=99) self.assertEqual(2, len(db.session.query(OAuthClient).all())) db.session.add(OAuthClient( user_id=99, client_id=gen_salt(20), client_secret=gen_salt(20), is_confidential=False, is_internal=True, _default_scopes="", last_activity=datetime.datetime.now(), ratelimit=0.2 )) db.session.commit() time.sleep(0.5) cleanup_clients(app_override=self.app, timedelta="seconds=0.1", userid=99, ratelimit='0.19') self.assertEqual(3, len(db.session.query(OAuthClient).all())) cleanup_clients(app_override=self.app, timedelta="seconds=0.1", userid=99, ratelimit='0.2') self.assertEqual(2, len(db.session.query(OAuthClient).all()))
def setUp(self): """ Sets up all of the users, clients, and tokens that management commands will run against. """ db.create_all(app=self.app) now = datetime.datetime.now() delta = datetime.timedelta times = [ now, now-delta(seconds=3), now+delta(seconds=3), now+delta(hours=1), ] self.times = times # Save for comparisons in the tests # This is a user that has registered but not confirmed their account u = user_manipulator.create( email="unconfirmed@unittest", registered_at=now+delta(seconds=1), ) db.session.add(u) # This is a user that has registered but not confirmed their account, # and furthermore will not have a registered_at attribute set u = user_manipulator.create( email="blankuser@unittest", ) db.session.add(u) # This is a user that has registered and confirmed their account u = user_manipulator.create( email="user@unittest", registered_at=now, confirmed_at=now, ) db.session.add(u) for _time in times: client = OAuthClient( user_id=u.id, client_id=gen_salt(20), client_secret=gen_salt(20), is_confidential=False, is_internal=True, _default_scopes="", last_activity=_time, ) db.session.add(client) token = OAuthToken( client_id=client.client_id, user_id=u.id, access_token=gen_salt(20), refresh_token=gen_salt(20), expires=_time, _scopes="", is_personal=False, is_internal=True, ) db.session.add(token) # Add a client without a last_activity to verify that the cleanup # scripts do not break under this condition client = OAuthClient( user_id=u.id, client_id=gen_salt(20), client_secret=gen_salt(20), is_confidential=False, is_internal=True, _default_scopes="", ) db.session.add(client) # Add a token without an expiry to verify that the cleanup scripts # do not break under this condition token = OAuthToken( client_id=client.client_id, user_id=u.id, access_token=gen_salt(20), refresh_token=gen_salt(20), _scopes="", is_personal=False, is_internal=True, ) db.session.add(token) db.session.commit()
def get_token(): parser = argparse.ArgumentParser() add_arguments(parser) args = parser.parse_args() app = create_app('manual_client_registration', EXTENSIONS=[ 'adsws.ext.sqlalchemy', 'adsws.ext.security', ], PACKAGES=[ 'adsws.modules.oauth2server', ]) with app.app_context() as context: try: u = db.session.query(User).filter_by(email=args.user_email).one() except NoResultFound: if not args.create_user: sys.exit( "User with email [%s] not found, and --create-user was not specified. Exiting." % args.user_email) u = User(email=args.user_email) db.session.add(u) db.session.commit() except MultipleResultsFound: raise DatabaseIntegrityError try: client = db.session.query(OAuthClient).filter_by( user_id=u.id, name=args.name).one() except MultipleResultsFound: raise DatabaseIntegrityError( "Multiple oauthclients found for that user and name") except NoResultFound: client = OAuthClient( user_id=u.id, description=args.description, name=args.name, is_confidential=True, is_internal=True, ) client.gen_salt() db.session.add(client) db.session.commit() try: tokens = db.session.query(OAuthToken).filter_by( client_id=client.client_id, user_id=u.id, is_personal=args.is_personal).all() #Iterate through each result and compare scopes matching_tokens = [] for t in tokens: if set(args.scopes) == set(t.scopes): matching_tokens.append(t) if not matching_tokens: raise NoResultFound print "%s tokens with those definitions found, returning the first" % len( matching_tokens) token = matching_tokens[0] except NoResultFound: token = OAuthToken( client_id=client.client_id, user_id=u.id, access_token=gen_salt( current_app.config.get('OAUTH2_TOKEN_PERSONAL_SALT_LEN', 40)), refresh_token=gen_salt( current_app.config.get('OAUTH2_TOKEN_PERSONAL_SALT_LEN', 40)), _scopes=' '.join(args.scopes), expires=datetime.datetime(2050, 1, 1) if args.is_personal else None, is_personal=args.is_personal, is_internal=True, ) db.session.add(token) db.session.commit() return { 'access_token': token.access_token, 'refresh_token': token.refresh_token, 'username': u.email, 'expires_in': token.expires.isoformat() if token.expires else None, 'token_type': 'Bearer' }