Skip to content
Snippets Groups Projects
Commit 5ad0cf26 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent f47c768f
No related branches found
No related tags found
No related merge requests found
Showing
with 169 additions and 59 deletions
Loading
Loading
@@ -13,7 +13,7 @@
.default-before_script:
before_script:
- date
- '[ "$FOSS_ONLY" = "1" ] && rm -rf ee/'
- '[ "$FOSS_ONLY" = "1" ] && rm -rf ee/ qa/spec/ee/ qa/qa/specs/features/ee/ qa/qa/ee/ qa/qa/ee.rb'
- export GOPATH=$CI_PROJECT_DIR/.go
- mkdir -p $GOPATH
- source scripts/utils.sh
Loading
Loading
Loading
Loading
@@ -40,7 +40,7 @@
paths:
- vendor/ruby
before_script:
- '[ "$FOSS_ONLY" = "1" ] && rm -rf ee/'
- '[ "$FOSS_ONLY" = "1" ] && rm -rf ee/ qa/spec/ee/ qa/qa/specs/features/ee/ qa/qa/ee/ qa/qa/ee.rb'
- cd qa/
- bundle install --clean --jobs=$(nproc) --path=vendor --retry=3 --quiet
- bundle check
Loading
Loading
@@ -50,6 +50,13 @@ qa:internal:
script:
- bundle exec rspec
 
qa:internal-foss:
extends:
- .qa-job-base
- .only-ee-as-if-foss
script:
- bundle exec rspec
qa:selectors:
extends: .qa-job-base
script:
Loading
Loading
Loading
Loading
@@ -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>
Loading
Loading
Loading
Loading
@@ -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" />
Loading
Loading
@@ -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" />
Loading
Loading
Loading
Loading
@@ -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"
>
Loading
Loading
Loading
Loading
@@ -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 />
Loading
Loading
Loading
Loading
@@ -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;
Loading
Loading
@@ -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 {
Loading
Loading
@@ -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;
Loading
Loading
# 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
# frozen_string_literal: true
 
class Explore::ProjectsController < Explore::ApplicationController
include PageLimiter
include ParamsBackwardCompatibility
include RendersMemberAccess
include SortingHelper
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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!
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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.
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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,
Loading
Loading
@@ -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 = {})
Loading
Loading
@@ -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?
 
Loading
Loading
Loading
Loading
@@ -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,
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment