diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb index 952081a349f..32c0fc6d14a 100644 --- a/app/controllers/projects/registry/repositories_controller.rb +++ b/app/controllers/projects/registry/repositories_controller.rb @@ -10,31 +10,9 @@ module Projects respond_to do |format| format.html format.json do - # Remove code below - render json: [ - { - name: 'gitlab-org/omnibus-gitlab/foo', - tags_path: 'foo', - destroy_path: 'bar', - location: 'foo', - id: '134', - destroy_path: 'bar' - }, - { - name: 'gitlab-org/omnibus-gitlab', - tags_path: 'foo', - destroy_path: 'bar', - location: 'foo', - id: '123', - }, - { - name: 'gitlab-org/omnibus-gitlab/bar', - tags_path: 'foo', - destroy_path: 'bar', - location: 'foo', - id: '973', - } - ] + render json: ContainerRepositoriesSerializer + .new(project: project, current_user: current_user) + .represent(@images) end end end @@ -42,25 +20,11 @@ module Projects def destroy if image.destroy respond_to do |format| - # TODO: @Kamil, I don't think this is used ever. Should we keep it or remove it? - format.html do - redirect_to project_container_registry_index_path(@project), - status: 302, - notice: 'Image repository has been removed successfully!' - end - format.json { head :no_content } end else respond_to do |format| - # TODO: @Kamil, I don't think this is used ever. Should we keep it or remove it? - format.html do - redirect_to project_container_registry_index_path(@project), - status: 302, - alert: 'Failed to remove image repository!' - end - - format.json { head :no_content } + format.json { head :bad_request } end end end diff --git a/app/controllers/projects/registry/tags_controller.rb b/app/controllers/projects/registry/tags_controller.rb index ae72bd03cfb..e32c5528ee7 100644 --- a/app/controllers/projects/registry/tags_controller.rb +++ b/app/controllers/projects/registry/tags_controller.rb @@ -3,20 +3,35 @@ module Projects class TagsController < ::Projects::Registry::ApplicationController before_action :authorize_update_container_image!, only: [:destroy] + def index + respond_to do |format| + format.json do + render json: ContainerTagsSerializer + .new(project: @project, current_user: @current_user) + .with_pagination(request, response) + .represent(tags) + end + end + end + def destroy - if tag.delete - redirect_to project_container_registry_index_path(@project), - status: 302, - notice: 'Registry tag has been removed successfully!' - else - redirect_to project_container_registry_index_path(@project), - status: 302, - alert: 'Failed to remove registry tag!' + respond_to do |format| + format.json do + if tag.delete + format.json { head :no_content } + else + format.json { head :bad_request } + end + end end end private + def tags + Kaminari::PaginatableArray.new(image.tags, limit: 15) + end + def image @image ||= project.container_repositories .find(params[:repository_id]) diff --git a/app/serializers/container_repositories_serializer.rb b/app/serializers/container_repositories_serializer.rb new file mode 100644 index 00000000000..56dc70b5687 --- /dev/null +++ b/app/serializers/container_repositories_serializer.rb @@ -0,0 +1,3 @@ +class ContainerRepositoriesSerializer < BaseSerializer + entity ContainerRepositoryEntity +end diff --git a/app/serializers/container_repository_entity.rb b/app/serializers/container_repository_entity.rb new file mode 100644 index 00000000000..1103cf30a07 --- /dev/null +++ b/app/serializers/container_repository_entity.rb @@ -0,0 +1,25 @@ +class ContainerRepositoryEntity < Grape::Entity + include RequestAwareEntity + + expose :id, :path, :location + + expose :tags_path do |repository| + project_registry_repository_tags_path(project, repository, format: :json) + end + + expose :destroy_path, if: -> (*) { can_destroy? } do |repository| + project_container_registry_path(project, repository, format: :json) + end + + private + + alias_method :repository, :object + + def project + request.project + end + + def can_destroy? + can?(request.current_user, :update_container_image, project) + end +end diff --git a/app/serializers/container_tag_entity.rb b/app/serializers/container_tag_entity.rb new file mode 100644 index 00000000000..ec1fc349586 --- /dev/null +++ b/app/serializers/container_tag_entity.rb @@ -0,0 +1,23 @@ +class ContainerTagEntity < Grape::Entity + include RequestAwareEntity + + expose :name, :location, :revision, :total_size, :created_at + + expose :destroy_path, if: -> (*) { can_destroy? } do |tag| + project_registry_repository_tag_path(project, tag.repository, tag.name, format: :json) + end + + private + + alias_method :tag, :object + + def project + request.project + end + + def can_destroy? + # TODO: We check permission against @project, not tag, + # as tag is no AR object that is attached to project + can?(request.current_user, :update_container_image, project) + end +end diff --git a/app/serializers/container_tags_serializer.rb b/app/serializers/container_tags_serializer.rb new file mode 100644 index 00000000000..6ff3adff135 --- /dev/null +++ b/app/serializers/container_tags_serializer.rb @@ -0,0 +1,17 @@ +class ContainerTagsSerializer < BaseSerializer + entity ContainerTagEntity + + def with_pagination(request, response) + tap { @paginator = Gitlab::Serializer::Pagination.new(request, response) } + end + + def paginated? + @paginator.present? + end + + def represent(resource, opts = {}) + resource = @paginator.paginate(resource) if paginated? + + super(resource, opts) + end +end diff --git a/config/routes/project.rb b/config/routes/project.rb index b36d13888cd..70d7673250c 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -271,7 +271,7 @@ constraints(ProjectUrlConstrainer.new) do namespace :registry do resources :repository, only: [] do - resources :tags, only: [:destroy], + resources :tags, only: [:index, :destroy], constraints: { id: Gitlab::Regex.container_registry_tag_regex } end end