コード例 #1
0
ファイル: manifest.py プロジェクト: BillDett/quay
    def delete(self, namespace_name, repository_name, manifestref, labelid):
        """
        Deletes an existing label from a manifest.
        """
        repo_ref = registry_model.lookup_repository(namespace_name, repository_name)
        if repo_ref is None:
            raise NotFound()

        manifest = registry_model.lookup_manifest_by_digest(repo_ref, manifestref)
        if manifest is None:
            raise NotFound()

        deleted = registry_model.delete_manifest_label(manifest, labelid)
        if deleted is None:
            raise NotFound()

        metadata = {
            "id": labelid,
            "key": deleted.key,
            "value": deleted.value,
            "manifest_digest": manifestref,
            "namespace": namespace_name,
            "repo": repository_name,
        }

        log_action("manifest_label_delete", namespace_name, metadata, repo_name=repository_name)
        return "", 204
コード例 #2
0
    def put(self, orgname, prototypeid):
        """
        Update the role of an existing permission prototype.
        """
        permission = AdministerOrganizationPermission(orgname)
        if permission.can():
            try:
                org = model.organization.get_organization(orgname)
            except model.InvalidOrganizationException:
                raise NotFound()

            existing = model.permission.get_prototype_permission(
                org, prototypeid)
            if not existing:
                raise NotFound()

            details = request.get_json()
            role_name = details["role"]
            prototype = model.permission.update_prototype_permission(
                org, prototypeid, role_name)
            if not prototype:
                raise NotFound()

            log_prototype_action("modify_prototype_permission",
                                 orgname,
                                 prototype,
                                 original_role=existing.role.name)

            users_filter = {prototype.activating_user, prototype.delegate_user}
            org_members = model.organization.get_organization_member_set(
                org, users_filter=users_filter)
            return prototype_view(prototype, org_members)

        raise Unauthorized()
コード例 #3
0
    def delete(self, orgname, teamname, email):
        """
        Delete an invite of an email address to join a team.
        """
        permission = AdministerOrganizationPermission(orgname)
        if permission.can():
            team = None

            # Find the team.
            try:
                team = model.team.get_organization_team(orgname, teamname)
            except model.InvalidTeamException:
                raise NotFound()

            # Delete the invite.
            if not model.team.delete_team_email_invite(team, email):
                raise NotFound()

            log_action(
                "org_delete_team_member_invite",
                orgname,
                {
                    "email": email,
                    "team": teamname,
                    "member": email
                },
            )
            return "", 204

        raise Unauthorized()
コード例 #4
0
ファイル: tag.py プロジェクト: zhangli19817/quay
    def get(self, namespace, repository, tag, parsed_args):
        """
        List the images for the specified repository tag.
        """
        repo_ref = registry_model.lookup_repository(namespace, repository)
        if repo_ref is None:
            raise NotFound()

        tag_ref = registry_model.get_repo_tag(repo_ref,
                                              tag,
                                              include_legacy_image=True)
        if tag_ref is None:
            raise NotFound()

        if tag_ref.legacy_image_if_present is None:
            return {"images": []}

        image_id = tag_ref.legacy_image.docker_image_id

        all_images = None
        if parsed_args["owned"]:
            # TODO: Remove the `owned` image concept once we are fully on V2_2.
            all_images = registry_model.get_legacy_images_owned_by_tag(tag_ref)
        else:
            image_with_parents = registry_model.get_legacy_image(
                repo_ref, image_id, include_parents=True)
            if image_with_parents is None:
                raise NotFound()

            all_images = [image_with_parents] + image_with_parents.parents

        return {
            "images": [image_dict(image) for image in all_images],
        }
コード例 #5
0
    def put(self, orgname, client_id):
        """ Updates an application under this organization. """
        permission = AdministerOrganizationPermission(orgname)
        if permission.can():
            try:
                org = model.organization.get_organization(orgname)
            except model.InvalidOrganizationException:
                raise NotFound()

            application = model.oauth.lookup_application(org, client_id)
            if not application:
                raise NotFound()

            app_data = request.get_json()
            application.name = app_data['name']
            application.application_uri = app_data['application_uri']
            application.redirect_uri = app_data['redirect_uri']
            application.description = app_data.get('description', '')
            application.avatar_email = app_data.get('avatar_email', None)
            application.save()

            app_data.update({
                'application_name': application.name,
                'client_id': application.client_id
            })

            log_action('update_application', orgname, app_data)

            return app_view(application)
        raise Unauthorized()
コード例 #6
0
ファイル: organization.py プロジェクト: wjjmjh/quay
    def post(self, orgname, client_id):
        """
        Resets the client secret of the application.
        """
        permission = AdministerOrganizationPermission(orgname)
        if permission.can():
            try:
                org = model.organization.get_organization(orgname)
            except model.InvalidOrganizationException:
                raise NotFound()

            application = model.oauth.lookup_application(org, client_id)
            if not application:
                raise NotFound()

            application = model.oauth.reset_client_secret(application)
            log_action(
                "reset_application_client_secret",
                orgname,
                {
                    "application_name": application.name,
                    "client_id": client_id
                },
            )

            return app_view(application)
        raise Unauthorized()
コード例 #7
0
ファイル: organization.py プロジェクト: wjjmjh/quay
    def delete(self, orgname, client_id):
        """
        Deletes the application under this organization.
        """
        permission = AdministerOrganizationPermission(orgname)
        if permission.can():
            try:
                org = model.organization.get_organization(orgname)
            except model.InvalidOrganizationException:
                raise NotFound()

            application = model.oauth.delete_application(org, client_id)
            if not application:
                raise NotFound()

            log_action(
                "delete_application",
                orgname,
                {
                    "application_name": application.name,
                    "client_id": client_id
                },
            )

            return "", 204
        raise Unauthorized()
コード例 #8
0
ファイル: trigger.py プロジェクト: zhill/quay
    def post(self, namespace_name, repo_name, trigger_uuid):
        """ Analyze the specified build trigger configuration. """
        trigger = get_trigger(trigger_uuid)

        if trigger.repository.namespace_user.username != namespace_name:
            raise NotFound()

        if trigger.repository.name != repo_name:
            raise NotFound()

        new_config_dict = request.get_json()["config"]
        handler = BuildTriggerHandler.get_handler(trigger, new_config_dict)
        server_hostname = app.config["SERVER_HOSTNAME"]
        try:
            trigger_analyzer = TriggerAnalyzer(
                handler,
                namespace_name,
                server_hostname,
                new_config_dict,
                AdministerOrganizationPermission(namespace_name).can(),
            )
            return trigger_analyzer.analyze_trigger()
        except TriggerException as rre:
            return {
                "status": "error",
                "message":
                "Could not analyze the repository: %s" % rre.message,
            }
        except NotImplementedError:
            return {
                "status": "notimplemented",
            }
コード例 #9
0
  def get(self, namespace_name, repository_name):
    """ Return the Mirror configuration for a given Repository. """
    repo = model.repository.get_repository(namespace_name, repository_name)
    if not repo:
      raise NotFound()

    mirror = model.repo_mirror.get_mirror(repo)
    if not mirror:
      raise NotFound()

    # Transformations
    rules = mirror.root_rule.rule_value
    username = self._decrypt_username(mirror.external_registry_username)
    sync_start_date = self._dt_to_string(mirror.sync_start_date)
    sync_expiration_date = self._dt_to_string(mirror.sync_expiration_date)
    robot = mirror.internal_robot.username if mirror.internal_robot is not None else None

    return {
      'is_enabled': mirror.is_enabled,
      'mirror_type': mirror.mirror_type.name,
      'external_reference': mirror.external_reference,
      'external_registry_username': username,
      'external_registry_config': mirror.external_registry_config or {},
      'sync_interval': mirror.sync_interval,
      'sync_start_date': sync_start_date,
      'sync_expiration_date': sync_expiration_date,
      'sync_retries_remaining': mirror.sync_retries_remaining,
      'sync_status': mirror.sync_status.name,
      'root_rule': {
        'rule_kind': 'tag_glob_csv',
        'rule_value': rules
      },
      'robot_username': robot,
    }
コード例 #10
0
ファイル: manifest.py プロジェクト: xzwupeng/quay
    def post(self, namespace_name, repository_name, manifestref):
        """ Adds a new label into the tag manifest. """
        label_data = request.get_json()

        # Check for any reserved prefixes.
        if label_validator.has_reserved_prefix(label_data['key']):
            abort(400, message='Label has a reserved prefix')

        repo_ref = registry_model.lookup_repository(namespace_name,
                                                    repository_name)
        if repo_ref is None:
            raise NotFound()

        manifest = registry_model.lookup_manifest_by_digest(
            repo_ref, manifestref)
        if manifest is None:
            raise NotFound()

        label = None
        try:
            label = registry_model.create_manifest_label(
                manifest, label_data['key'], label_data['value'], 'api',
                label_data['media_type'])
        except InvalidLabelKeyException:
            message = ('Label is of an invalid format or missing please ' +
                       'use %s format for labels' % VALID_LABEL_KEY_REGEX)
            abort(400, message=message)
        except InvalidMediaTypeException:
            message = 'Media type is invalid please use a valid media type: text/plain, application/json'
            abort(400, message=message)

        if label is None:
            raise NotFound()

        metadata = {
            'id': label.uuid,
            'key': label.key,
            'value': label.value,
            'manifest_digest': manifestref,
            'media_type': label.media_type_name,
            'namespace': namespace_name,
            'repo': repository_name,
        }

        log_action('manifest_label_add',
                   namespace_name,
                   metadata,
                   repo_name=repository_name)

        resp = {'label': _label_dict(label)}
        repo_string = '%s/%s' % (namespace_name, repository_name)
        headers = {
            'Location':
            api.url_for(ManageRepositoryManifestLabel,
                        repository=repo_string,
                        manifestref=manifestref,
                        labelid=label.uuid),
        }
        return resp, 201, headers
コード例 #11
0
ファイル: manifest.py プロジェクト: BillDett/quay
    def get(self, namespace_name, repository_name, manifestref):
        repo_ref = registry_model.lookup_repository(namespace_name, repository_name)
        if repo_ref is None:
            raise NotFound()

        manifest = registry_model.lookup_manifest_by_digest(repo_ref, manifestref)
        if manifest is None:
            raise NotFound()

        return _manifest_dict(manifest)
コード例 #12
0
ファイル: secscan.py プロジェクト: syed/quay
    def get(self, namespace, repository, manifestref, parsed_args):
        repo_ref = registry_model.lookup_repository(namespace, repository)
        if repo_ref is None:
            raise NotFound()

        manifest = registry_model.lookup_manifest_by_digest(repo_ref, manifestref, allow_dead=True)
        if manifest is None:
            raise NotFound()

        return _security_info(manifest, parsed_args.vulnerabilities)
コード例 #13
0
    def get(self, namespace, repository, imageid, parsed_args):
        """ Fetches the features and vulnerabilities (if any) for a repository image. """
        repo_ref = registry_model.lookup_repository(namespace, repository)
        if repo_ref is None:
            raise NotFound()

        legacy_image = registry_model.get_legacy_image(repo_ref, imageid)
        if legacy_image is None:
            raise NotFound()

        return _security_info(legacy_image, parsed_args.vulnerabilities)
コード例 #14
0
ファイル: build.py プロジェクト: xzwupeng/quay
    def get(self, namespace, repository, build_uuid):
        """ Returns information about a build. """
        try:
            build = model.build.get_repository_build(build_uuid)
        except model.build.InvalidRepositoryBuildException:
            raise NotFound()

        if build.repository.name != repository or build.repository.namespace_user.username != namespace:
            raise NotFound()

        return build_status_view(build)
コード例 #15
0
    def get(self, orgname, membername):
        """
        Retrieves the details of a member of the organization.
        """
        permission = AdministerOrganizationPermission(orgname)
        if permission.can():
            # Lookup the user.
            member = model.user.get_user(membername)
            if not member:
                raise NotFound()

            organization = model.user.get_user_or_org(orgname)
            if not organization:
                raise NotFound()

            # Lookup the user's information in the organization.
            teams = list(
                model.team.get_user_teams_within_org(membername, organization))
            if not teams:
                # 404 if the user is not a robot under the organization, as that means the referenced
                # user or robot is not a member of this organization.
                if not member.robot:
                    raise NotFound()

                namespace, _ = parse_robot_username(member.username)
                if namespace != orgname:
                    raise NotFound()

            repo_permissions = model.permission.list_organization_member_permissions(
                organization, member)

            def local_team_view(team):
                return {
                    "name": team.name,
                    "avatar": avatar.get_data_for_team(team),
                }

            return {
                "name":
                member.username,
                "kind":
                "robot" if member.robot else "user",
                "avatar":
                avatar.get_data_for_user(member),
                "teams": [local_team_view(team) for team in teams],
                "repositories": [
                    permission.repository.name
                    for permission in repo_permissions
                ],
            }

        raise Unauthorized()
コード例 #16
0
    def post(self, namespace, repository, tag):
        """
        Restores a repository tag back to a previous image in the repository.
        """
        repo_ref = registry_model.lookup_repository(namespace, repository)
        if repo_ref is None:
            raise NotFound()

        # Restore the tag back to the previous image.
        image_id = request.get_json().get("image", None)
        manifest_digest = request.get_json().get("manifest_digest", None)

        if image_id is None and manifest_digest is None:
            raise InvalidRequest("Missing manifest_digest")

        # Data for logging the reversion/restoration.
        username = get_authenticated_user().username
        log_data = {
            "username": username,
            "repo": repository,
            "tag": tag,
            "image": image_id,
            "manifest_digest": manifest_digest,
        }

        manifest_or_legacy_image = None
        if manifest_digest is not None:
            manifest_or_legacy_image = registry_model.lookup_manifest_by_digest(
                repo_ref,
                manifest_digest,
                allow_dead=True,
                require_available=True)
        elif image_id is not None:
            manifest_or_legacy_image = registry_model.get_legacy_image(
                repo_ref, image_id)

        if manifest_or_legacy_image is None:
            raise NotFound()

        if not registry_model.retarget_tag(
                repo_ref,
                tag,
                manifest_or_legacy_image,
                storage,
                docker_v2_signing_key,
                is_reversion=True,
        ):
            raise InvalidRequest("Could not restore tag")

        log_action("revert_tag", namespace, log_data, repo_name=repository)

        return {}
コード例 #17
0
    def get(self, namespace, repository, image_id):
        """
        Get the information available for the specified image.
        """
        repo_ref = registry_model.lookup_repository(namespace, repository)
        if repo_ref is None:
            raise NotFound()

        image = registry_model.get_legacy_image(repo_ref, image_id, storage)
        if image is None:
            raise NotFound()

        return image_dict(image)
コード例 #18
0
    def get(self, namespace_name, repository_name, manifestref):
        repo_ref = registry_model.lookup_repository(namespace_name, repository_name)
        if repo_ref is None:
            raise NotFound()

        manifest = registry_model.lookup_manifest_by_digest(repo_ref, manifestref)
        # sub-manifests created via pull-thru proxy cache as part of a manifest list
        # pull will not contain the manifest bytes unless individually pulled.
        # to avoid a parsing error from `_manifest_dict`, we return a 404 either
        # when the manifest doesn't exist or if the manifest bytes are empty.
        if manifest is None or manifest.internal_manifest_bytes.as_unicode() == "":
            raise NotFound()

        return _manifest_dict(manifest)
コード例 #19
0
    def get(self, namespace_name, repository_name, manifestref, parsed_args):
        repo_ref = registry_model.lookup_repository(namespace_name, repository_name)
        if repo_ref is None:
            raise NotFound()

        manifest = registry_model.lookup_manifest_by_digest(repo_ref, manifestref)
        if manifest is None:
            raise NotFound()

        labels = registry_model.list_manifest_labels(manifest, parsed_args["filter"])
        if labels is None:
            raise NotFound()

        return {"labels": [_label_dict(label) for label in labels]}
コード例 #20
0
ファイル: build.py プロジェクト: xzwupeng/quay
    def delete(self, namespace, repository, build_uuid):
        """ Cancels a repository build. """
        try:
            build = model.build.get_repository_build(build_uuid)
        except model.build.InvalidRepositoryBuildException:
            raise NotFound()

        if build.repository.name != repository or build.repository.namespace_user.username != namespace:
            raise NotFound()

        if model.build.cancel_repository_build(build, dockerfile_build_queue):
            return 'Okay', 201
        else:
            raise InvalidRequest('Build is currently running or has finished')
コード例 #21
0
  def post(self, namespace_name, repository_name):
    """ Update the sync_status for a given Repository's mirroring configuration. """
    repo = model.repository.get_repository(namespace_name, repository_name)
    if not repo:
      raise NotFound()

    mirror = model.repo_mirror.get_mirror(repository=repo)
    if not mirror:
      raise NotFound()

    if mirror and model.repo_mirror.update_sync_status_to_cancel(mirror):
      track_and_log('repo_mirror_config_changed', wrap_repository(repo), changed="sync_status", to="SYNC_CANCEL")
      return '', 204

    raise NotFound()
コード例 #22
0
    def post(self, namespace, repository):
        """
        Change the visibility of a repository.
        """
        if not model.repo_exists(namespace, repository):
            raise NotFound()

        tags, _ = tuf_metadata_api.get_default_tags_with_expiration(
            namespace, repository)
        if tags and not tuf_metadata_api.delete_metadata(
                namespace, repository):
            raise DownstreamIssue("Unable to delete downstream trust metadata")

        values = request.get_json()
        model.set_trust(namespace, repository, values["trust_enabled"])

        log_action(
            "change_repo_trust",
            namespace,
            {
                "repo": repository,
                "namespace": namespace,
                "trust_enabled": values["trust_enabled"]
            },
            repo_name=repository,
        )

        return {"success": True}
コード例 #23
0
ファイル: team.py プロジェクト: ynnt/quay
    def put(self, orgname, teamname, email):
        """
        Invites an email address to an existing team.
        """
        permission = AdministerOrganizationPermission(orgname)
        if permission.can():
            team = None

            # Find the team.
            try:
                team = model.team.get_organization_team(orgname, teamname)
            except model.InvalidTeamException:
                raise NotFound()

            # Invite the email to the team.
            inviter = get_authenticated_user()
            invite = handle_addinvite_team(inviter, team, email=email)
            log_action(
                "org_invite_team_member",
                orgname,
                {
                    "email": email,
                    "team": teamname,
                    "member": email
                },
            )
            return invite_view(invite)

        raise Unauthorized()
コード例 #24
0
ファイル: user.py プロジェクト: xzwupeng/quay
    def get(self, uuid):
        note = model.notification.lookup_notification(get_authenticated_user(),
                                                      uuid)
        if not note:
            raise NotFound()

        return notification_view(note)
コード例 #25
0
    def post(self, orgname):
        """
        Creates a new application under this organization.
        """
        permission = AdministerOrganizationPermission(orgname)
        if permission.can():
            try:
                org = model.organization.get_organization(orgname)
            except model.InvalidOrganizationException:
                raise NotFound()

            app_data = request.get_json()
            application = model.oauth.create_application(
                org,
                app_data["name"],
                app_data.get("application_uri", ""),
                app_data.get("redirect_uri", ""),
                description=app_data.get("description", ""),
                avatar_email=app_data.get("avatar_email", None),
            )

            app_data.update({
                "application_name": application.name,
                "client_id": application.client_id
            })

            log_action("create_application", orgname, app_data)

            return app_view(application)
        raise Unauthorized()
コード例 #26
0
ファイル: user.py プロジェクト: xzwupeng/quay
    def get(self, access_token_uuid):
        access_token = model.oauth.lookup_access_token_for_user(
            get_authenticated_user(), access_token_uuid)
        if not access_token:
            raise NotFound()

        return authorization_view(access_token)
コード例 #27
0
ファイル: repository.py プロジェクト: xzwupeng/quay
    def put(self, namespace, repository):
        """ Change the state of a repository. """
        if not model.repo_exists(namespace, repository):
            raise NotFound()

        values = request.get_json()
        state_name = values['state']

        try:
            state = RepositoryState[state_name]
        except KeyError:
            state = None

        if state == RepositoryState.MIRROR and not features.REPO_MIRROR:
            return {'detail': 'Unknown Repository State: %s' % state_name}, 400

        if state is None:
            return {
                'detail': '%s is not a valid Repository state.' % state_name
            }, 400

        model.set_repository_state(namespace, repository, state)

        log_action('change_repo_state',
                   namespace, {
                       'repo': repository,
                       'namespace': namespace,
                       'state_changed': state_name
                   },
                   repo_name=repository)

        return {'success': True}
コード例 #28
0
    def post(self, kid):
        notes = request.get_json().get("notes", "")
        try:
            key = pre_oci_model.approve_service_key(
                kid, 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,
            }

            # Note: this may not actually be the current person modifying the config, but if they're in the config tool,
            # they have full access to the DB and could pretend to be any user, so pulling any superuser is likely fine
            super_user = app.config.get("SUPER_USERS", [None])[0]
            log_action("service_key_approve", super_user, key_log_metadata)
        except ServiceKeyDoesNotExist:
            raise NotFound()
        except ServiceKeyAlreadyApproved:
            pass

        return make_response("", 201)
コード例 #29
0
    def get(self):
        """ List the invoices for the current user. """
        user = get_authenticated_user()
        if not user.stripe_id:
            raise NotFound()

        return get_invoices(user.stripe_id)
コード例 #30
0
    def get(self):
        """ List the invoice fields for the current user. """
        user = get_authenticated_user()
        if not user.stripe_id:
            raise NotFound()

        return {'fields': get_invoice_fields(user)[0]}