Пример #1
0
def _queue_logs_export(start_time,
                       end_time,
                       options,
                       namespace_name,
                       repository_name=None):
    callback_url = options.get("callback_url")
    if callback_url:
        if not callback_url.startswith(
                "https://") and not callback_url.startswith("http://"):
            raise InvalidRequest("Invalid callback URL")

    callback_email = options.get("callback_email")
    if callback_email:
        if callback_email.find("@") < 0:
            raise InvalidRequest("Invalid callback e-mail")

    (start_time, end_time) = _validate_logs_arguments(start_time, end_time)
    export_id = logs_model.queue_logs_export(
        start_time,
        end_time,
        export_action_logs_queue,
        namespace_name,
        repository_name,
        callback_url,
        callback_email,
    )
    if export_id is None:
        raise InvalidRequest("Invalid export request")

    return export_id
Пример #2
0
    def put(self, username):
        """ Updates information about the specified user. """
        if SuperUserPermission().can():
            user = pre_oci_model.get_nonrobot_user(username)
            if user is None:
                raise NotFound()

            if superusers.is_superuser(username):
                raise InvalidRequest('Cannot update a superuser')

            user_data = request.get_json()
            if 'password' in user_data:
                # Ensure that we are using database auth.
                if app.config['AUTHENTICATION_TYPE'] != 'Database':
                    raise InvalidRequest(
                        'Cannot change password in non-database auth')

                pre_oci_model.change_password(username, user_data['password'])

            if 'email' in user_data:
                # Ensure that we are using database auth.
                if app.config['AUTHENTICATION_TYPE'] not in [
                        'Database', 'AppToken'
                ]:
                    raise InvalidRequest(
                        'Cannot change e-mail in non-database auth')

                pre_oci_model.update_email(username,
                                           user_data['email'],
                                           auto_verify=True)

            if 'enabled' in user_data:
                # Disable/enable the user.
                pre_oci_model.update_enabled(username,
                                             bool(user_data['enabled']))

            if 'superuser' in user_data:
                config_object = config_provider.get_config()
                superusers_set = set(config_object['SUPER_USERS'])

                if user_data['superuser']:
                    superusers_set.add(username)
                elif username in superusers_set:
                    superusers_set.remove(username)

                config_object['SUPER_USERS'] = list(superusers_set)
                config_provider.save_config(config_object)

            return_value = user.to_dict()
            if user_data.get('password') is not None:
                password = user_data.get('password')
                return_value[
                    'encrypted_password'] = authentication.encrypt_user_password(
                        password)
            if user_data.get('email') is not None:
                return_value['email'] = user_data.get('email')

            return return_value

        raise Unauthorized()
Пример #3
0
    def put(self, username):
        """
        Updates information about the specified user.
        """
        if SuperUserPermission().can():
            user = pre_oci_model.get_nonrobot_user(username)
            if user is None:
                raise NotFound()

            if superusers.is_superuser(username):
                raise InvalidRequest("Cannot update a superuser")

            user_data = request.get_json()
            if "password" in user_data:
                # Ensure that we are using database auth.
                if app.config["AUTHENTICATION_TYPE"] != "Database":
                    raise InvalidRequest("Cannot change password in non-database auth")

                pre_oci_model.change_password(username, user_data["password"])

            if "email" in user_data:
                # Ensure that we are using database auth.
                if app.config["AUTHENTICATION_TYPE"] not in ["Database", "AppToken"]:
                    raise InvalidRequest("Cannot change e-mail in non-database auth")

                pre_oci_model.update_email(username, user_data["email"], auto_verify=True)

            if "enabled" in user_data:
                # Disable/enable the user.
                pre_oci_model.update_enabled(username, bool(user_data["enabled"]))

            if "superuser" in user_data:
                config_object = config_provider.get_config()
                superusers_set = set(config_object["SUPER_USERS"])

                if user_data["superuser"]:
                    superusers_set.add(username)
                elif username in superusers_set:
                    superusers_set.remove(username)

                config_object["SUPER_USERS"] = list(superusers_set)
                config_provider.save_config(config_object)

            return_value = user.to_dict()
            if user_data.get("password") is not None:
                password = user_data.get("password")
                return_value["encrypted_password"] = authentication.encrypt_user_password(
                    password
                ).decode("ascii")
            if user_data.get("email") is not None:
                return_value["email"] = user_data.get("email")

            return return_value

        raise Unauthorized()
Пример #4
0
    def put(self, kid):
        if SuperUserPermission().can():
            body = request.get_json()
            try:
                key = pre_oci_model.get_service_key(kid,
                                                    approved_only=False,
                                                    alive_only=False)
            except ServiceKeyDoesNotExist:
                raise NotFound()

            key_log_metadata = {
                'kid': key.kid,
                'service': key.service,
                'name': body.get('name', key.name),
                'expiration_date': key.expiration_date,
            }

            if 'expiration' in body:
                expiration_date = body['expiration']
                if expiration_date is not None and expiration_date != '':
                    try:
                        expiration_date = datetime.utcfromtimestamp(
                            float(expiration_date))
                    except ValueError as ve:
                        raise InvalidRequest('Invalid expiration date: %s' %
                                             ve)

                    if expiration_date <= datetime.now():
                        raise InvalidRequest(
                            'Cannot have an expiration date in the past')

                key_log_metadata.update({
                    'old_expiration_date': key.expiration_date,
                    'expiration_date': expiration_date,
                })

                log_action('service_key_extend', None, key_log_metadata)
                pre_oci_model.set_key_expiration(kid, expiration_date)

            if 'name' in body or 'metadata' in body:
                key_name = body.get('name')
                if not validate_service_key_name(key_name):
                    raise InvalidRequest(
                        'Invalid service key friendly name: %s' % key_name)

                pre_oci_model.update_service_key(kid, key_name,
                                                 body.get('metadata'))
                log_action('service_key_modify', None, key_log_metadata)

            updated_key = pre_oci_model.get_service_key(kid,
                                                        approved_only=False,
                                                        alive_only=False)
            return jsonify(updated_key.to_dict())

        raise Unauthorized()
Пример #5
0
    def put(self, kid):
        if SuperUserPermission().can():
            body = request.get_json()
            try:
                key = pre_oci_model.get_service_key(kid,
                                                    approved_only=False,
                                                    alive_only=False)
            except ServiceKeyDoesNotExist:
                raise NotFound()

            key_log_metadata = {
                "kid": key.kid,
                "service": key.service,
                "name": body.get("name", key.name),
                "expiration_date": key.expiration_date,
            }

            if "expiration" in body:
                expiration_date = body["expiration"]
                if expiration_date is not None and expiration_date != "":
                    try:
                        expiration_date = datetime.utcfromtimestamp(
                            float(expiration_date))
                    except ValueError as ve:
                        raise InvalidRequest("Invalid expiration date: %s" %
                                             ve)

                    if expiration_date <= datetime.now():
                        raise InvalidRequest(
                            "Cannot have an expiration date in the past")

                key_log_metadata.update({
                    "old_expiration_date": key.expiration_date,
                    "expiration_date": expiration_date,
                })

                log_action("service_key_extend", None, key_log_metadata)
                pre_oci_model.set_key_expiration(kid, expiration_date)

            if "name" in body or "metadata" in body:
                key_name = body.get("name")
                if not validate_service_key_name(key_name):
                    raise InvalidRequest(
                        "Invalid service key friendly name: %s" % key_name)

                pre_oci_model.update_service_key(kid, key_name,
                                                 body.get("metadata"))
                log_action("service_key_modify", None, key_log_metadata)

            updated_key = pre_oci_model.get_service_key(kid,
                                                        approved_only=False,
                                                        alive_only=False)
            return jsonify(updated_key.to_dict())

        raise Unauthorized()
Пример #6
0
    def post(self, namespace_name, repository_name, uuid):
        """
        Resets repository notification to 0 failures.
        """
        reset = model.reset_notification_number_of_failures(namespace_name, repository_name, uuid)
        if not reset:
            raise InvalidRequest(
                "No repository notification found for: %s, %s, %s"
                % (namespace_name, repository_name, uuid)
            )

        log_action(
            "reset_repo_notification",
            namespace_name,
            {
                "repo": repository_name,
                "namespace": namespace_name,
                "notification_id": uuid,
                "event": reset.event_name,
                "method": reset.method_name,
            },
            repo_name=repository_name,
        )

        return "No Content", 204
Пример #7
0
    def delete(self, namespace_name, repository_name, uuid):
        """
        Deletes the specified notification.
        """
        deleted = model.delete_repo_notification(namespace_name, repository_name, uuid)
        if not deleted:
            raise InvalidRequest(
                "No repository notification found for: %s, %s, %s"
                % (namespace_name, repository_name, uuid)
            )

        log_action(
            "delete_repo_notification",
            namespace_name,
            {
                "repo": repository_name,
                "namespace": namespace_name,
                "notification_id": uuid,
                "event": deleted.event_name,
                "method": deleted.method_name,
            },
            repo_name=repository_name,
        )

        return "No Content", 204
Пример #8
0
    def post(self):
        """ Creates a new user. """
        # Ensure that we are using database auth.
        if app.config["AUTHENTICATION_TYPE"] != "Database":
            raise InvalidRequest("Cannot create a user in a non-database auth system")

        user_information = request.get_json()
        if SuperUserPermission().can():
            # Generate a temporary password for the user.
            random = SystemRandom()
            password = "".join(
                [random.choice(string.ascii_uppercase + string.digits) for _ in range(32)]
            )

            # Create the user.
            username = user_information["username"]
            email = user_information.get("email")
            install_user, confirmation_code = pre_oci_model.create_install_user(
                username, password, email
            )
            if features.MAILING:
                send_confirmation_email(
                    install_user.username, install_user.email, confirmation_code
                )

            return {
                "username": username,
                "email": email,
                "password": password,
                "encrypted_password": authentication.encrypt_user_password(password),
            }

        raise Unauthorized()
Пример #9
0
    def post(self, namespace):
        """
        Takes ownership of the specified organization or user.
        """
        if SuperUserPermission().can():
            # Disallow for superusers.
            if superusers.is_superuser(namespace):
                raise InvalidRequest("Cannot take ownership of a superuser")

            authed_user = get_authenticated_user()
            entity_id, was_user = pre_oci_model.take_ownership(namespace, authed_user)
            if entity_id is None:
                raise NotFound()

            # Log the change.
            log_metadata = {
                "entity_id": entity_id,
                "namespace": namespace,
                "was_user": was_user,
                "superuser": authed_user.username,
            }

            log_action("take_ownership", authed_user.username, log_metadata)

            return jsonify({"namespace": namespace})

        raise Unauthorized()
Пример #10
0
    def post(self, username):
        # Ensure that we are using database auth.
        if app.config["AUTHENTICATION_TYPE"] != "Database":
            raise InvalidRequest("Cannot send a recovery e-mail for non-database auth")

        if SuperUserPermission().can():
            user = pre_oci_model.get_nonrobot_user(username)
            if user is None:
                raise NotFound()

            if superusers.is_superuser(username):
                raise InvalidRequest("Cannot send a recovery email for a superuser")

            code = pre_oci_model.create_reset_password_email_code(user.email)
            send_recovery_email(user.email, code)
            return {"email": user.email}

        raise Unauthorized()
Пример #11
0
    def post(self, namespace_name, repository_name, uuid):
        """ Queues a test notification for this repository. """
        test_note = model.queue_test_notification(uuid)
        if not test_note:
            raise InvalidRequest(
                "No repository notification found for: %s, %s, %s" %
                (namespace_name, repository_name, uuid))

        return {}, 200
Пример #12
0
def _queue_logs_export(start_time, end_time, options, namespace_name, repository_name=None):
  callback_url = options.get('callback_url')
  if callback_url:
    if not callback_url.startswith('https://') and not callback_url.startswith('http://'):
      raise InvalidRequest('Invalid callback URL')

  callback_email = options.get('callback_email')
  if callback_email:
    if callback_email.find('@') < 0:
      raise InvalidRequest('Invalid callback e-mail')

  (start_time, end_time) = _validate_logs_arguments(start_time, end_time)
  export_id = logs_model.queue_logs_export(start_time, end_time, export_action_logs_queue,
                                           namespace_name, repository_name, callback_url,
                                           callback_email)
  if export_id is None:
    raise InvalidRequest('Invalid export request')

  return export_id
Пример #13
0
    def delete(self, username):
        """ Deletes the specified user. """
        if SuperUserPermission().can():
            user = pre_oci_model.get_nonrobot_user(username)
            if user is None:
                raise NotFound()

            if superusers.is_superuser(username):
                raise InvalidRequest("Cannot delete a superuser")

            pre_oci_model.mark_user_for_deletion(username)
            return "", 204

        raise Unauthorized()
Пример #14
0
    def delete(self, namespace_name, repository_name, uuid):
        """ Deletes the specified notification. """
        deleted = model.delete_repo_notification(namespace_name,
                                                 repository_name, uuid)
        if not deleted:
            raise InvalidRequest(
                "No repository notification found for: %s, %s, %s" %
                (namespace_name, repository_name, uuid))

        log_action('delete_repo_notification',
                   namespace_name, {
                       'repo': repository_name,
                       'namespace': namespace_name,
                       'notification_id': uuid,
                       'event': deleted.event_name,
                       'method': deleted.method_name
                   },
                   repo_name=repository_name)

        return 'No Content', 204
Пример #15
0
    def post(self, namespace_name, repository_name, uuid):
        """ Resets repository notification to 0 failures. """
        reset = model.reset_notification_number_of_failures(
            namespace_name, repository_name, uuid)
        if not reset:
            raise InvalidRequest(
                "No repository notification found for: %s, %s, %s" %
                (namespace_name, repository_name, uuid))

        log_action('reset_repo_notification',
                   namespace_name, {
                       'repo': repository_name,
                       'namespace': namespace_name,
                       'notification_id': uuid,
                       'event': reset.event_name,
                       'method': reset.method_name
                   },
                   repo_name=repository_name)

        return 'No Content', 204
Пример #16
0
    def post(self, username):
        if not authentication.federated_service:
            abort(404)

        # Only allowed if there is a logged in user.
        if not get_authenticated_user():
            raise Unauthorized()

        # Try to link the user with the given *external* username, to an internal record.
        (user, err_msg) = authentication.link_user(username)
        if user is None:
            raise InvalidRequest(err_msg, payload={"username": username})

        return {
            "entity": {
                "name": user.username,
                "kind": "user",
                "is_robot": False,
                "avatar": avatar.get_data_for_user(user),
            }
        }
Пример #17
0
    def post(self, username):
        if not authentication.federated_service:
            abort(404)

        # Only allowed if there is a logged in user.
        if not get_authenticated_user():
            raise Unauthorized()

        # Try to link the user with the given *external* username, to an internal record.
        (user, err_msg) = authentication.link_user(username)
        if user is None:
            raise InvalidRequest(err_msg, payload={'username': username})

        return {
            'entity': {
                'name': user.username,
                'kind': 'user',
                'is_robot': False,
                'avatar': avatar.get_data_for_user(user)
            }
        }
Пример #18
0
    def post(self):
        if SuperUserPermission().can():
            body = request.get_json()
            key_name = body.get("name", "")
            if not validate_service_key_name(key_name):
                raise InvalidRequest("Invalid service key friendly name: %s" % key_name)

            # Ensure we have a valid expiration date if specified.
            expiration_date = body.get("expiration", None)
            if expiration_date is not None:
                try:
                    expiration_date = datetime.utcfromtimestamp(float(expiration_date))
                except ValueError as ve:
                    raise InvalidRequest("Invalid expiration date: %s" % ve)

                if expiration_date <= datetime.now():
                    raise InvalidRequest("Expiration date cannot be in the past")

            # Create the metadata for the key.
            user = get_authenticated_user()
            metadata = body.get("metadata", {})
            metadata.update(
                {
                    "created_by": "Quay Superuser Panel",
                    "creator": user.username,
                    "ip": get_request_ip(),
                }
            )

            # Generate a key with a private key that we *never save*.
            (private_key, key_id) = pre_oci_model.generate_service_key(
                body["service"], expiration_date, metadata=metadata, name=key_name
            )
            # Auto-approve the service key.
            pre_oci_model.approve_service_key(
                key_id, user, ServiceKeyApprovalType.SUPERUSER, notes=body.get("notes", "")
            )

            # Log the creation and auto-approval of the service key.
            key_log_metadata = {
                "kid": key_id,
                "preshared": True,
                "service": body["service"],
                "name": key_name,
                "expiration_date": expiration_date,
                "auto_approved": True,
            }

            log_action("service_key_create", None, key_log_metadata)
            log_action("service_key_approve", None, key_log_metadata)

            return jsonify(
                {
                    "kid": key_id,
                    "name": key_name,
                    "service": body["service"],
                    "public_key": private_key.publickey().exportKey("PEM").decode("ascii"),
                    "private_key": private_key.exportKey("PEM").decode("ascii"),
                }
            )

        raise Unauthorized()
Пример #19
0
    def post(self):
        if SuperUserPermission().can():
            body = request.get_json()
            key_name = body.get('name', '')
            if not validate_service_key_name(key_name):
                raise InvalidRequest('Invalid service key friendly name: %s' %
                                     key_name)

            # Ensure we have a valid expiration date if specified.
            expiration_date = body.get('expiration', None)
            if expiration_date is not None:
                try:
                    expiration_date = datetime.utcfromtimestamp(
                        float(expiration_date))
                except ValueError as ve:
                    raise InvalidRequest('Invalid expiration date: %s' % ve)

                if expiration_date <= datetime.now():
                    raise InvalidRequest(
                        'Expiration date cannot be in the past')

            # Create the metadata for the key.
            user = get_authenticated_user()
            metadata = body.get('metadata', {})
            metadata.update({
                'created_by': 'Quay Superuser Panel',
                'creator': user.username,
                'ip': get_request_ip(),
            })

            # Generate a key with a private key that we *never save*.
            (private_key,
             key_id) = pre_oci_model.generate_service_key(body['service'],
                                                          expiration_date,
                                                          metadata=metadata,
                                                          name=key_name)
            # Auto-approve the service key.
            pre_oci_model.approve_service_key(key_id,
                                              user,
                                              ServiceKeyApprovalType.SUPERUSER,
                                              notes=body.get('notes', ''))

            # Log the creation and auto-approval of the service key.
            key_log_metadata = {
                'kid': key_id,
                'preshared': True,
                'service': body['service'],
                'name': key_name,
                'expiration_date': expiration_date,
                'auto_approved': True,
            }

            log_action('service_key_create', None, key_log_metadata)
            log_action('service_key_approve', None, key_log_metadata)

            return jsonify({
                'kid':
                key_id,
                'name':
                key_name,
                'service':
                body['service'],
                'public_key':
                private_key.publickey().exportKey('PEM'),
                'private_key':
                private_key.exportKey('PEM'),
            })

        raise Unauthorized()