def create_robot(robot_shortname, parent, description="", unstructured_metadata=None): (username_valid, username_issue) = validate_username(robot_shortname) if not username_valid: raise InvalidRobotException( "The name for the robot '%s' is invalid: %s" % (robot_shortname, username_issue) ) username = format_robot_username(parent.username, robot_shortname) try: User.get(User.username == username) msg = "Existing robot with name: %s" % username logger.info(msg) raise InvalidRobotException(msg) except User.DoesNotExist: pass service = LoginService.get(name="quayrobot") try: with db_transaction(): created = User.create(username=username, email=str(uuid.uuid4()), robot=True) token = random_string_generator(length=64)() RobotAccountToken.create(robot_account=created, token=token, fully_migrated=True) FederatedLogin.create( user=created, service=service, service_ident="robot:%s" % created.id ) RobotAccountMetadata.create( robot_account=created, description=description[0:255], unstructured_json=unstructured_metadata or {}, ) return created, token except Exception as ex: raise DataModelException(ex.message)
def regenerate_robot_token(robot_shortname, parent): robot_username = format_robot_username(parent.username, robot_shortname) robot, metadata = lookup_robot_and_metadata(robot_username) password = random_string_generator(length=64)() robot.email = str(uuid4()) robot.uuid = str(uuid4()) service = LoginService.get(name="quayrobot") login = FederatedLogin.get(FederatedLogin.user == robot, FederatedLogin.service == service) login.service_ident = "robot:%s" % (robot.id) try: token_data = RobotAccountToken.get(robot_account=robot) except RobotAccountToken.DoesNotExist: token_data = RobotAccountToken.create(robot_account=robot) token_data.token = password with db_transaction(): token_data.save() login.save() robot.save() return robot, password, metadata
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 upgrade(tables, tester, progress_reporter): op = ProgressWrapper(original_op, progress_reporter) # ### commands auto generated by Alembic - please adjust! ### op.drop_index("oauthaccesstoken_refresh_token", table_name="oauthaccesstoken") op.drop_column(u"oauthaccesstoken", "refresh_token") op.drop_column("accesstoken", "code") op.drop_column("appspecificauthtoken", "token_code") op.drop_column("oauthaccesstoken", "access_token") op.drop_column("oauthapplication", "client_secret") op.drop_column("oauthauthorizationcode", "code") op.drop_column("repositorybuildtrigger", "private_key") op.drop_column("repositorybuildtrigger", "auth_token") # ### end Alembic commands ### # Overwrite all plaintext robot credentials. from app import app if app.config.get("SETUP_COMPLETE", False) or tester.is_testing(): while True: try: robot_account_token = RobotAccountToken.get(fully_migrated=False) logger.debug("Found robot account token %s migrate", robot_account_token.id) robot_account = robot_account_token.robot_account assert robot_account.robot result = ( User.update(email=str(uuid.uuid4())) .where( User.id == robot_account.id, User.robot == True, User.uuid == robot_account.uuid, ) .execute() ) assert result == 1 try: federated_login = FederatedLogin.get(user=robot_account) assert federated_login.service.name == "quayrobot" federated_login.service_ident = "robot:%s" % robot_account.id federated_login.save() except FederatedLogin.DoesNotExist: pass robot_account_token.fully_migrated = True robot_account_token.save() logger.debug("Finished migrating robot account token %s", robot_account_token.id) except RobotAccountToken.DoesNotExist: break
def retrieve_robot_token(robot): """ Returns the decrypted token for the given robot. """ try: token = RobotAccountToken.get(robot_account=robot).token.decrypt() except RobotAccountToken.DoesNotExist: if ActiveDataMigration.has_flag(ERTMigrationFlags.READ_OLD_FIELDS): # For legacy only. token = robot.email else: raise return token
def upgrade(tables, tester, progress_reporter): op = ProgressWrapper(original_op, progress_reporter) # ### commands auto generated by Alembic - please adjust! ### op.drop_index("oauthaccesstoken_refresh_token", table_name="oauthaccesstoken") op.drop_column(u"oauthaccesstoken", "refresh_token") op.drop_column("accesstoken", "code") op.drop_column("appspecificauthtoken", "token_code") op.drop_column("oauthaccesstoken", "access_token") op.drop_column("oauthapplication", "client_secret") op.drop_column("oauthauthorizationcode", "code") op.drop_column("repositorybuildtrigger", "private_key") op.drop_column("repositorybuildtrigger", "auth_token") # ### end Alembic commands ### # Overwrite all plaintext robot credentials. from app import app if app.config.get("SETUP_COMPLETE", False) or tester.is_testing(): while True: try: robot_account_token = RobotAccountToken.get( fully_migrated=False) robot_account = robot_account_token.robot_account robot_account.email = str(uuid.uuid4()) robot_account.save() federated_login = FederatedLogin.get(user=robot_account) federated_login.service_ident = "robot:%s" % robot_account.id federated_login.save() robot_account_token.fully_migrated = True robot_account_token.save() except RobotAccountToken.DoesNotExist: break
def verify_robot(robot_username, password): try: password.encode("ascii") 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: 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 upgrade(tables, tester, progress_reporter): op = ProgressWrapper(original_op, progress_reporter) # ### commands auto generated by Alembic - please adjust! ### op.drop_index('oauthaccesstoken_refresh_token', table_name='oauthaccesstoken') op.drop_column(u'oauthaccesstoken', 'refresh_token') op.drop_column('accesstoken', 'code') op.drop_column('appspecificauthtoken', 'token_code') op.drop_column('oauthaccesstoken', 'access_token') op.drop_column('oauthapplication', 'client_secret') op.drop_column('oauthauthorizationcode', 'code') op.drop_column('repositorybuildtrigger', 'private_key') op.drop_column('repositorybuildtrigger', 'auth_token') # ### end Alembic commands ### # Overwrite all plaintext robot credentials. while True: try: robot_account_token = RobotAccountToken.get(fully_migrated=False) robot_account = robot_account_token.robot_account robot_account.email = str(uuid.uuid4()) robot_account.save() federated_login = FederatedLogin.get(user=robot_account) federated_login.service_ident = 'robot:%s' % robot_account.id federated_login.save() robot_account_token.fully_migrated = True robot_account_token.save() except RobotAccountToken.DoesNotExist: break
def retrieve_robot_token(robot): """ Returns the decrypted token for the given robot. """ token = RobotAccountToken.get(robot_account=robot).token.decrypt() return token