diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-23 12:08:38 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-23 12:08:38 +0000 |
commit | 5ad0cf26551baff8f08af8562a8d45e6ec14d71a (patch) | |
tree | 57f1a6bad31bcd11efacd3fdfb9cc92f88fb6a86 /app | |
parent | f47c768fad17d4c876e96524f83f8306f071db66 (diff) | |
download | gitlab-ce-5ad0cf26551baff8f08af8562a8d45e6ec14d71a.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
42 files changed, 246 insertions, 132 deletions
diff --git a/app/assets/javascripts/groups/components/group_folder.vue b/app/assets/javascripts/groups/components/group_folder.vue index e885b2b5f41..cf8c9bf74ec 100644 --- a/app/assets/javascripts/groups/components/group_folder.vue +++ b/app/assets/javascripts/groups/components/group_folder.vue @@ -44,7 +44,7 @@ export default { :action="action" /> <li v-if="hasMoreChildren" class="group-row"> - <a :href="parentGroup.relativePath" class="group-row-contents has-more-items"> + <a :href="parentGroup.relativePath" class="group-row-contents has-more-items py-2"> <i class="fa fa-external-link" aria-hidden="true"> </i> {{ moreChildrenStats }} </a> </li> diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue index ede74d18ed4..af9399a37bd 100644 --- a/app/assets/javascripts/groups/components/group_item.vue +++ b/app/assets/javascripts/groups/components/group_item.vue @@ -91,7 +91,7 @@ export default { <li :id="groupDomId" :class="rowClass" class="group-row" @click.stop="onClickRowGroup"> <div :class="{ 'project-row-contents': !isGroup }" - class="group-row-contents d-flex align-items-center" + class="group-row-contents d-flex align-items-center py-2" > <div class="folder-toggle-wrap append-right-4 d-flex align-items-center"> <item-caret :is-group-open="group.isOpen" /> @@ -104,7 +104,7 @@ export default { /> <div :class="{ 'd-sm-flex': !group.isChildrenLoading }" - class="avatar-container rect-avatar s40 d-none flex-grow-0 flex-shrink-0 " + class="avatar-container rect-avatar s32 d-none flex-grow-0 flex-shrink-0 " > <a :href="group.relativePath" class="no-expand"> <img v-if="hasAvatar" :src="group.avatarUrl" class="avatar s40" /> diff --git a/app/assets/javascripts/serverless/components/environment_row.vue b/app/assets/javascripts/serverless/components/environment_row.vue index 4d18c5c4bdd..089e0550583 100644 --- a/app/assets/javascripts/serverless/components/environment_row.vue +++ b/app/assets/javascripts/serverless/components/environment_row.vue @@ -47,7 +47,7 @@ export default { <template> <li :id="envId" :class="isOpenClass" class="group-row has-children"> <div - class="group-row-contents d-flex justify-content-end align-items-center" + class="group-row-contents d-flex justify-content-end align-items-center py-2" role="button" @click.stop="toggleOpen" > diff --git a/app/assets/javascripts/serverless/components/function_row.vue b/app/assets/javascripts/serverless/components/function_row.vue index 4b3bb078eae..dca0e01b250 100644 --- a/app/assets/javascripts/serverless/components/function_row.vue +++ b/app/assets/javascripts/serverless/components/function_row.vue @@ -63,7 +63,7 @@ export default { <template> <li :id="name" class="group-row"> - <div class="group-row-contents" role="button" @click="openDetails"> + <div class="group-row-contents py-2" role="button" @click="openDetails"> <p class="float-right text-right"> <span>{{ image }}</span ><br /> diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss index 1cf72c51ca7..3085f5e89b5 100644 --- a/app/assets/stylesheets/pages/groups.scss +++ b/app/assets/stylesheets/pages/groups.scss @@ -382,8 +382,6 @@ table.pipeline-project-metrics tr td { } .group-row-contents { - padding: $gl-padding; - &:hover { border-color: $blue-200; background-color: $blue-50; @@ -410,13 +408,7 @@ table.pipeline-project-metrics tr td { .title { margin-top: -$gl-padding-8; // negative margin required for flex-wrap - font-size: $gl-font-size-large; - } - - @include media-breakpoint-down(md) { - .title { - font-size: $gl-font-size; - } + font-size: $gl-font-size; } &.has-more-items { @@ -483,7 +475,6 @@ table.pipeline-project-metrics tr td { .last-updated { position: relative; - right: 12px; min-width: 250px; text-align: right; color: $gl-text-color-secondary; diff --git a/app/controllers/concerns/page_limiter.rb b/app/controllers/concerns/page_limiter.rb new file mode 100644 index 00000000000..5b078d80fca --- /dev/null +++ b/app/controllers/concerns/page_limiter.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +# Include this in your controller and call `limit_pages` in order +# to configure the limiter. +# +# Examples: +# class MyController < ApplicationController +# include PageLimiter +# +# before_action only: [:index] do +# limit_pages(500) +# end +# +# # You can override the default response +# rescue_from PageOutOfBoundsError, with: :page_out_of_bounds +# +# def page_out_of_bounds(error) +# # Page limit number is available as error.message +# head :ok +# end +# + +module PageLimiter + extend ActiveSupport::Concern + + PageLimiterError = Class.new(StandardError) + PageLimitNotANumberError = Class.new(PageLimiterError) + PageLimitNotSensibleError = Class.new(PageLimiterError) + PageOutOfBoundsError = Class.new(PageLimiterError) + + included do + rescue_from PageOutOfBoundsError, with: :default_page_out_of_bounds_response + end + + def limit_pages(max_page_number) + check_page_number!(max_page_number) + end + + private + + # If the page exceeds the defined maximum, raise a PageOutOfBoundsError + # If the page doesn't exceed the limit, it does nothing. + def check_page_number!(max_page_number) + raise PageLimitNotANumberError unless max_page_number.is_a?(Integer) + raise PageLimitNotSensibleError unless max_page_number > 0 + + if params[:page].present? && params[:page].to_i > max_page_number + record_page_limit_interception + raise PageOutOfBoundsError.new(max_page_number) + end + end + + # By default just return a HTTP status code and an empty response + def default_page_out_of_bounds_response + head :bad_request + end + + # Record the page limit being hit in Prometheus + def record_page_limit_interception + dd = DeviceDetector.new(request.user_agent) + + Gitlab::Metrics.counter(:gitlab_page_out_of_bounds, + controller: params[:controller], + action: params[:action], + bot: dd.bot? + ) + end +end diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb index 271f2b4b57d..a8a76b47bbe 100644 --- a/app/controllers/explore/projects_controller.rb +++ b/app/controllers/explore/projects_controller.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class Explore::ProjectsController < Explore::ApplicationController + include PageLimiter include ParamsBackwardCompatibility include RendersMemberAccess include SortingHelper @@ -9,6 +10,13 @@ class Explore::ProjectsController < Explore::ApplicationController before_action :set_non_archived_param before_action :set_sorting + # Limit taken from https://gitlab.com/gitlab-org/gitlab/issues/38357 + before_action only: [:index, :trending, :starred] do + limit_pages(200) + end + + rescue_from PageOutOfBoundsError, with: :page_out_of_bounds + def index @projects = load_projects @@ -53,10 +61,14 @@ class Explore::ProjectsController < Explore::ApplicationController private - # rubocop: disable CodeReuse/ActiveRecord - def load_projects + def load_project_counts @total_user_projects_count = ProjectsFinder.new(params: { non_public: true }, current_user: current_user).execute @total_starred_projects_count = ProjectsFinder.new(params: { starred: true }, current_user: current_user).execute + end + + # rubocop: disable CodeReuse/ActiveRecord + def load_projects + load_project_counts projects = ProjectsFinder.new(current_user: current_user, params: params) .execute @@ -80,4 +92,21 @@ class Explore::ProjectsController < Explore::ApplicationController def sorting_field Project::SORTING_PREFERENCE_FIELD end + + def page_out_of_bounds(error) + load_project_counts + @max_page_number = error.message + + respond_to do |format| + format.html do + render "page_out_of_bounds", status: :bad_request + end + + format.json do + render json: { + html: view_to_html_string("explore/projects/page_out_of_bounds") + }, status: :bad_request + end + end + end end diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index daddd9dd485..d7ae6d2cbb4 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -15,17 +15,17 @@ class Projects::SnippetsController < Projects::ApplicationController before_action :check_snippets_available! before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji, :mark_as_spam] - # Allow read any snippet - before_action :authorize_read_project_snippet!, except: [:new, :create, :index] + # Allow create snippet + before_action :authorize_create_snippet!, only: [:new, :create] - # Allow write(create) snippet - before_action :authorize_create_project_snippet!, only: [:new, :create] + # Allow read any snippet + before_action :authorize_read_snippet!, except: [:new, :create, :index] # Allow modify snippet - before_action :authorize_update_project_snippet!, only: [:edit, :update] + before_action :authorize_update_snippet!, only: [:edit, :update] # Allow destroy snippet - before_action :authorize_admin_project_snippet!, only: [:destroy] + before_action :authorize_admin_snippet!, only: [:destroy] respond_to :html @@ -115,16 +115,16 @@ class Projects::SnippetsController < Projects::ApplicationController project_snippet_path(@project, @snippet) end - def authorize_read_project_snippet! - return render_404 unless can?(current_user, :read_project_snippet, @snippet) + def authorize_read_snippet! + return render_404 unless can?(current_user, :read_snippet, @snippet) end - def authorize_update_project_snippet! - return render_404 unless can?(current_user, :update_project_snippet, @snippet) + def authorize_update_snippet! + return render_404 unless can?(current_user, :update_snippet, @snippet) end - def authorize_admin_project_snippet! - return render_404 unless can?(current_user, :admin_project_snippet, @snippet) + def authorize_admin_snippet! + return render_404 unless can?(current_user, :admin_snippet, @snippet) end def snippet_params diff --git a/app/controllers/snippets/notes_controller.rb b/app/controllers/snippets/notes_controller.rb index 551b37cb3d3..a7e8ef0798b 100644 --- a/app/controllers/snippets/notes_controller.rb +++ b/app/controllers/snippets/notes_controller.rb @@ -33,7 +33,7 @@ class Snippets::NotesController < ApplicationController end def authorize_read_snippet! - return render_404 unless can?(current_user, :read_personal_snippet, snippet) + return render_404 unless can?(current_user, :read_snippet, snippet) end def authorize_create_note! diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index fc073e47368..b6ad5fd02b0 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -126,7 +126,7 @@ class SnippetsController < ApplicationController end def authorize_read_snippet! - return if can?(current_user, :read_personal_snippet, @snippet) + return if can?(current_user, :read_snippet, @snippet) if current_user render_404 @@ -136,15 +136,15 @@ class SnippetsController < ApplicationController end def authorize_update_snippet! - return render_404 unless can?(current_user, :update_personal_snippet, @snippet) + return render_404 unless can?(current_user, :update_snippet, @snippet) end def authorize_admin_snippet! - return render_404 unless can?(current_user, :admin_personal_snippet, @snippet) + return render_404 unless can?(current_user, :admin_snippet, @snippet) end def authorize_create_snippet! - return render_404 unless can?(current_user, :create_personal_snippet) + return render_404 unless can?(current_user, :create_snippet) end def snippet_params diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index 67d33648470..0b092d2622b 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -41,6 +41,8 @@ class UploadsController < ApplicationController case model when Note can?(current_user, :read_project, model.project) + when Snippet, ProjectSnippet + can?(current_user, :read_snippet, model) when User # We validate the current user has enough (writing) # access to itself when a secret is given. diff --git a/app/graphql/mutations/snippets/create.rb b/app/graphql/mutations/snippets/create.rb index 4e0e65d09a9..266a123de82 100644 --- a/app/graphql/mutations/snippets/create.rb +++ b/app/graphql/mutations/snippets/create.rb @@ -67,11 +67,11 @@ module Mutations end def authorized_resource?(project) - Ability.allowed?(context[:current_user], :create_project_snippet, project) + Ability.allowed?(context[:current_user], :create_snippet, project) end def can_create_personal_snippet? - Ability.allowed?(context[:current_user], :create_personal_snippet) + Ability.allowed?(context[:current_user], :create_snippet) end end end diff --git a/app/graphql/types/permission_types/project.rb b/app/graphql/types/permission_types/project.rb index 2879dbd2b5c..094c72fa812 100644 --- a/app/graphql/types/permission_types/project.rb +++ b/app/graphql/types/permission_types/project.rb @@ -21,7 +21,7 @@ module Types permission_field :create_snippet def create_snippet - Ability.allowed?(context[:current_user], :create_project_snippet, object) + Ability.allowed?(context[:current_user], :create_snippet, object) end end end diff --git a/app/graphql/types/permission_types/user.rb b/app/graphql/types/permission_types/user.rb index dba4de2dacc..93d9787d58e 100644 --- a/app/graphql/types/permission_types/user.rb +++ b/app/graphql/types/permission_types/user.rb @@ -8,7 +8,7 @@ module Types permission_field :create_snippet def create_snippet - Ability.allowed?(context[:current_user], :create_personal_snippet) + Ability.allowed?(context[:current_user], :create_snippet) end end end diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb index d6e466d4678..e24d6a0e8db 100644 --- a/app/helpers/markup_helper.rb +++ b/app/helpers/markup_helper.rb @@ -76,13 +76,14 @@ module MarkupHelper # +max_chars+ limit. If the length limit falls within a tag's contents, then # the tag contents are truncated without removing the closing tag. def first_line_in_markdown(object, attribute, max_chars = nil, options = {}) - md = markdown_field(object, attribute, options) + md = markdown_field(object, attribute, options.merge(post_process: false)) return unless md.present? tags = %w(a gl-emoji b pre code p span) tags << 'img' if options[:allow_images] text = truncate_visible(md, max_chars || md.length) + text = prepare_for_rendering(text, markdown_field_render_context(object, attribute, options)) text = sanitize( text, tags: tags, @@ -107,15 +108,12 @@ module MarkupHelper def markdown_field(object, field, context = {}) object = object.for_display if object.respond_to?(:for_display) - redacted_field_html = object.try(:"redacted_#{field}_html") - return '' unless object.present? - return redacted_field_html if redacted_field_html - html = Banzai.render_field(object, field, context) - context.reverse_merge!(object.banzai_render_context(field)) if object.respond_to?(:banzai_render_context) + redacted_field_html = object.try(:"redacted_#{field}_html") + return redacted_field_html if redacted_field_html - prepare_for_rendering(html, context) + render_markdown_field(object, field, context) end def markup(file_name, text, context = {}) @@ -277,6 +275,23 @@ module MarkupHelper Gitlab::OtherMarkup.render(file_name, text, context) end + def render_markdown_field(object, field, context = {}) + post_process = context.delete(:post_process) + post_process = true if post_process.nil? + + html = Banzai.render_field(object, field, context) + + return html unless post_process + + prepare_for_rendering(html, markdown_field_render_context(object, field, context)) + end + + def markdown_field_render_context(object, field, base_context = {}) + return base_context unless object.respond_to?(:banzai_render_context) + + base_context.reverse_merge(object.banzai_render_context(field)) + end + def prepare_for_rendering(html, context = {}) return '' unless html.present? diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 63f1f24b611..339d68871ae 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -425,7 +425,7 @@ module ProjectsHelper { environments: :read_environment, milestones: :read_milestone, - snippets: :read_project_snippet, + snippets: :read_snippet, settings: :admin_project, builds: :read_build, clusters: :read_cluster, @@ -443,7 +443,7 @@ module ProjectsHelper blobs: :download_code, commits: :download_code, merge_requests: :read_merge_request, - notes: [:read_merge_request, :download_code, :read_issue, :read_project_snippet], + notes: [:read_merge_request, :download_code, :read_issue, :read_snippet], members: :read_project_member ) end diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb index de70d0073b3..6dd4ccb510a 100644 --- a/app/mailers/emails/notes.rb +++ b/app/mailers/emails/notes.rb @@ -26,19 +26,17 @@ module Emails mail_answer_note_thread(@merge_request, @note, note_thread_options(recipient_id, reason)) end - def note_project_snippet_email(recipient_id, note_id, reason = nil) + def note_snippet_email(recipient_id, note_id, reason = nil) setup_note_mail(note_id, recipient_id) - @snippet = @note.noteable - @target_url = project_snippet_url(*note_target_url_options) - mail_answer_note_thread(@snippet, @note, note_thread_options(recipient_id, reason)) - end - def note_personal_snippet_email(recipient_id, note_id, reason = nil) - setup_note_mail(note_id, recipient_id) + case @snippet + when ProjectSnippet + @target_url = project_snippet_url(*note_target_url_options) + when Snippet + @target_url = gitlab_snippet_url(@note.noteable) + end - @snippet = @note.noteable - @target_url = gitlab_snippet_url(@note.noteable) mail_answer_note_thread(@snippet, @note, note_thread_options(recipient_id, reason)) end diff --git a/app/models/ability.rb b/app/models/ability.rb index 1466407d0d1..671a92632d5 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -24,7 +24,7 @@ class Ability # read the given snippet. def users_that_can_read_personal_snippet(users, snippet) DeclarativePolicy.subject_scope do - users.select { |u| allowed?(u, :read_personal_snippet, snippet) } + users.select { |u| allowed?(u, :read_snippet, snippet) } end end diff --git a/app/models/concerns/project_features_compatibility.rb b/app/models/concerns/project_features_compatibility.rb index eac676f30a5..76d26500267 100644 --- a/app/models/concerns/project_features_compatibility.rb +++ b/app/models/concerns/project_features_compatibility.rb @@ -62,6 +62,10 @@ module ProjectFeaturesCompatibility write_feature_attribute_string(:snippets_access_level, value) end + def pages_access_level=(value) + write_feature_attribute_string(:pages_access_level, value) + end + private def write_feature_attribute_boolean(field, value) diff --git a/app/models/event.rb b/app/models/event.rb index 9611019adb8..35fb062311f 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -145,10 +145,8 @@ class Event < ApplicationRecord Ability.allowed?(user, :read_issue, note? ? note_target : target) elsif merge_request? || merge_request_note? Ability.allowed?(user, :read_merge_request, note? ? note_target : target) - elsif personal_snippet_note? - Ability.allowed?(user, :read_personal_snippet, note_target) - elsif project_snippet_note? - Ability.allowed?(user, :read_project_snippet, note_target) + elsif personal_snippet_note? || project_snippet_note? + Ability.allowed?(user, :read_snippet, note_target) elsif milestone? Ability.allowed?(user, :read_milestone, project) else diff --git a/app/models/note.rb b/app/models/note.rb index de9478ce68d..0434f0963d3 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -367,7 +367,7 @@ class Note < ApplicationRecord end def noteable_ability_name - for_snippet? ? noteable.class.name.underscore : noteable_type.demodulize.underscore + for_snippet? ? 'snippet' : noteable_type.demodulize.underscore end def can_be_discussion_note? diff --git a/app/models/project.rb b/app/models/project.rb index a73ca7d5bbb..236111cba94 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -322,7 +322,7 @@ class Project < ApplicationRecord :pages_enabled?, :public_pages?, :private_pages?, :merge_requests_access_level, :forking_access_level, :issues_access_level, :wiki_access_level, :snippets_access_level, :builds_access_level, - :repository_access_level, + :repository_access_level, :pages_access_level, to: :project_feature, allow_nil: true delegate :scheduled?, :started?, :in_progress?, :failed?, :finished?, prefix: :import, to: :import_state, allow_nil: true @@ -2274,7 +2274,7 @@ class Project < ApplicationRecord end def snippets_visible?(user = nil) - Ability.allowed?(user, :read_project_snippet, self) + Ability.allowed?(user, :read_snippet, self) end def max_attachment_size diff --git a/app/models/snippet.rb b/app/models/snippet.rb index b7f396681af..19685cdb78e 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -215,9 +215,7 @@ class Snippet < ApplicationRecord end def embeddable? - ability = project_id? ? :read_project_snippet : :read_personal_snippet - - Ability.allowed?(nil, ability, self) + Ability.allowed?(nil, :read_snippet, self) end def notes_with_associations @@ -240,7 +238,7 @@ class Snippet < ApplicationRecord end def to_ability_name - model_name.singular + 'snippet' end def valid_secret_token?(token) diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb index f212bb06bc9..764d61a9e22 100644 --- a/app/policies/global_policy.rb +++ b/app/policies/global_policy.rb @@ -75,7 +75,7 @@ class GlobalPolicy < BasePolicy rule { ~anonymous }.policy do enable :read_instance_metadata - enable :create_personal_snippet + enable :create_snippet end rule { admin }.policy do @@ -83,7 +83,7 @@ class GlobalPolicy < BasePolicy enable :update_custom_attribute end - rule { external_user }.prevent :create_personal_snippet + rule { external_user }.prevent :create_snippet end GlobalPolicy.prepend_if_ee('EE::GlobalPolicy') diff --git a/app/policies/personal_snippet_policy.rb b/app/policies/personal_snippet_policy.rb index c2fcf1a1010..bc60913563c 100644 --- a/app/policies/personal_snippet_policy.rb +++ b/app/policies/personal_snippet_policy.rb @@ -6,19 +6,19 @@ class PersonalSnippetPolicy < BasePolicy condition(:internal_snippet, scope: :subject) { @subject.internal? } rule { public_snippet }.policy do - enable :read_personal_snippet + enable :read_snippet enable :create_note end rule { is_author | admin }.policy do - enable :read_personal_snippet - enable :update_personal_snippet - enable :admin_personal_snippet + enable :read_snippet + enable :update_snippet + enable :admin_snippet enable :create_note end rule { internal_snippet & ~external_user }.policy do - enable :read_personal_snippet + enable :read_snippet enable :create_note end @@ -26,8 +26,5 @@ class PersonalSnippetPolicy < BasePolicy rule { can?(:create_note) }.enable :award_emoji - rule { can?(:read_all_resources) }.enable :read_personal_snippet - - # Aliasing the ability to ease GraphQL permissions check - rule { can?(:read_personal_snippet) }.enable :read_snippet + rule { can?(:read_all_resources) }.enable :read_snippet end diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 2789152e175..bbcb3c637a9 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -9,7 +9,7 @@ class ProjectPolicy < BasePolicy merge_request label milestone - project_snippet + snippet wiki note pipeline @@ -185,7 +185,7 @@ class ProjectPolicy < BasePolicy enable :read_issue enable :read_label enable :read_milestone - enable :read_project_snippet + enable :read_snippet enable :read_project_member enable :read_note enable :create_project @@ -208,7 +208,7 @@ class ProjectPolicy < BasePolicy enable :download_code enable :read_statistics enable :download_wiki_code - enable :create_project_snippet + enable :create_snippet enable :update_issue enable :reopen_issue enable :admin_issue @@ -286,8 +286,8 @@ class ProjectPolicy < BasePolicy rule { can?(:maintainer_access) }.policy do enable :admin_board enable :push_to_delete_protected_branch - enable :update_project_snippet - enable :admin_project_snippet + enable :update_snippet + enable :admin_snippet enable :admin_project_member enable :admin_note enable :admin_wiki @@ -352,7 +352,7 @@ class ProjectPolicy < BasePolicy end rule { snippets_disabled }.policy do - prevent(*create_read_update_admin_destroy(:project_snippet)) + prevent(*create_read_update_admin_destroy(:snippet)) end rule { wiki_disabled }.policy do @@ -405,7 +405,7 @@ class ProjectPolicy < BasePolicy enable :read_wiki enable :read_label enable :read_milestone - enable :read_project_snippet + enable :read_snippet enable :read_project_member enable :read_merge_request enable :read_note diff --git a/app/policies/project_snippet_policy.rb b/app/policies/project_snippet_policy.rb index a9094fbd958..a38d9154102 100644 --- a/app/policies/project_snippet_policy.rb +++ b/app/policies/project_snippet_policy.rb @@ -14,44 +14,41 @@ class ProjectSnippetPolicy < BasePolicy # We have to check both project feature visibility and a snippet visibility and take the stricter one # This will be simplified - check https://gitlab.com/gitlab-org/gitlab-foss/issues/27573 rule { ~can?(:read_project) }.policy do - prevent :read_project_snippet - prevent :update_project_snippet - prevent :admin_project_snippet + prevent :read_snippet + prevent :update_snippet + prevent :admin_snippet end - # we have to use this complicated prevent because the delegated project policy - # is overly greedy in allowing :read_project_snippet, since it doesn't have any - # information about the snippet. However, :read_project_snippet on the *project* - # is used to hide/show various snippet-related controls, so we can't just move - # all of the handling here. + # we have to use this complicated prevent because the delegated project + # policy is overly greedy in allowing :read_snippet, since it doesn't have + # any information about the snippet. However, :read_snippet on the *project* + # is used to hide/show various snippet-related controls, so we can't just + # move all of the handling here. rule do all?(private_snippet | (internal_snippet & external_user), ~project.guest, ~is_author, ~can?(:read_all_resources)) - end.prevent :read_project_snippet + end.prevent :read_snippet rule { internal_snippet & ~is_author & ~admin }.policy do - prevent :update_project_snippet - prevent :admin_project_snippet + prevent :update_snippet + prevent :admin_snippet end - rule { public_snippet }.enable :read_project_snippet + rule { public_snippet }.enable :read_snippet rule { is_author & ~project.reporter & ~admin }.policy do - prevent :admin_project_snippet + prevent :admin_snippet end rule { is_author | admin }.policy do - enable :read_project_snippet - enable :update_project_snippet - enable :admin_project_snippet + enable :read_snippet + enable :update_snippet + enable :admin_snippet end - rule { ~can?(:read_project_snippet) }.prevent :create_note - - # Aliasing the ability to ease GraphQL permissions check - rule { can?(:read_project_snippet) }.enable :read_snippet + rule { ~can?(:read_snippet) }.prevent :create_note end ProjectSnippetPolicy.prepend_if_ee('EE::ProjectSnippetPolicy') diff --git a/app/services/snippets/destroy_service.rb b/app/services/snippets/destroy_service.rb index f253817d94f..c1e87e74aa4 100644 --- a/app/services/snippets/destroy_service.rb +++ b/app/services/snippets/destroy_service.rb @@ -36,9 +36,7 @@ module Snippets attr_reader :snippet def user_can_delete_snippet? - return can?(current_user, :admin_project_snippet, snippet) if project - - can?(current_user, :admin_personal_snippet, snippet) + can?(current_user, :admin_snippet, snippet) end def service_response_error(message, http_status) diff --git a/app/views/admin/application_settings/_account_and_limit.html.haml b/app/views/admin/application_settings/_account_and_limit.html.haml index 80a53dba2aa..4ab0ec90735 100644 --- a/app/views/admin/application_settings/_account_and_limit.html.haml +++ b/app/views/admin/application_settings/_account_and_limit.html.haml @@ -22,7 +22,7 @@ .form-group = f.label :session_expire_delay, _('Session duration (minutes)'), class: 'label-light' = f.number_field :session_expire_delay, class: 'form-control' - %span.form-text.text-muted#session_expire_delay_help_block= _('GitLab restart is required to apply changes') + %span.form-text.text-muted#session_expire_delay_help_block= _('GitLab restart is required to apply changes.') = render_if_exists 'admin/application_settings/personal_access_token_expiration_policy', form: f diff --git a/app/views/dashboard/_snippets_head.html.haml b/app/views/dashboard/_snippets_head.html.haml index 4958cdc3745..d2fb4a3cd43 100644 --- a/app/views/dashboard/_snippets_head.html.haml +++ b/app/views/dashboard/_snippets_head.html.haml @@ -3,7 +3,7 @@ - if current_user && current_user.snippets.any? || @snippets.any? .page-title-controls - - if can?(current_user, :create_personal_snippet) + - if can?(current_user, :create_snippet) = link_to _("New snippet"), new_snippet_path, class: "btn btn-success", title: _("New snippet") .top-area diff --git a/app/views/dashboard/snippets/index.html.haml b/app/views/dashboard/snippets/index.html.haml index 44a9270971a..69155b6c04d 100644 --- a/app/views/dashboard/snippets/index.html.haml +++ b/app/views/dashboard/snippets/index.html.haml @@ -1,7 +1,7 @@ - @hide_top_links = true - page_title "Snippets" - header_title "Snippets", dashboard_snippets_path -- button_path = new_snippet_path if can?(current_user, :create_personal_snippet) +- button_path = new_snippet_path if can?(current_user, :create_snippet) = render 'dashboard/snippets_head' - if current_user.snippets.exists? diff --git a/app/views/explore/projects/page_out_of_bounds.html.haml b/app/views/explore/projects/page_out_of_bounds.html.haml new file mode 100644 index 00000000000..57114dd0752 --- /dev/null +++ b/app/views/explore/projects/page_out_of_bounds.html.haml @@ -0,0 +1,21 @@ +- @hide_top_links = true +- page_title _("Projects") +- header_title _("Projects"), dashboard_projects_path + += render_dashboard_gold_trial(current_user) + +- if current_user + = render 'dashboard/projects_head', project_tab_filter: :explore +- else + = render 'explore/head' + += render 'explore/projects/nav' unless Feature.enabled?(:project_list_filter_bar) && current_user + +.nothing-here-block + .svg-content + = image_tag 'illustrations/profile-page/personal-project.svg', size: '75' + .text-content + %h5= _("Maximum page reached") + %p= _("Sorry, you have exceeded the maximum browsable page number. Please use the API to explore further.") + + = link_to _("Back to page %{number}") % { number: @max_page_number }, request.params.merge(page: @max_page_number), class: 'btn btn-inverted' diff --git a/app/views/layouts/header/_new_dropdown.haml b/app/views/layouts/header/_new_dropdown.haml index 30109621515..3cbfb24a868 100644 --- a/app/views/layouts/header/_new_dropdown.haml +++ b/app/views/layouts/header/_new_dropdown.haml @@ -21,7 +21,7 @@ - if @project&.persisted? - create_project_issue = show_new_issue_link?(@project) - merge_project = merge_request_source_project_for_project(@project) - - create_project_snippet = can?(current_user, :create_project_snippet, @project) + - create_project_snippet = can?(current_user, :create_snippet, @project) - if create_project_issue || merge_project || create_project_snippet %li.dropdown-bold-header @@ -38,5 +38,5 @@ %li= link_to _('New project'), new_project_path, class: 'qa-global-new-project-link' - if current_user.can_create_group? %li= link_to _('New group'), new_group_path - - if current_user.can?(:create_personal_snippet) + - if current_user.can?(:create_snippet) %li= link_to _('New snippet'), new_snippet_path, class: 'qa-global-new-snippet-link' diff --git a/app/views/notify/note_project_snippet_email.html.haml b/app/views/notify/note_project_snippet_email.html.haml deleted file mode 100644 index 5e69f01a486..00000000000 --- a/app/views/notify/note_project_snippet_email.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render 'note_email' diff --git a/app/views/notify/note_project_snippet_email.text.erb b/app/views/notify/note_project_snippet_email.text.erb deleted file mode 100644 index 413d9e6e9ac..00000000000 --- a/app/views/notify/note_project_snippet_email.text.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render 'note_email' %> diff --git a/app/views/notify/note_personal_snippet_email.html.haml b/app/views/notify/note_snippet_email.html.haml index 5e69f01a486..5e69f01a486 100644 --- a/app/views/notify/note_personal_snippet_email.html.haml +++ b/app/views/notify/note_snippet_email.html.haml diff --git a/app/views/notify/note_personal_snippet_email.text.erb b/app/views/notify/note_snippet_email.text.erb index 413d9e6e9ac..413d9e6e9ac 100644 --- a/app/views/notify/note_personal_snippet_email.text.erb +++ b/app/views/notify/note_snippet_email.text.erb diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml index f1a7528065a..33465953086 100644 --- a/app/views/projects/buttons/_dropdown.html.haml +++ b/app/views/projects/buttons/_dropdown.html.haml @@ -1,5 +1,5 @@ - can_create_issue = show_new_issue_link?(@project) -- can_create_project_snippet = can?(current_user, :create_project_snippet, @project) +- can_create_project_snippet = can?(current_user, :create_snippet, @project) - can_push_code = can?(current_user, :push_code, @project) - create_mr_from_new_fork = can?(current_user, :fork_project, @project) && can?(current_user, :create_merge_request_in, @project) - merge_project = merge_request_source_project_for_project(@project) diff --git a/app/views/projects/snippets/_actions.html.haml b/app/views/projects/snippets/_actions.html.haml index 29bad50579c..41c9bac0102 100644 --- a/app/views/projects/snippets/_actions.html.haml +++ b/app/views/projects/snippets/_actions.html.haml @@ -1,33 +1,33 @@ - return unless current_user .d-none.d-sm-block - - if can?(current_user, :update_project_snippet, @snippet) + - if can?(current_user, :update_snippet, @snippet) = link_to edit_project_snippet_path(@project, @snippet), class: "btn btn-grouped" do = _('Edit') - - if can?(current_user, :admin_project_snippet, @snippet) + - if can?(current_user, :admin_snippet, @snippet) = link_to project_snippet_path(@project, @snippet), method: :delete, data: { confirm: _("Are you sure?") }, class: "btn btn-grouped btn-inverted btn-remove", title: _('Delete Snippet') do = _('Delete') - - if can?(current_user, :create_project_snippet, @project) + - if can?(current_user, :create_snippet, @project) = link_to new_project_snippet_path(@project), class: 'btn btn-grouped btn-inverted btn-success', title: _("New snippet") do = _('New snippet') - if @snippet.submittable_as_spam_by?(current_user) = link_to _('Submit as spam'), mark_as_spam_project_snippet_path(@project, @snippet), method: :post, class: 'btn btn-grouped btn-spam', title: _('Submit as spam') -- if can?(current_user, :create_project_snippet, @project) || can?(current_user, :update_project_snippet, @snippet) +- if can?(current_user, :create_snippet, @project) || can?(current_user, :update_snippet, @snippet) .d-block.d-sm-none.dropdown %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } } = _('Options') = icon('caret-down') .dropdown-menu.dropdown-menu-full-width %ul - - if can?(current_user, :create_project_snippet, @project) + - if can?(current_user, :create_snippet, @project) %li = link_to new_project_snippet_path(@project), title: _("New snippet") do = _('New snippet') - - if can?(current_user, :admin_project_snippet, @snippet) + - if can?(current_user, :admin_snippet, @snippet) %li = link_to project_snippet_path(@project, @snippet), method: :delete, data: { confirm: _("Are you sure?") }, title: _('Delete Snippet') do = _('Delete') - - if can?(current_user, :update_project_snippet, @snippet) + - if can?(current_user, :update_snippet, @snippet) %li = link_to edit_project_snippet_path(@project, @snippet) do = _('Edit') diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml index 0ce18d83d57..65462647419 100644 --- a/app/views/projects/snippets/index.html.haml +++ b/app/views/projects/snippets/index.html.haml @@ -6,7 +6,7 @@ - include_private = @project.team.member?(current_user) || current_user.admin? = render partial: 'snippets/snippets_scope_menu', locals: { subject: @project, include_private: include_private } - - if can?(current_user, :create_project_snippet, @project) + - if can?(current_user, :create_snippet, @project) .nav-controls = link_to _("New snippet"), new_project_snippet_path(@project), class: "btn btn-success", title: _("New snippet") diff --git a/app/views/snippets/_actions.html.haml b/app/views/snippets/_actions.html.haml index 5ee12a2f22a..979821a3846 100644 --- a/app/views/snippets/_actions.html.haml +++ b/app/views/snippets/_actions.html.haml @@ -1,13 +1,13 @@ - return unless current_user .d-none.d-sm-block - - if can?(current_user, :update_personal_snippet, @snippet) + - if can?(current_user, :update_snippet, @snippet) = link_to edit_snippet_path(@snippet), class: "btn btn-grouped" do = _("Edit") - - if can?(current_user, :admin_personal_snippet, @snippet) + - if can?(current_user, :admin_snippet, @snippet) = link_to gitlab_snippet_path(@snippet), method: :delete, data: { confirm: _("Are you sure?") }, class: "btn btn-grouped btn-inverted btn-remove", title: _('Delete Snippet') do = _("Delete") - - if can?(current_user, :create_personal_snippet) + - if can?(current_user, :create_snippet) = link_to new_snippet_path, class: "btn btn-grouped btn-success btn-inverted", title: _("New snippet") do = _("New snippet") - if @snippet.submittable_as_spam_by?(current_user) @@ -18,15 +18,15 @@ = icon('caret-down') .dropdown-menu.dropdown-menu-full-width %ul - - if can?(current_user, :create_personal_snippet) + - if can?(current_user, :create_snippet) %li = link_to new_snippet_path, title: _("New snippet") do = _("New snippet") - - if can?(current_user, :admin_personal_snippet, @snippet) + - if can?(current_user, :admin_snippet, @snippet) %li = link_to gitlab_snippet_path(@snippet), method: :delete, data: { confirm: _("Are you sure?") }, title: _('Delete Snippet') do = _("Delete") - - if can?(current_user, :update_personal_snippet, @snippet) + - if can?(current_user, :update_snippet, @snippet) %li = link_to edit_snippet_path(@snippet) do = _("Edit") diff --git a/app/views/snippets/_snippets.html.haml b/app/views/snippets/_snippets.html.haml index 69b19c0def9..1d22575803b 100644 --- a/app/views/snippets/_snippets.html.haml +++ b/app/views/snippets/_snippets.html.haml @@ -3,7 +3,7 @@ - current_user_empty_message_header = s_('UserProfile|You haven\'t created any snippets.') - current_user_empty_message_description = s_('UserProfile|Snippets in GitLab can either be private, internal, or public.') - primary_button_label = _('New snippet') -- primary_button_link = new_snippet_path if can?(current_user, :create_personal_snippet) +- primary_button_link = new_snippet_path if can?(current_user, :create_snippet) - visitor_empty_message = s_('UserProfile|No snippets found.') .snippets-list-holder |