Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-26 12:08:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-26 12:08:06 +0300
commit27c6c4bf061c3a2289ce4808b1b354535994d09d (patch)
treee973f10e40356141a4f19b94259b3b2f2b93b792 /app
parent47a2a65f346719a0b4441a28a7adcbe747173f30 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/components/related_items_list.scss18
-rw-r--r--app/controllers/concerns/check_codeowner_rules.rb9
-rw-r--r--app/controllers/projects/blob_controller.rb17
-rw-r--r--app/finders/ci/runners_finder.rb4
-rw-r--r--app/finders/issuable_finder.rb2
-rw-r--r--app/graphql/mutations/merge_requests/create.rb63
-rw-r--r--app/graphql/types/milestone_type.rb12
-rw-r--r--app/graphql/types/mutation_type.rb1
-rw-r--r--app/models/concerns/featurable.rb99
-rw-r--r--app/models/concerns/issuable.rb9
-rw-r--r--app/models/milestone.rb4
-rw-r--r--app/models/project_feature.rb106
12 files changed, 214 insertions, 130 deletions
diff --git a/app/assets/stylesheets/components/related_items_list.scss b/app/assets/stylesheets/components/related_items_list.scss
index 61f971a3185..fd1108a7305 100644
--- a/app/assets/stylesheets/components/related_items_list.scss
+++ b/app/assets/stylesheets/components/related_items_list.scss
@@ -23,6 +23,11 @@ $item-remove-button-space: 42px;
.sortable-link {
white-space: normal;
}
+
+ .item-assignees .avatar {
+ height: $gl-padding;
+ width: $gl-padding;
+ }
}
.item-body {
@@ -276,10 +281,6 @@ $item-remove-button-space: 42px;
/* Small devices (landscape phones, 768px and up) */
@include media-breakpoint-up(md) {
- .item-body .item-contents {
- max-width: 95%;
- }
-
.related-items-tree .item-contents,
.item-body .item-title {
max-width: 100%;
@@ -348,6 +349,11 @@ $item-remove-button-space: 42px;
}
.item-assignees {
+ .avatar {
+ height: $gl-padding-24;
+ width: $gl-padding-24;
+ }
+
.avatar-counter {
height: $gl-padding-24;
min-width: $gl-padding-24;
@@ -366,6 +372,10 @@ $item-remove-button-space: 42px;
.sortable-link {
line-height: 1.3;
}
+
+ .item-info-area {
+ flex-basis: auto;
+ }
}
@media only screen and (min-width: 1500px) {
diff --git a/app/controllers/concerns/check_codeowner_rules.rb b/app/controllers/concerns/check_codeowner_rules.rb
deleted file mode 100644
index 87947a356f7..00000000000
--- a/app/controllers/concerns/check_codeowner_rules.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-module CheckCodeownerRules
- extend ActiveSupport::Concern
-
- def codeowners_check_error(project, branch_name, paths)
- ::Gitlab::CodeOwners::Validator.new(project, branch_name, paths).execute
- end
-end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index d044548e147..d35498260c6 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -9,7 +9,6 @@ class Projects::BlobController < Projects::ApplicationController
include ActionView::Helpers::SanitizeHelper
include RedirectsForMissingPathOnTree
include SourcegraphDecorator
- include CheckCodeownerRules
prepend_before_action :authenticate_user!, only: [:edit]
@@ -29,7 +28,6 @@ class Projects::BlobController < Projects::ApplicationController
before_action :editor_variables, except: [:show, :preview, :diff]
before_action :validate_diff_params, only: :diff
before_action :set_last_commit_sha, only: [:edit, :update]
- before_action :validate_codeowner_rules, only: [:create, :update]
before_action only: :show do
push_frontend_feature_flag(:code_navigation, @project)
@@ -118,18 +116,7 @@ class Projects::BlobController < Projects::ApplicationController
private
- def validate_codeowner_rules
- return if params[:file_path].blank?
-
- codeowners_error = codeowners_check_error(@project, @branch_name, params[:file_path])
-
- if codeowners_error.present?
- flash.now[:alert] = codeowners_error
- view = params[:action] == 'update' ? :edit : :new
-
- render view
- end
- end
+ attr_reader :branch_name
def blob
@blob ||= @repository.blob_at(@commit.id, @path)
@@ -270,3 +257,5 @@ class Projects::BlobController < Projects::ApplicationController
params.permit(:full, :since, :to, :bottom, :unfold, :offset, :indent)
end
end
+
+Projects::BlobController.prepend_if_ee('EE::Projects::BlobController')
diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb
index 54d9d9522e0..1b76211c524 100644
--- a/app/finders/ci/runners_finder.rb
+++ b/app/finders/ci/runners_finder.rb
@@ -52,9 +52,9 @@ module Ci
raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :admin_group, @group)
# Getting all runners from the group itself and all its descendants
- descentant_projects = Project.for_group_and_its_subgroups(@group)
+ descendant_projects = Project.for_group_and_its_subgroups(@group)
- @runners = Ci::Runner.belonging_to_group_or_project(@group.self_and_descendants, descentant_projects)
+ @runners = Ci::Runner.belonging_to_group_or_project(@group.self_and_descendants, descendant_projects)
end
def filter_by_status!
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 7014f2ec205..5cdc22fd873 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -451,7 +451,7 @@ class IssuableFinder
if params.filter_by_no_label?
items.without_label
elsif params.filter_by_any_label?
- items.any_label
+ items.any_label(params[:sort])
else
items.with_label(params.label_names, params[:sort])
end
diff --git a/app/graphql/mutations/merge_requests/create.rb b/app/graphql/mutations/merge_requests/create.rb
new file mode 100644
index 00000000000..95d6fb100e7
--- /dev/null
+++ b/app/graphql/mutations/merge_requests/create.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Mutations
+ module MergeRequests
+ class Create < BaseMutation
+ include Mutations::ResolvesProject
+
+ graphql_name 'MergeRequestCreate'
+
+ argument :project_path, GraphQL::ID_TYPE,
+ required: true,
+ description: 'Project full path the merge request is associated with'
+
+ argument :title, GraphQL::STRING_TYPE,
+ required: true,
+ description: copy_field_description(Types::MergeRequestType, :title)
+
+ argument :source_branch, GraphQL::STRING_TYPE,
+ required: true,
+ description: copy_field_description(Types::MergeRequestType, :source_branch)
+
+ argument :target_branch, GraphQL::STRING_TYPE,
+ required: true,
+ description: copy_field_description(Types::MergeRequestType, :target_branch)
+
+ argument :description, GraphQL::STRING_TYPE,
+ required: false,
+ description: copy_field_description(Types::MergeRequestType, :description)
+
+ field :merge_request,
+ Types::MergeRequestType,
+ null: true,
+ description: 'The merge request after mutation'
+
+ authorize :create_merge_request_from
+
+ def resolve(project_path:, title:, source_branch:, target_branch:, description: nil)
+ project = authorized_find!(full_path: project_path)
+
+ attributes = {
+ title: title,
+ source_branch: source_branch,
+ target_branch: target_branch,
+ author_id: current_user.id,
+ description: description
+ }
+
+ merge_request = ::MergeRequests::CreateService.new(project, current_user, attributes).execute
+
+ {
+ merge_request: merge_request.valid? ? merge_request : nil,
+ errors: errors_on_object(merge_request)
+ }
+ end
+
+ private
+
+ def find_object(full_path:)
+ resolve_project(full_path: full_path)
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/milestone_type.rb b/app/graphql/types/milestone_type.rb
index 900f8c6f01d..99bd6e819d6 100644
--- a/app/graphql/types/milestone_type.rb
+++ b/app/graphql/types/milestone_type.rb
@@ -35,5 +35,17 @@ module Types
field :updated_at, Types::TimeType, null: false,
description: 'Timestamp of last milestone update'
+
+ field :project_milestone, GraphQL::BOOLEAN_TYPE, null: false,
+ description: 'Indicates if milestone is at project level',
+ method: :project_milestone?
+
+ field :group_milestone, GraphQL::BOOLEAN_TYPE, null: false,
+ description: 'Indicates if milestone is at group level',
+ method: :group_milestone?
+
+ field :subgroup_milestone, GraphQL::BOOLEAN_TYPE, null: false,
+ description: 'Indicates if milestone is at subgroup level',
+ method: :subgroup_milestone?
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index aeff84b83b8..ae5469ba5b2 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -16,6 +16,7 @@ module Types
mount_mutation Mutations::Issues::SetConfidential
mount_mutation Mutations::Issues::SetDueDate
mount_mutation Mutations::Issues::Update
+ mount_mutation Mutations::MergeRequests::Create
mount_mutation Mutations::MergeRequests::SetLabels
mount_mutation Mutations::MergeRequests::SetLocked
mount_mutation Mutations::MergeRequests::SetMilestone
diff --git a/app/models/concerns/featurable.rb b/app/models/concerns/featurable.rb
new file mode 100644
index 00000000000..60aa46ce04c
--- /dev/null
+++ b/app/models/concerns/featurable.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+# == Featurable concern
+#
+# This concern adds features (tools) functionality to Project and Group
+# To enable features you need to call `set_available_features`
+#
+# Example:
+#
+# class ProjectFeature
+# include Featurable
+# set_available_features %i(wiki merge_request)
+
+module Featurable
+ extend ActiveSupport::Concern
+
+ # Can be enabled only for members, everyone or disabled
+ # Access control is made only for non private containers.
+ #
+ # Permission levels:
+ #
+ # Disabled: not enabled for anyone
+ # Private: enabled only for team members
+ # Enabled: enabled for everyone able to access the project
+ # Public: enabled for everyone (only allowed for pages)
+ DISABLED = 0
+ PRIVATE = 10
+ ENABLED = 20
+ PUBLIC = 30
+
+ STRING_OPTIONS = HashWithIndifferentAccess.new({
+ 'disabled' => DISABLED,
+ 'private' => PRIVATE,
+ 'enabled' => ENABLED,
+ 'public' => PUBLIC
+ }).freeze
+
+ class_methods do
+ def set_available_features(available_features = [])
+ @available_features = available_features
+
+ class_eval do
+ available_features.each do |feature|
+ define_method("#{feature}_enabled?") do
+ public_send("#{feature}_access_level") > DISABLED # rubocop:disable GitlabSecurity/PublicSend
+ end
+ end
+ end
+ end
+
+ def available_features
+ @available_features
+ end
+
+ def access_level_attribute(feature)
+ feature = ensure_feature!(feature)
+
+ "#{feature}_access_level".to_sym
+ end
+
+ def quoted_access_level_column(feature)
+ attribute = connection.quote_column_name(access_level_attribute(feature))
+ table = connection.quote_table_name(table_name)
+
+ "#{table}.#{attribute}"
+ end
+
+ def access_level_from_str(level)
+ STRING_OPTIONS.fetch(level)
+ end
+
+ def str_from_access_level(level)
+ STRING_OPTIONS.key(level)
+ end
+
+ def ensure_feature!(feature)
+ feature = feature.model_name.plural if feature.respond_to?(:model_name)
+ feature = feature.to_sym
+ raise ArgumentError, "invalid feature: #{feature}" unless available_features.include?(feature)
+
+ feature
+ end
+ end
+
+ def access_level(feature)
+ public_send(self.class.access_level_attribute(feature)) # rubocop:disable GitlabSecurity/PublicSend
+ end
+
+ def feature_available?(feature, user)
+ # This feature might not be behind a feature flag at all, so default to true
+ return false unless ::Feature.enabled?(feature, user, default_enabled: true)
+
+ get_permission(user, feature)
+ end
+
+ def string_access_level(feature)
+ self.class.str_from_access_level(access_level(feature))
+ end
+end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index a1b14dca4ac..1407a380978 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -139,7 +139,6 @@ module Issuable
scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) }
scope :with_label_ids, ->(label_ids) { joins(:label_links).where(label_links: { label_id: label_ids }) }
- scope :any_label, -> { joins(:label_links).distinct }
scope :join_project, -> { joins(:project) }
scope :inc_notes_with_associations, -> { includes(notes: [:project, :author, :award_emoji]) }
scope :references_project, -> { references(:project) }
@@ -316,6 +315,14 @@ module Issuable
end
end
+ def any_label(sort = nil)
+ if sort
+ joins(:label_links).group(*grouping_columns(sort))
+ else
+ joins(:label_links).distinct
+ end
+ end
+
# Includes table keys in group by clause when sorting
# preventing errors in postgres
#
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index b5e4f62792e..ba9635897a3 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -179,6 +179,10 @@ class Milestone < ApplicationRecord
end
end
+ def subgroup_milestone?
+ group_milestone? && parent.subgroup?
+ end
+
private
def milestone_format_reference(format = :iid)
diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb
index 9201cd24d66..b3ebcbd4b17 100644
--- a/app/models/project_feature.rb
+++ b/app/models/project_feature.rb
@@ -1,51 +1,16 @@
# frozen_string_literal: true
class ProjectFeature < ApplicationRecord
- # == Project features permissions
- #
- # Grants access level to project tools
- #
- # Tools can be enabled only for users, everyone or disabled
- # Access control is made only for non private projects
- #
- # levels:
- #
- # Disabled: not enabled for anyone
- # Private: enabled only for team members
- # Enabled: enabled for everyone able to access the project
- # Public: enabled for everyone (only allowed for pages)
- #
-
- # Permission levels
- DISABLED = 0
- PRIVATE = 10
- ENABLED = 20
- PUBLIC = 30
+ include Featurable
FEATURES = %i(issues forking merge_requests wiki snippets builds repository pages metrics_dashboard).freeze
+
+ set_available_features(FEATURES)
+
PRIVATE_FEATURES_MIN_ACCESS_LEVEL = { merge_requests: Gitlab::Access::REPORTER, metrics_dashboard: Gitlab::Access::REPORTER }.freeze
PRIVATE_FEATURES_MIN_ACCESS_LEVEL_FOR_PRIVATE_PROJECT = { repository: Gitlab::Access::REPORTER }.freeze
- STRING_OPTIONS = HashWithIndifferentAccess.new({
- 'disabled' => DISABLED,
- 'private' => PRIVATE,
- 'enabled' => ENABLED,
- 'public' => PUBLIC
- }).freeze
class << self
- def access_level_attribute(feature)
- feature = ensure_feature!(feature)
-
- "#{feature}_access_level".to_sym
- end
-
- def quoted_access_level_column(feature)
- attribute = connection.quote_column_name(access_level_attribute(feature))
- table = connection.quote_table_name(table_name)
-
- "#{table}.#{attribute}"
- end
-
def required_minimum_access_level(feature)
feature = ensure_feature!(feature)
@@ -60,24 +25,6 @@ class ProjectFeature < ApplicationRecord
required_minimum_access_level(feature)
end
end
-
- def access_level_from_str(level)
- STRING_OPTIONS.fetch(level)
- end
-
- def str_from_access_level(level)
- STRING_OPTIONS.key(level)
- end
-
- private
-
- def ensure_feature!(feature)
- feature = feature.model_name.plural if feature.respond_to?(:model_name)
- feature = feature.to_sym
- raise ArgumentError, "invalid project feature: #{feature}" unless FEATURES.include?(feature)
-
- feature
- end
end
# Default scopes force us to unscope here since a service may need to check
@@ -107,45 +54,6 @@ class ProjectFeature < ApplicationRecord
end
end
- def feature_available?(feature, user)
- # This feature might not be behind a feature flag at all, so default to true
- return false unless ::Feature.enabled?(feature, user, default_enabled: true)
-
- get_permission(user, feature)
- end
-
- def access_level(feature)
- public_send(ProjectFeature.access_level_attribute(feature)) # rubocop:disable GitlabSecurity/PublicSend
- end
-
- def string_access_level(feature)
- ProjectFeature.str_from_access_level(access_level(feature))
- end
-
- def builds_enabled?
- builds_access_level > DISABLED
- end
-
- def wiki_enabled?
- wiki_access_level > DISABLED
- end
-
- def merge_requests_enabled?
- merge_requests_access_level > DISABLED
- end
-
- def forking_enabled?
- forking_access_level > DISABLED
- end
-
- def issues_enabled?
- issues_access_level > DISABLED
- end
-
- def pages_enabled?
- pages_access_level > DISABLED
- end
-
def public_pages?
return true unless Gitlab.config.pages.access_control
@@ -164,7 +72,7 @@ class ProjectFeature < ApplicationRecord
# which cannot be higher than repository access level
def repository_children_level
validator = lambda do |field|
- level = public_send(field) || ProjectFeature::ENABLED # rubocop:disable GitlabSecurity/PublicSend
+ level = public_send(field) || ENABLED # rubocop:disable GitlabSecurity/PublicSend
not_allowed = level > repository_access_level
self.errors.add(field, "cannot have higher visibility level than repository access level") if not_allowed
end
@@ -175,8 +83,8 @@ class ProjectFeature < ApplicationRecord
# Validates access level for other than pages cannot be PUBLIC
def allowed_access_levels
validator = lambda do |field|
- level = public_send(field) || ProjectFeature::ENABLED # rubocop:disable GitlabSecurity/PublicSend
- not_allowed = level > ProjectFeature::ENABLED
+ level = public_send(field) || ENABLED # rubocop:disable GitlabSecurity/PublicSend
+ not_allowed = level > ENABLED
self.errors.add(field, "cannot have public visibility level") if not_allowed
end