コード例 #1
0
    def post(self, kid):
        if SuperUserPermission().can():
            notes = request.get_json().get("notes", "")
            approver = get_authenticated_user()
            try:
                key = pre_oci_model.approve_service_key(
                    kid, approver, ServiceKeyApprovalType.SUPERUSER, notes=notes
                )

                # Log the approval of the service key.
                key_log_metadata = {
                    "kid": kid,
                    "service": key.service,
                    "name": key.name,
                    "expiration_date": key.expiration_date,
                }

                log_action("service_key_approve", None, key_log_metadata)
            except ServiceKeyDoesNotExist:
                raise NotFound()
            except ServiceKeyAlreadyApproved:
                pass

            return make_response("", 201)

        raise Unauthorized()
コード例 #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
ファイル: superuser.py プロジェクト: zhill/quay
    def delete(self, name):
        """ Deletes the specified organization. """
        if SuperUserPermission().can():
            pre_oci_model.mark_organization_for_deletion(name)
            return "", 204

        raise Unauthorized()
コード例 #4
0
ファイル: namespacequota.py プロジェクト: jonathankingfc/quay
    def post(self, orgname):
        """
        Create a new organization quota.
        """
        if not SuperUserPermission().can():
            raise Unauthorized()

        quota_data = request.get_json()
        limit_bytes = quota_data["limit_bytes"]

        try:
            org = model.organization.get_organization(orgname)
        except model.InvalidOrganizationException:
            raise NotFound()

        # Currently only supporting one quota definition per namespace
        quotas = model.namespacequota.get_namespace_quota_list(orgname)
        if quotas:
            raise request_error(
                message="Organization quota for '%s' already exists" % orgname)

        try:
            model.namespacequota.create_namespace_quota(org, limit_bytes)
            return "Created", 201
        except model.DataModelException as ex:
            raise request_error(exception=ex)
コード例 #5
0
ファイル: superuser.py プロジェクト: jonathankingfc/quay
    def get(self, parsed_args, page_token):
        """
        List the usage logs for the current system.
        """
        if SuperUserPermission().can():
            start_time = parsed_args["starttime"]
            end_time = parsed_args["endtime"]

            (start_time,
             end_time) = _validate_logs_arguments(start_time, end_time)
            log_entry_page = logs_model.lookup_logs(start_time,
                                                    end_time,
                                                    page_token=page_token)
            return (
                {
                    "start_time":
                    format_date(start_time),
                    "end_time":
                    format_date(end_time),
                    "logs": [
                        log.to_dict(avatar, include_namespace=True)
                        for log in log_entry_page.logs
                    ],
                },
                log_entry_page.next_page_token,
            )

        raise Unauthorized()
コード例 #6
0
ファイル: superuser.py プロジェクト: zhill/quay
    def get(self):
        """ Returns the change log for this installation. """
        if SuperUserPermission().can():
            with open(os.path.join(ROOT_DIR, "CHANGELOG.md"), "r") as f:
                return {"log": f.read()}

        raise Unauthorized()
コード例 #7
0
ファイル: superuser.py プロジェクト: zhill/quay
    def get(self, parsed_args):
        """ Returns a list of all users in the system. """
        if SuperUserPermission().can():
            users = pre_oci_model.get_active_users(disabled=parsed_args["disabled"])
            return {"users": [user.to_dict() for user in users]}

        raise Unauthorized()
コード例 #8
0
def _syncing_setup_allowed(orgname):
    """ Returns whether syncing setup is allowed for the current user over the matching org. """
    if not features.NONSUPERUSER_TEAM_SYNCING_SETUP and not SuperUserPermission(
    ).can():
        return False

    return AdministerOrganizationPermission(orgname).can()
コード例 #9
0
ファイル: globalmessages.py プロジェクト: zhill/quay
    def delete(self, uuid):
        """ Delete a message """
        if SuperUserPermission().can():
            model.delete_message(uuid)
            return make_response("", 204)

        abort(403)
コード例 #10
0
ファイル: namespacequota.py プロジェクト: jonathankingfc/quay
    def post(self, orgname, quota_id):
        if not SuperUserPermission().can():
            raise Unauthorized()

        quota_limit_data = request.get_json()
        quota_type = quota_limit_data["type"]
        quota_limit_threshold = quota_limit_data["threshold_percent"]

        quota = get_quota(orgname, quota_id)

        quota_limit = model.namespacequota.get_namespace_quota_limit_list(
            quota,
            quota_type=quota_type,
            percent_of_limit=quota_limit_threshold,
        )

        if quota_limit:
            msg = "Quota limit already exists"
            raise request_error(message=msg)

        if quota_limit_data["type"].lower() == "reject" and quota_limit:
            raise request_error(
                message="Only one quota limit of type 'Reject' allowed.")

        try:
            model.namespacequota.create_namespace_quota_limit(
                quota,
                quota_type,
                quota_limit_threshold,
            )
            return "Created", 201
        except model.DataModelException as ex:
            raise request_error(exception=ex)
コード例 #11
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()
コード例 #12
0
    def get(self):
        if SuperUserPermission().can():
            keys = pre_oci_model.list_all_service_keys()

            return jsonify({"keys": [key.to_dict() for key in keys],})

        raise Unauthorized()
コード例 #13
0
ファイル: superuser.py プロジェクト: zhill/quay
    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()
コード例 #14
0
    def get(self):
        """
        Returns a list of all organizations in the system.
        """
        if SuperUserPermission().can():
            return {"organizations": [org.to_dict() for org in pre_oci_model.get_organizations()]}

        raise Unauthorized()
コード例 #15
0
ファイル: namespacequota.py プロジェクト: jonathankingfc/quay
    def get(self, orgname, quota_id):
        orgperm = OrganizationMemberPermission(orgname)
        if not orgperm.can() and not SuperUserPermission().can():
            raise Unauthorized()

        quota = get_quota(orgname, quota_id)

        return quota_view(quota)
コード例 #16
0
    def get(self, kid):
        if SuperUserPermission().can():
            try:
                key = pre_oci_model.get_service_key(kid, approved_only=False, alive_only=False)
                return jsonify(key.to_dict())
            except ServiceKeyDoesNotExist:
                raise NotFound()

        raise Unauthorized()
コード例 #17
0
ファイル: superuser.py プロジェクト: zhill/quay
    def put(self, name):
        """ Updates information about the specified user. """
        if SuperUserPermission().can():
            org_data = request.get_json()
            old_name = org_data["name"] if "name" in org_data else None
            org = pre_oci_model.change_organization_name(name, old_name)
            return org.to_dict()

        raise Unauthorized()
コード例 #18
0
ファイル: team.py プロジェクト: ynnt/quay
    def get(self, orgname, teamname, parsed_args):
        """
        Retrieve the list of members for the specified team.
        """
        view_permission = ViewTeamPermission(orgname, teamname)
        edit_permission = AdministerOrganizationPermission(orgname)

        if view_permission.can():
            team = None
            try:
                team = model.team.get_organization_team(orgname, teamname)
            except model.InvalidTeamException:
                raise NotFound()

            members = model.organization.get_organization_team_members(team.id)
            invites = []

            if parsed_args["includePending"] and edit_permission.can():
                invites = model.team.get_organization_team_member_invites(
                    team.id)

            data = {
                "name":
                teamname,
                "members":
                [member_view(m)
                 for m in members] + [invite_view(i) for i in invites],
                "can_edit":
                edit_permission.can(),
            }

            if features.TEAM_SYNCING and authentication.federated_service:
                if _syncing_setup_allowed(orgname):
                    data["can_sync"] = {
                        "service": authentication.federated_service,
                    }

                    data["can_sync"].update(authentication.service_metadata())

                sync_info = model.team.get_team_sync_information(
                    orgname, teamname)
                if sync_info is not None:
                    data["synced"] = {
                        "service": sync_info.service.name,
                    }

                    if SuperUserPermission().can():
                        data["synced"].update({
                            "last_updated":
                            format_date(sync_info.last_updated),
                            "config":
                            json.loads(sync_info.config),
                        })

            return data

        raise Unauthorized()
コード例 #19
0
ファイル: superuser.py プロジェクト: jonathankingfc/quay
    def delete(self, namespace, quota_id):
        if SuperUserPermission().can():
            namespace_user = user.get_user_or_org(namespace)
            quota = get_quota(namespace_user.username, quota_id)
            namespacequota.delete_namespace_quota(quota)

            return "", 204

        raise Unauthorized()
コード例 #20
0
ファイル: namespacequota.py プロジェクト: jonathankingfc/quay
    def delete(self, orgname, quota_id):
        if not SuperUserPermission().can():
            raise Unauthorized()

        quota = get_quota(orgname, quota_id)

        # Exceptions by`delete_instance` are unexpected and raised
        model.namespacequota.delete_namespace_quota(quota)

        return "", 204
コード例 #21
0
ファイル: superuser.py プロジェクト: zhill/quay
    def get(self, build_uuid):
        """ Return the status for the builds specified by the build uuids. """
        if SuperUserPermission().can():
            try:
                build = pre_oci_model.get_repository_build(build_uuid)
            except InvalidRepositoryBuildException as e:
                raise InvalidResponse(str(e))
            return build.to_dict()

        raise Unauthorized()
コード例 #22
0
ファイル: superuser.py プロジェクト: zhill/quay
    def get(self, username):
        """ Returns information about the specified user. """
        if SuperUserPermission().can():
            user = pre_oci_model.get_nonrobot_user(username)
            if user is None:
                raise NotFound()

            return user.to_dict()

        raise Unauthorized()
コード例 #23
0
ファイル: superuser.py プロジェクト: zhill/quay
    def get(self, build_uuid):
        """ Return the build logs for the build specified by the build uuid. """
        if SuperUserPermission().can():
            try:
                repo_build = pre_oci_model.get_repository_build(build_uuid)
                return get_logs_or_log_url(repo_build)
            except InvalidRepositoryBuildException as e:
                raise InvalidResponse(str(e))

        raise Unauthorized()
コード例 #24
0
ファイル: superuser.py プロジェクト: zhill/quay
    def get(self, parsed_args):
        """ Returns the aggregated logs for the current system. """
        if SuperUserPermission().can():
            (start_time, end_time) = _validate_logs_arguments(
                parsed_args["starttime"], parsed_args["endtime"]
            )
            aggregated_logs = logs_model.get_aggregated_log_counts(start_time, end_time)
            return {"aggregated": [log.to_dict() for log in aggregated_logs]}

        raise Unauthorized()
コード例 #25
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()
コード例 #26
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()
コード例 #27
0
ファイル: superuser.py プロジェクト: jonathankingfc/quay
    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()
コード例 #28
0
ファイル: superuser.py プロジェクト: zhill/quay
    def get(self, build_uuid):
        """ Returns information about a build. """
        if SuperUserPermission().can():
            try:
                build = pre_oci_model.get_repository_build(build_uuid)
            except InvalidRepositoryBuildException:
                raise NotFound()

            return build.to_dict()

        raise Unauthorized()
コード例 #29
0
    def calculate_overall_health(self,
                                 service_statuses,
                                 skip=None,
                                 notes=None):
        """
        Returns true if and only if all the given service statuses report as healthy.
        """
        is_healthy = True
        notes = notes or []

        service_statuses_bools = {}
        service_status_expanded = {}

        for service_name in service_statuses:
            status, message = service_statuses[service_name]

            service_statuses_bools[service_name] = status
            service_status_expanded[service_name] = {
                "status": status,
            }

            if not status:
                service_status_expanded[service_name]["failure"] = message
            elif message:
                service_status_expanded[service_name]["message"] = message

            if skip and service_name in skip:
                notes.append("%s skipped in compute health" % service_name)
                continue

            is_healthy = is_healthy and status

        data = {
            "services": service_statuses_bools,
        }

        expanded_data = {
            "services_expanded": service_status_expanded,
            "notes": notes,
            "is_testing": self.app.config["TESTING"],
            "config_provider": self.config_provider.provider_id,
            "local_service_key_id": self.instance_keys.local_key_id,
            "hostname": socket.gethostname(),
        }

        add_debug_information = SuperUserPermission().can() or session.get(
            "health_debug", False)
        if add_debug_information:
            data.update(expanded_data)

        if not is_healthy:
            logger.warning("[FAILED HEALTH CHECK] %s", expanded_data)

        return (data, 200 if is_healthy else 503)
コード例 #30
0
    def calculate_overall_health(self,
                                 service_statuses,
                                 skip=None,
                                 notes=None):
        """ Returns true if and only if all the given service statuses report as healthy. """
        is_healthy = True
        notes = notes or []

        service_statuses_bools = {}
        service_status_expanded = {}

        for service_name in service_statuses:
            status, message = service_statuses[service_name]

            service_statuses_bools[service_name] = status
            service_status_expanded[service_name] = {
                'status': status,
            }

            if not status:
                service_status_expanded[service_name]['failure'] = message
            elif message:
                service_status_expanded[service_name]['message'] = message

            if skip and service_name in skip:
                notes.append('%s skipped in compute health' % service_name)
                continue

            is_healthy = is_healthy and status

        data = {
            'services': service_statuses_bools,
        }

        expanded_data = {
            'services_expanded': service_status_expanded,
            'notes': notes,
            'is_testing': self.app.config['TESTING'],
            'config_provider': self.config_provider.provider_id,
            'local_service_key_id': self.instance_keys.local_key_id,
            'hostname': socket.gethostname(),
        }

        add_debug_information = SuperUserPermission().can() or session.get(
            'health_debug', False)
        if add_debug_information:
            data.update(expanded_data)

        if not is_healthy:
            logger.warning('[FAILED HEALTH CHECK] %s', expanded_data)

        return (data, 200 if is_healthy else 503)