예제 #1
0
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)
예제 #2
0
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
예제 #3
0
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
예제 #5
0
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
예제 #7
0
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
예제 #8
0
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
예제 #9
0
def retrieve_robot_token(robot):
    """
    Returns the decrypted token for the given robot.
    """
    token = RobotAccountToken.get(robot_account=robot).token.decrypt()
    return token