def test_get_matching_users(initialized_db): # Exact match. for user in User.select().where(User.organization == False, User.robot == False): assert list(get_matching_users(user.username))[0].username == user.username # Prefix matching. for user in User.select().where(User.organization == False, User.robot == False): assert user.username in [r.username for r in get_matching_users(user.username[:2])]
def _notify_superusers(key): notification_metadata = { "name": key.name, "kid": key.kid, "service": key.service, "jwk": key.jwk, "metadata": key.metadata, "created_date": timegm(key.created_date.utctimetuple()), } if key.expiration_date is not None: notification_metadata["expiration_date"] = timegm( key.expiration_date.utctimetuple()) if len(config.app_config["SUPER_USERS"]) > 0: superusers = User.select().where( User.username << config.app_config["SUPER_USERS"]) for superuser in superusers: create_notification( "service_key_submitted", superuser, metadata=notification_metadata, lookup_path="/service_key_approval/{0}/{1}".format( key.kid, superuser.id), )
def change_username(user_id, new_username): (username_valid, username_issue) = validate_username(new_username) if not username_valid: raise InvalidUsernameException("Invalid username %s: %s" % (new_username, username_issue)) with db_transaction(): # Reload the user for update user = db_for_update(User.select().where(User.id == user_id)).get() # Rename the robots for robot in db_for_update( _list_entity_robots(user.username, include_metadata=False, include_token=False)): _, robot_shortname = parse_robot_username(robot.username) new_robot_name = format_robot_username(new_username, robot_shortname) robot.username = new_robot_name robot.save() # Rename the user user.username = new_username user.save() # Remove any prompts for username. remove_user_prompt(user, "confirm_username") return user
def mark_namespace_for_deletion(user, queues, namespace_gc_queue, force=False): """ Marks a namespace (as referenced by the given user) for deletion. A queue item will be added to delete the namespace's repositories and storage, while the namespace itself will be renamed, disabled, and delinked from other tables. """ if not user.enabled: return None if not force and not user.organization: # Ensure that the user is not the sole admin for any organizations. If so, then the user # cannot be deleted before those organizations are deleted or reassigned. organizations = get_solely_admined_organizations(user) if len(organizations) > 0: message = ( "Cannot delete %s as you are the only admin for organizations: " % user.username) for index, org in enumerate(organizations): if index > 0: message = message + ", " message = message + org.username raise DataModelException(message) # Delete all queue items for the user. for queue in queues: queue.delete_namespaced_items(user.username) # Delete non-repository related items. This operation is very quick, so we can do so here. _delete_user_linked_data(user) with db_transaction(): original_username = user.username user = db_for_update(User.select().where(User.id == user.id)).get() # Mark the namespace as deleted and ready for GC. try: marker = DeletedNamespace.create( namespace=user, original_username=original_username, original_email=user.email) except IntegrityError: return # Disable the namespace itself, and replace its various unique fields with UUIDs. user.enabled = False user.username = str(uuid4()) user.email = str(uuid4()) user.save() # Add a queueitem to delete the namespace. marker.queue_id = namespace_gc_queue.put( [str(user.id)], json.dumps({ "marker_id": marker.id, "original_username": original_username, }), ) marker.save() return marker.id
def get_solely_admined_organizations(user_obj): """ Returns the organizations admined solely by the given user. """ orgs = ( User.select() .where(User.organization == True) .join(Team) .join(TeamRole) .where(TeamRole.name == "admin") .switch(Team) .join(TeamMember) .where(TeamMember.user == user_obj) .distinct() ) # Filter to organizations where the user is the sole admin. solely_admined = [] for org in orgs: admin_user_count = ( TeamMember.select() .join(Team) .join(TeamRole) .where(Team.organization == org, TeamRole.name == "admin") .switch(TeamMember) .join(User) .where(User.robot == False) .distinct() .count() ) if admin_user_count == 1: solely_admined.append(org) return solely_admined
def get_organization_member_set(org, include_robots=False, users_filter=None): """ Returns the set of all member usernames under the given organization, with optional filtering by robots and/or by a specific set of User objects. """ Org = User.alias() org_users = ( User.select(User.username) .join(TeamMember) .join(Team) .where(Team.organization == org) .distinct() ) if not include_robots: org_users = org_users.where(User.robot == False) if users_filter is not None: ids_list = [u.id for u in users_filter if u is not None] if not ids_list: return set() org_users = org_users.where(User.id << ids_list) return {user.username for user in org_users}
def get_organizations(deleted=False): query = User.select().where(User.organization == True, User.robot == False) if not deleted: query = query.where(User.id.not_in(DeletedNamespace.select(DeletedNamespace.namespace))) return query
def get_user_map_by_ids(namespace_ids): id_user = {namespace_id: None for namespace_id in namespace_ids} users = User.select().where(User.id << namespace_ids, User.organization == False) for user in users: id_user[user.id] = user return id_user
def list_team_robots(team): """ Returns an iterator of all the *robots* found in a team. Does not include users. """ return User.select().join(TeamMember).join(Team).where( Team.id == team, User.robot == True)
def __get_org_admin_users(org): return ( User.select() .join(TeamMember) .join(Team) .join(TeamRole) .where(Team.organization == org, TeamRole.name == "admin", User.robot == False) .distinct() )
def _list_entity_robots(entity_name, include_metadata=True, include_token=True): """ Return the list of robots for the specified entity. This MUST return a query, not a materialized list so that callers can use db_for_update. """ if include_metadata or include_token: query = ( User.select(User, RobotAccountToken, RobotAccountMetadata) .join(RobotAccountMetadata, JOIN.LEFT_OUTER) .switch(User) .join(RobotAccountToken) .where(User.robot == True, User.username ** (entity_name + "+%")) ) else: query = User.select(User).where(User.robot == True, User.username ** (entity_name + "+%")) return query
def verify_robot(robot_username, password): try: password = remove_unicode(password) except UnicodeEncodeError: msg = "Could not find robot with username: %s and supplied password." % robot_username raise InvalidRobotException(msg) result = parse_robot_username(robot_username) if result is None: raise InvalidRobotException("%s is an invalid robot name" % robot_username) robot = lookup_robot(robot_username) assert robot.robot # Lookup the token for the robot. try: token_data = RobotAccountToken.get(robot_account=robot) if not token_data.token.matches(password): msg = "Could not find robot with username: %s and supplied password." % robot_username raise InvalidRobotException(msg) except RobotAccountToken.DoesNotExist: # TODO(remove-unenc): Remove once migrated. if not ActiveDataMigration.has_flag(ERTMigrationFlags.READ_OLD_FIELDS): raise InvalidRobotException(msg) if password.find("robot:") >= 0: # Just to be sure. raise InvalidRobotException(msg) query = (User.select().join(FederatedLogin).join(LoginService).where( FederatedLogin.service_ident == password, LoginService.name == "quayrobot", User.username == robot_username, )) try: robot = query.get() except User.DoesNotExist: msg = "Could not find robot with username: %s and supplied password." % robot_username raise InvalidRobotException(msg) # Find the owner user and ensure it is not disabled. try: owner = User.get(User.username == result[0]) except User.DoesNotExist: raise InvalidRobotException("Robot %s owner does not exist" % robot_username) if not owner.enabled: raise InvalidRobotException( "This user has been disabled. Please contact your administrator.") # Mark that the robot was accessed. _basequery.update_last_accessed(robot) return robot
def get_active_users(disabled=True, deleted=False): query = User.select().where(User.organization == False, User.robot == False) if not disabled: query = query.where(User.enabled == True) if not deleted: query = query.where(User.id.not_in(DeletedNamespace.select(DeletedNamespace.namespace))) return query
def get_organizations(disabled=True, deleted=False): query = User.select().where(User.organization == True, User.robot == False) if not disabled: query = query.where(User.enabled == True) else: # NOTE: Deleted users are already disabled, so we don't need this extra check. if not deleted: query = query.where(User.id.not_in(DeletedNamespace.select(DeletedNamespace.namespace))) return query
def _list_entity_robots(entity_name, include_metadata=True, include_token=True): """ Return the list of robots for the specified entity. This MUST return a query, not a materialized list so that callers can use db_for_update. """ # TODO(remove-unenc): Remove FederatedLogin and LEFT_OUTER on RobotAccountToken once migration # is complete. if include_metadata or include_token: query = ( User.select(User, RobotAccountToken, FederatedLogin, RobotAccountMetadata) .join(FederatedLogin) .switch(User) .join(RobotAccountMetadata, JOIN.LEFT_OUTER) .switch(User) .join(RobotAccountToken, JOIN.LEFT_OUTER) .where(User.robot == True, User.username ** (entity_name + "+%")) ) else: query = User.select(User).where(User.robot == True, User.username ** (entity_name + "+%")) return query
def get_all_repo_users_transitive_via_teams(namespace_name, repository_name): return ( User.select() .distinct() .join(TeamMember) .join(Team) .join(RepositoryPermission) .join(Repository) .join(Namespace, on=(Repository.namespace_user == Namespace.id)) .where(Namespace.username == namespace_name, Repository.name == repository_name) )
def get_matching_robots(name_prefix, username, limit=10): admined_orgs = (_basequery.get_user_organizations(username).switch( Team).join(TeamRole).where(TeamRole.name == "admin")) prefix_checks = False for org in admined_orgs: org_search = prefix_search(User.username, org.username + "+" + name_prefix) prefix_checks = prefix_checks | org_search user_search = prefix_search(User.username, username + "+" + name_prefix) prefix_checks = prefix_checks | user_search return User.select().where(prefix_checks).limit(limit)
def cleanup_old_robots(page_size=50, force=False): """ Deletes any robots that live under namespaces that no longer exist. """ if not force and not app.config.get("SETUP_COMPLETE", False): return # Collect the robot accounts to delete. page_number = 1 to_delete = [] encountered_namespaces = {} while True: found_bots = False for robot in list(User.select().where(User.robot == True).paginate( page_number, page_size)): found_bots = True logger.info("Checking robot %s (page %s)", robot.username, page_number) parsed = parse_robot_username(robot.username) if parsed is None: continue namespace, _ = parsed if namespace in encountered_namespaces: if not encountered_namespaces[namespace]: logger.info("Marking %s to be deleted", robot.username) to_delete.append(robot) else: try: User.get(username=namespace) encountered_namespaces[namespace] = True except User.DoesNotExist: # Save the robot account for deletion. logger.info("Marking %s to be deleted", robot.username) to_delete.append(robot) encountered_namespaces[namespace] = False if not found_bots: break page_number = page_number + 1 # Cleanup any robot accounts whose corresponding namespace doesn't exist. logger.info("Found %s robots to delete", len(to_delete)) for index, robot in enumerate(to_delete): logger.info("Deleting robot %s of %s (%s)", index, len(to_delete), robot.username) robot.delete_instance(recursive=True, delete_nullable=True)
def _get_matching_users(username_prefix, robot_namespace=None, organization=None, limit=20, exact_matches_only=False): user_search = prefix_search(User.username, username_prefix) if exact_matches_only: user_search = User.username == username_prefix direct_user_query = user_search & (User.organization == False) & (User.robot == False) if robot_namespace: robot_prefix = format_robot_username(robot_namespace, username_prefix) robot_search = prefix_search(User.username, robot_prefix) direct_user_query = (robot_search & (User.robot == True)) | direct_user_query query = (User.select(User.id, User.username, User.email, User.robot).group_by( User.id, User.username, User.email, User.robot).where(direct_user_query)) if organization: query = (query.select(User.id, User.username, User.email, User.robot, fn.Sum(Team.id)).join( TeamMember, JOIN.LEFT_OUTER).join( Team, JOIN.LEFT_OUTER, on=((Team.id == TeamMember.team) & (Team.organization == organization)), ).order_by(User.robot.desc())) class MatchingUserResult(object): def __init__(self, *args): self.id = args[0] self.username = args[1] self.email = args[2] self.robot = args[3] if organization: self.is_org_member = args[3] != None else: self.is_org_member = None return (MatchingUserResult(*args) for args in query.tuples().limit(limit))
def _notify_superusers(key): notification_metadata = { 'name': key.name, 'kid': key.kid, 'service': key.service, 'jwk': key.jwk, 'metadata': key.metadata, 'created_date': timegm(key.created_date.utctimetuple()), } if key.expiration_date is not None: notification_metadata['expiration_date'] = timegm(key.expiration_date.utctimetuple()) if len(config.app_config['SUPER_USERS']) > 0: superusers = User.select().where(User.username << config.app_config['SUPER_USERS']) for superuser in superusers: create_notification('service_key_submitted', superuser, metadata=notification_metadata, lookup_path='/service_key_approval/{0}/{1}'.format(key.kid, superuser.id))
def test_config_file_with_no_db_users(self): with FreshConfigProvider(): # Write some config. self.putJsonResponse(SuperUserConfig, data=dict(config={}, hostname='foobar')) # Delete all the users in the DB. for user in list(User.select()): model.user.delete_user(user, all_queues) # This method should now succeed. data = dict(username='******', password='******', email='*****@*****.**') result = self.postJsonResponse(SuperUserCreateInitialSuperUser, data=data) self.assertTrue(result['status']) # Verify the superuser was created. User.get(User.username == 'cooluser') # Verify the superuser was placed into the config. result = self.getJsonResponse(SuperUserConfig) self.assertEquals(['cooluser'], result['config']['SUPER_USERS'])
def test_cleanup_old_robots(initialized_db): before_robot_count = User.select().where(User.robot == True).count() before_user_count = User.select().count() # Run the cleanup once, and ensure it does nothing. cleanup_old_robots(force=True) after_robot_count = User.select().where(User.robot == True).count() after_user_count = User.select().count() assert before_robot_count == after_robot_count assert before_user_count == after_user_count # Create some orphan robots. created = set() for index in range(0, 50): created.add('doesnotexist+a%s' % index) created.add('anothernamespace+b%s' % index) User.create(username='******' % index, robot=True) User.create(username='******' % index, robot=True) before_robot_count = User.select().where(User.robot == True).count() before_user_count = User.select().count() cleanup_old_robots(page_size=10, force=True) after_robot_count = User.select().where(User.robot == True).count() after_user_count = User.select().count() assert before_robot_count == after_robot_count + len(created) assert before_user_count == after_user_count + len(created) for name in created: with pytest.raises(User.DoesNotExist): User.get(username=name)
def upgrade(tables, tester, progress_reporter): op = ProgressWrapper(original_op, progress_reporter) from app import app if app.config.get("SETUP_COMPLETE", False) or tester.is_testing(): # Empty all access token names to fix the bug where we put the wrong name and code # in for some tokens. ( AccessToken.update(token_name=None) .where(~(AccessToken.token_name >> None), AccessToken.temporary == False) .execute() ) # AccessToken. logger.info("Backfilling encrypted credentials for access tokens") for access_token in _iterate( AccessToken, ((AccessToken.token_name >> None) | (AccessToken.token_name == "")) ): logger.info("Backfilling encrypted credentials for access token %s", access_token.id) assert access_token.code is not None assert access_token.code[:ACCESS_TOKEN_NAME_PREFIX_LENGTH] assert access_token.code[ACCESS_TOKEN_NAME_PREFIX_LENGTH:] token_name = access_token.code[:ACCESS_TOKEN_NAME_PREFIX_LENGTH] token_code = _decrypted(access_token.code[ACCESS_TOKEN_NAME_PREFIX_LENGTH:]) ( AccessToken.update(token_name=token_name, token_code=token_code) .where(AccessToken.id == access_token.id, AccessToken.code == access_token.code) .execute() ) assert AccessToken.select().where(AccessToken.token_name >> None).count() == 0 # Robots. logger.info("Backfilling encrypted credentials for robots") while True: has_row = False query = ( User.select() .join(RobotAccountToken, JOIN.LEFT_OUTER) .where(User.robot == True, RobotAccountToken.id >> None) .limit(BATCH_SIZE) ) for robot_user in query: logger.info("Backfilling encrypted credentials for robot %s", robot_user.id) has_row = True try: RobotAccountToken.create( robot_account=robot_user, token=_decrypted(robot_user.email), fully_migrated=False, ) except IntegrityError: break if not has_row: break # RepositoryBuildTrigger logger.info("Backfilling encrypted credentials for repo build triggers") for repo_build_trigger in _iterate( RepositoryBuildTrigger, (RepositoryBuildTrigger.fully_migrated == False) ): logger.info( "Backfilling encrypted credentials for repo build trigger %s", repo_build_trigger.id ) ( RepositoryBuildTrigger.update( secure_auth_token=_decrypted(repo_build_trigger.auth_token), secure_private_key=_decrypted(repo_build_trigger.private_key), fully_migrated=True, ) .where( RepositoryBuildTrigger.id == repo_build_trigger.id, RepositoryBuildTrigger.uuid == repo_build_trigger.uuid, ) .execute() ) assert ( RepositoryBuildTrigger.select() .where(RepositoryBuildTrigger.fully_migrated == False) .count() ) == 0 # AppSpecificAuthToken logger.info("Backfilling encrypted credentials for app specific auth tokens") for token in _iterate( AppSpecificAuthToken, ( (AppSpecificAuthToken.token_name >> None) | (AppSpecificAuthToken.token_name == "") | (AppSpecificAuthToken.token_secret >> None) ), ): logger.info("Backfilling encrypted credentials for app specific auth %s", token.id) assert token.token_code[AST_TOKEN_NAME_PREFIX_LENGTH:] token_name = token.token_code[:AST_TOKEN_NAME_PREFIX_LENGTH] token_secret = _decrypted(token.token_code[AST_TOKEN_NAME_PREFIX_LENGTH:]) assert token_name assert token_secret ( AppSpecificAuthToken.update(token_name=token_name, token_secret=token_secret) .where( AppSpecificAuthToken.id == token.id, AppSpecificAuthToken.token_code == token.token_code, ) .execute() ) assert ( AppSpecificAuthToken.select().where(AppSpecificAuthToken.token_name >> None).count() ) == 0 # OAuthAccessToken logger.info("Backfilling credentials for OAuth access tokens") for token in _iterate( OAuthAccessToken, ((OAuthAccessToken.token_name >> None) | (OAuthAccessToken.token_name == "")), ): logger.info("Backfilling credentials for OAuth access token %s", token.id) token_name = token.access_token[:OAUTH_ACCESS_TOKEN_PREFIX_LENGTH] token_code = Credential.from_string( token.access_token[OAUTH_ACCESS_TOKEN_PREFIX_LENGTH:] ) assert token_name assert token.access_token[OAUTH_ACCESS_TOKEN_PREFIX_LENGTH:] ( OAuthAccessToken.update(token_name=token_name, token_code=token_code) .where( OAuthAccessToken.id == token.id, OAuthAccessToken.access_token == token.access_token, ) .execute() ) assert (OAuthAccessToken.select().where(OAuthAccessToken.token_name >> None).count()) == 0 # OAuthAuthorizationCode logger.info("Backfilling credentials for OAuth auth code") for code in _iterate( OAuthAuthorizationCode, ((OAuthAuthorizationCode.code_name >> None) | (OAuthAuthorizationCode.code_name == "")), ): logger.info("Backfilling credentials for OAuth auth code %s", code.id) user_code = code.code or random_string_generator(AUTHORIZATION_CODE_PREFIX_LENGTH * 2)() code_name = user_code[:AUTHORIZATION_CODE_PREFIX_LENGTH] code_credential = Credential.from_string(user_code[AUTHORIZATION_CODE_PREFIX_LENGTH:]) assert code_name assert user_code[AUTHORIZATION_CODE_PREFIX_LENGTH:] ( OAuthAuthorizationCode.update(code_name=code_name, code_credential=code_credential) .where(OAuthAuthorizationCode.id == code.id) .execute() ) assert ( OAuthAuthorizationCode.select().where(OAuthAuthorizationCode.code_name >> None).count() ) == 0 # OAuthApplication logger.info("Backfilling secret for OAuth applications") for app in _iterate(OAuthApplication, OAuthApplication.fully_migrated == False): logger.info("Backfilling secret for OAuth application %s", app.id) client_secret = app.client_secret or str(uuid.uuid4()) secure_client_secret = _decrypted(client_secret) ( OAuthApplication.update( secure_client_secret=secure_client_secret, fully_migrated=True ) .where(OAuthApplication.id == app.id, OAuthApplication.fully_migrated == False) .execute() ) assert ( OAuthApplication.select().where(OAuthApplication.fully_migrated == False).count() ) == 0 # Adjust existing fields to be nullable. op.alter_column("accesstoken", "code", nullable=True, existing_type=sa.String(length=255)) op.alter_column( "oauthaccesstoken", "access_token", nullable=True, existing_type=sa.String(length=255) ) op.alter_column( "oauthauthorizationcode", "code", nullable=True, existing_type=sa.String(length=255) ) op.alter_column( "appspecificauthtoken", "token_code", nullable=True, existing_type=sa.String(length=255) ) # Adjust new fields to be non-nullable. op.alter_column( "accesstoken", "token_name", nullable=False, existing_type=sa.String(length=255) ) op.alter_column( "accesstoken", "token_code", nullable=False, existing_type=sa.String(length=255) ) op.alter_column( "appspecificauthtoken", "token_name", nullable=False, existing_type=sa.String(length=255) ) op.alter_column( "appspecificauthtoken", "token_secret", nullable=False, existing_type=sa.String(length=255) ) op.alter_column( "oauthaccesstoken", "token_name", nullable=False, existing_type=sa.String(length=255) ) op.alter_column( "oauthaccesstoken", "token_code", nullable=False, existing_type=sa.String(length=255) ) op.alter_column( "oauthauthorizationcode", "code_name", nullable=False, existing_type=sa.String(length=255) ) op.alter_column( "oauthauthorizationcode", "code_credential", nullable=False, existing_type=sa.String(length=255), )
def upgrade(tables, tester, progress_reporter): op = ProgressWrapper(original_op, progress_reporter) # NOTE: Disconnects the Alembic database connection. We do this because the Peewee calls below # use a *different* connection, and if we leave the alembic connection open, it'll time out. # See: https://github.com/sqlalchemy/alembic/issues/630 op.get_bind().execute("COMMIT") op.get_bind().invalidate() from app import app if app.config.get("SETUP_COMPLETE", False) or tester.is_testing(): # AccessToken. logger.info("Backfilling encrypted credentials for access tokens") for access_token in _iterate(AccessToken, ((AccessToken.token_name >> None) | (AccessToken.token_name == ""))): logger.info( "Backfilling encrypted credentials for access token %s", access_token.id) assert access_token.code is not None assert access_token.code[:ACCESS_TOKEN_NAME_PREFIX_LENGTH] assert access_token.code[ACCESS_TOKEN_NAME_PREFIX_LENGTH:] token_name = access_token.code[:ACCESS_TOKEN_NAME_PREFIX_LENGTH] token_code = _decrypted( access_token.code[ACCESS_TOKEN_NAME_PREFIX_LENGTH:]) (AccessToken.update( token_name=token_name, token_code=token_code).where( AccessToken.id == access_token.id, AccessToken.code == access_token.code).execute()) assert AccessToken.select().where( AccessToken.token_name >> None).count() == 0 # Robots. logger.info("Backfilling encrypted credentials for robots") while True: has_row = False query = (User.select().join( RobotAccountToken, JOIN.LEFT_OUTER).where( User.robot == True, RobotAccountToken.id >> None).limit(BATCH_SIZE)) for robot_user in query: logger.info("Backfilling encrypted credentials for robot %s", robot_user.id) has_row = True try: RobotAccountToken.create( robot_account=robot_user, token=_decrypted(robot_user.email), fully_migrated=False, ) except IntegrityError: break if not has_row: break # RepositoryBuildTrigger logger.info( "Backfilling encrypted credentials for repo build triggers") for repo_build_trigger in _iterate( RepositoryBuildTrigger, (RepositoryBuildTrigger.fully_migrated == False)): logger.info( "Backfilling encrypted credentials for repo build trigger %s", repo_build_trigger.id) (RepositoryBuildTrigger.update( secure_auth_token=_decrypted(repo_build_trigger.auth_token), secure_private_key=_decrypted(repo_build_trigger.private_key), fully_migrated=True, ).where( RepositoryBuildTrigger.id == repo_build_trigger.id, RepositoryBuildTrigger.uuid == repo_build_trigger.uuid, ).execute()) assert (RepositoryBuildTrigger.select().where( RepositoryBuildTrigger.fully_migrated == False).count()) == 0 # AppSpecificAuthToken logger.info( "Backfilling encrypted credentials for app specific auth tokens") for token in _iterate( AppSpecificAuthToken, ((AppSpecificAuthToken.token_name >> None) | (AppSpecificAuthToken.token_name == "") | (AppSpecificAuthToken.token_secret >> None)), ): logger.info( "Backfilling encrypted credentials for app specific auth %s", token.id) assert token.token_code[AST_TOKEN_NAME_PREFIX_LENGTH:] token_name = token.token_code[:AST_TOKEN_NAME_PREFIX_LENGTH] token_secret = _decrypted( token.token_code[AST_TOKEN_NAME_PREFIX_LENGTH:]) assert token_name assert token_secret (AppSpecificAuthToken.update( token_name=token_name, token_secret=token_secret).where( AppSpecificAuthToken.id == token.id, AppSpecificAuthToken.token_code == token.token_code, ).execute()) assert (AppSpecificAuthToken.select().where( AppSpecificAuthToken.token_name >> None).count()) == 0 # OAuthAccessToken logger.info("Backfilling credentials for OAuth access tokens") for token in _iterate( OAuthAccessToken, ((OAuthAccessToken.token_name >> None) | (OAuthAccessToken.token_name == "")), ): logger.info("Backfilling credentials for OAuth access token %s", token.id) token_name = token.access_token[:OAUTH_ACCESS_TOKEN_PREFIX_LENGTH] token_code = Credential.from_string( token.access_token[OAUTH_ACCESS_TOKEN_PREFIX_LENGTH:]) assert token_name assert token.access_token[OAUTH_ACCESS_TOKEN_PREFIX_LENGTH:] (OAuthAccessToken.update( token_name=token_name, token_code=token_code).where( OAuthAccessToken.id == token.id, OAuthAccessToken.access_token == token.access_token, ).execute()) assert (OAuthAccessToken.select().where( OAuthAccessToken.token_name >> None).count()) == 0 # OAuthAuthorizationCode logger.info("Backfilling credentials for OAuth auth code") for code in _iterate( OAuthAuthorizationCode, ((OAuthAuthorizationCode.code_name >> None) | (OAuthAuthorizationCode.code_name == "")), ): logger.info("Backfilling credentials for OAuth auth code %s", code.id) user_code = code.code or random_string_generator( AUTHORIZATION_CODE_PREFIX_LENGTH * 2)() code_name = user_code[:AUTHORIZATION_CODE_PREFIX_LENGTH] code_credential = Credential.from_string( user_code[AUTHORIZATION_CODE_PREFIX_LENGTH:]) assert code_name assert user_code[AUTHORIZATION_CODE_PREFIX_LENGTH:] (OAuthAuthorizationCode.update( code_name=code_name, code_credential=code_credential).where( OAuthAuthorizationCode.id == code.id).execute()) assert (OAuthAuthorizationCode.select().where( OAuthAuthorizationCode.code_name >> None).count()) == 0 # OAuthApplication logger.info("Backfilling secret for OAuth applications") for app in _iterate(OAuthApplication, OAuthApplication.fully_migrated == False): logger.info("Backfilling secret for OAuth application %s", app.id) client_secret = app.client_secret or str(uuid.uuid4()) secure_client_secret = _decrypted(client_secret) (OAuthApplication.update( secure_client_secret=secure_client_secret, fully_migrated=True).where( OAuthApplication.id == app.id, OAuthApplication.fully_migrated == False).execute()) assert (OAuthApplication.select().where( OAuthApplication.fully_migrated == False).count()) == 0
def get_minimum_user_id(): return User.select(fn.Min(User.id)).tuples().get()[0]
def get_user_organizations(username): UserAlias = User.alias() return (User.select().distinct().join(Team).join(TeamMember).join( UserAlias, on=(UserAlias.id == TeamMember.user)).where( User.organization == True, UserAlias.username == username))
def has_users(self): return bool(list(User.select().limit(1)))
def get_robot_count(): return User.select().where(User.robot == True).count()
def is_valid(self): try: list(User.select().limit(1)) return True except: return False
def has_users(): """ Return false if no users in database yet """ return bool(User.select().limit(1))