Merge branch 'master' into ph-inline-js

This commit is contained in:
Phil Hughes 2017-07-27 16:00:30 +01:00
commit 76704c7960
243 changed files with 4290 additions and 1251 deletions

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
7.5

View File

@ -2,6 +2,18 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 9.4.1 (2017-07-25)
- Fix pipeline_schedules pages throwing error 500 (when ref is empty). !12983
- Fix editing project with container images present. !13028
- Fix some invalid entries in PO files. !13032
- Fix cross site request protection when logging in as a regular user when LDAP is enabled. !13049
- Fix bug causing metrics files to be truncated. !35420
- Fix anonymous access to public projects in groups with pending invites.
- Fixed issue boards sidebar close icon size.
- Fixed duplicate new milestone buttons when new navigation is turned on.
- Fix margins in the mini graph for pipeline in commits box.
## 9.4.0 (2017-07-22)
- Add blame view age mapping. !7198 (Jeff Stubler)

View File

@ -114,8 +114,8 @@ scheduling into milestones. Labelling is a task for everyone.
Most issues will have labels for at least one of the following:
- Type: ~"feature proposal", ~bug, ~customer, etc.
- Subject: ~wiki, ~"container registry", ~ldap, ~api, etc.
- Team: ~CI, ~Discussion, ~Edge, ~Frontend, ~Platform, etc.
- Subject: ~wiki, ~"container registry", ~ldap, ~api, ~frontend, etc.
- Team: ~CI, ~Discussion, ~Edge, ~Platform, etc.
- Priority: ~Deliverable, ~Stretch
All labels, their meaning and priority are defined on the
@ -278,7 +278,7 @@ For feature proposals for EE, open an issue on the
In order to help track the feature proposals, we have created a
[`feature proposal`][fpl] label. For the time being, users that are not members
of the project cannot add labels. You can instead ask one of the [core team]
members to add the label `feature proposal` to the issue or add the following
members to add the label ~"feature proposal" to the issue or add the following
code snippet right after your description in a new line: `~"feature proposal"`.
Please keep feature proposals as small and simple as possible, complex ones

View File

@ -16,6 +16,7 @@ gem 'mysql2', '~> 0.4.5', group: :mysql
gem 'pg', '~> 0.18.2', group: :postgres
gem 'rugged', '~> 0.25.1.1'
gem 'grape-route-helpers', '~> 2.0.0'
gem 'faraday', '~> 0.12'
@ -60,7 +61,8 @@ gem 'browser', '~> 2.2'
# LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes
# see https://github.com/intridea/omniauth-ldap/compare/master...gitlabhq:master
gem 'gitlab_omniauth-ldap', '~> 1.2.1', require: 'omniauth-ldap'
gem 'gitlab_omniauth-ldap', '~> 2.0.3', require: 'omniauth-ldap'
gem 'net-ldap'
# Git Wiki
# Required manually in config/initializers/gollum.rb to control load order
@ -164,7 +166,7 @@ gem 'rainbow', '~> 2.2'
gem 'settingslogic', '~> 2.0.9'
# Linear-time regex library for untrusted regular expressions
gem 're2', '~> 1.1.0'
gem 're2', '~> 1.1.1'
# Misc

View File

@ -288,11 +288,11 @@ GEM
mime-types (>= 1.16, < 3)
posix-spawn (~> 0.3)
gitlab-markup (1.5.1)
gitlab_omniauth-ldap (1.2.1)
net-ldap (~> 0.9)
omniauth (~> 1.0)
pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.3)
gitlab_omniauth-ldap (2.0.3)
net-ldap (~> 0.16)
omniauth (~> 1.3)
pyu-ruby-sasl (>= 0.0.3.3, < 0.1)
rubyntlm (~> 0.5)
globalid (0.3.7)
activesupport (>= 4.1.0)
gollum-grit_adapter (1.0.1)
@ -345,6 +345,10 @@ GEM
grape-entity (0.6.0)
activesupport
multi_json (>= 1.3.2)
grape-route-helpers (2.0.0)
activesupport
grape (~> 0.16, >= 0.16.0)
rake
grpc (1.4.0)
google-protobuf (~> 3.1)
googleauth (~> 0.5.1)
@ -467,7 +471,7 @@ GEM
mustermann-grape (1.0.0)
mustermann (~> 1.0.0)
mysql2 (0.4.5)
net-ldap (0.12.1)
net-ldap (0.16.0)
netrc (0.11.0)
nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
@ -656,7 +660,7 @@ GEM
debugger-ruby_core_source (~> 1.3)
rdoc (4.2.2)
json (~> 1.4)
re2 (1.1.0)
re2 (1.1.1)
recaptcha (3.0.0)
json
recursive-open-struct (1.0.0)
@ -740,7 +744,7 @@ GEM
nokogiri (>= 1.5.10)
ruby_parser (3.9.0)
sexp_processor (~> 4.1)
rubyntlm (0.5.2)
rubyntlm (0.6.2)
rubypants (0.2.0)
rubyzip (1.2.1)
rufus-scheduler (3.4.0)
@ -974,13 +978,14 @@ DEPENDENCIES
github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.5.1)
gitlab_omniauth-ldap (~> 1.2.1)
gitlab_omniauth-ldap (~> 2.0.3)
gollum-lib (~> 4.2)
gollum-rugged_adapter (~> 0.4.4)
gon (~> 6.1.0)
google-api-client (~> 0.8.6)
grape (~> 0.19.2)
grape-entity (~> 0.6.0)
grape-route-helpers (~> 2.0.0)
haml_lint (~> 0.21.0)
hamlit (~> 2.6.1)
hashie-forbidden_attributes
@ -1008,6 +1013,7 @@ DEPENDENCIES
minitest (~> 5.7.0)
mousetrap-rails (~> 1.4.6)
mysql2 (~> 0.4.5)
net-ldap
nokogiri (~> 1.6.7, >= 1.6.7.2)
oauth2 (~> 1.4)
octokit (~> 4.6.2)
@ -1055,7 +1061,7 @@ DEPENDENCIES
raindrops (~> 0.18)
rblineprof (~> 0.3.6)
rdoc (~> 4.2)
re2 (~> 1.1.0)
re2 (~> 1.1.1)
recaptcha (~> 3.0)
redcarpet (~> 3.4)
redis (~> 3.2)

View File

@ -20,6 +20,8 @@
/* global NamespaceSelects */
/* global Project */
/* global ProjectAvatar */
/* global MergeRequest */
/* global Compare */
/* global CompareAutocomplete */
/* global ProjectNew */
/* global ProjectShow */
@ -228,6 +230,19 @@ import initIssuableSidebar from './init_issuable_sidebar';
new gl.IssuableTemplateSelectors();
break;
case 'projects:merge_requests:creations:new':
const mrNewCompareNode = document.querySelector('.js-merge-request-new-compare');
if (mrNewCompareNode) {
new Compare({
targetProjectUrl: mrNewCompareNode.dataset.targetProjectUrl,
sourceBranchUrl: mrNewCompareNode.dataset.sourceBranchUrl,
targetBranchUrl: mrNewCompareNode.dataset.targetBranchUrl,
});
} else {
const mrNewSubmitNode = document.querySelector('.js-merge-request-new-submit');
new MergeRequest({
action: mrNewSubmitNode.dataset.mrSubmitAction,
});
}
case 'projects:merge_requests:creations:diffs':
case 'projects:merge_requests:edit':
new gl.Diff();
@ -267,8 +282,14 @@ import initIssuableSidebar from './init_issuable_sidebar';
new gl.Diff();
shortcut_handler = new ShortcutsIssuable(true);
new ZenMode();
initIssuableSidebar();
initNotes();
const mrShowNode = document.querySelector('.merge-request');
window.mergeRequest = new MergeRequest({
action: mrShowNode.dataset.mrAction,
});
break;
case 'dashboard:activity':
new gl.Activities();

View File

@ -3,10 +3,10 @@ document.addEventListener('DOMContentLoaded', () => {
modal: true,
show: false,
});
$('.how_to_merge_link').bind('click', () => {
$('.how_to_merge_link').on('click', () => {
modal.show();
});
$('.modal-header .close').bind('click', () => {
$('.modal-header .close').on('click', () => {
modal.hide();
});
});

View File

@ -175,7 +175,7 @@ import Cookies from 'js-cookie';
getConflictsCountText() {
const count = this.getConflictsCount();
const text = count ? 'conflicts' : 'conflict';
const text = count > 1 ? 'conflicts' : 'conflict';
return `${count} ${text}`;
},

View File

@ -108,7 +108,8 @@ export default {
</div>
<mr-widget-memory-usage
v-if="deployment.metrics_url"
:metricsUrl="deployment.metrics_url"
:metrics-url="deployment.metrics_url"
:metrics-monitoring-url="deployment.metrics_monitoring_url"
/>
</div>
</div>

View File

@ -7,7 +7,14 @@ import MRWidgetService from '../services/mr_widget_service';
export default {
name: 'MemoryUsage',
props: {
metricsUrl: { type: String, required: true },
metricsUrl: {
type: String,
required: true,
},
metricsMonitoringUrl: {
type: String,
required: true,
},
},
data() {
return {
@ -124,7 +131,7 @@ export default {
<p
v-if="shouldShowMemoryGraph"
class="usage-info js-usage-info">
Memory usage <b>{{memoryChangeType}}</b> from {{memoryFrom}}MB to {{memoryTo}}MB
<a :href="metricsMonitoringUrl">Memory</a> usage <b>{{memoryChangeType}}</b> from {{memoryFrom}}MB to {{memoryTo}}MB
</p>
<p
v-if="shouldShowLoadFailure"

View File

@ -21,6 +21,11 @@ header.navbar-gitlab-new {
padding-right: 0;
color: currentColor;
img {
height: 28px;
margin-right: 10px;
}
> a {
display: flex;
align-items: center;

View File

@ -211,6 +211,10 @@
-webkit-overflow-scrolling: touch;
}
&.affix-top .issuable-sidebar {
height: 100%;
}
&.right-sidebar-expanded {
width: $gutter_width;

View File

@ -597,7 +597,7 @@
}
// Dropdown button in mini pipeline graph
.mini-pipeline-graph-dropdown-toggle {
button.mini-pipeline-graph-dropdown-toggle {
border-radius: 100px;
background-color: $white-light;
border-width: 1px;
@ -608,6 +608,7 @@
padding: 0;
transition: all 0.2s linear;
position: relative;
vertical-align: middle;
> .fa.fa-caret-down {
position: absolute;

View File

@ -76,11 +76,11 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
params.delete(:domain_blacklist_raw) if params[:domain_blacklist_file]
params.require(:application_setting).permit(
application_setting_params_ce
application_setting_params_attributes
)
end
def application_setting_params_ce
def application_setting_params_attributes
[
:admin_notification_email,
:after_sign_out_path,

View File

@ -1,6 +1,6 @@
class Admin::DashboardController < Admin::ApplicationController
def index
@projects = Project.with_route.limit(10)
@projects = Project.without_deleted.with_route.limit(10)
@users = User.limit(10)
@groups = Group.with_route.limit(10)
end

View File

@ -22,6 +22,7 @@ class Projects::ApplicationController < ApplicationController
def project
return @project if @project
return nil unless params[:project_id] || params[:id]
path = File.join(params[:namespace_id], params[:project_id] || params[:id])
auth_proc = ->(project) { !project.pending_delete? }

View File

@ -223,12 +223,18 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
if can?(current_user, :read_environment, environment) && environment.has_metrics?
metrics_project_environment_deployment_path(environment.project, environment, deployment)
end
metrics_monitoring_url =
if can?(current_user, :read_environment, environment)
environment_metrics_path(environment)
end
{
id: environment.id,
name: environment.name,
url: project_environment_path(project, environment),
metrics_url: metrics_url,
metrics_monitoring_url: metrics_monitoring_url,
stop_url: stop_url,
external_url: environment.external_url,
external_url_formatted: environment.formatted_external_url,

View File

@ -296,10 +296,10 @@ class ProjectsController < Projects::ApplicationController
def project_params
params.require(:project)
.permit(project_params_ce)
.permit(project_params_attributes)
end
def project_params_ce
def project_params_attributes
[
:avatar,
:build_allow_git_fetch,

View File

@ -11,6 +11,7 @@
# group_id: integer
# project_id: integer
# milestone_title: string
# author_id: integer
# assignee_id: integer
# search: string
# label_name: string

View File

@ -18,7 +18,8 @@ module SystemNoteHelper
'milestone' => 'icon_clock_o',
'discussion' => 'icon_comment_o',
'moved' => 'icon_arrow_circle_o_right',
'outdated' => 'icon_edit'
'outdated' => 'icon_edit',
'duplicate' => 'icon_clone'
}.freeze
def icon_for_system_note(note)

View File

@ -21,7 +21,7 @@ module Ci
has_many :merge_requests, foreign_key: "head_pipeline_id"
has_many :pending_builds, -> { pending }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :retryable_builds, -> { latest.failed_or_canceled }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :retryable_builds, -> { latest.failed_or_canceled.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :cancelable_statuses, -> { cancelable }, foreign_key: :commit_id, class_name: 'CommitStatus'
has_many :manual_actions, -> { latest.manual_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :artifacts, -> { latest.with_artifacts_not_expired.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'

View File

@ -40,10 +40,6 @@ module Ci
update_attribute(:active, false)
end
def runnable_by_owner?
Ability.allowed?(owner, :create_pipeline, project)
end
def set_next_run_at
self.next_run_at = Gitlab::Ci::CronParser.new(cron, cron_timezone).next_time_from(Time.now)
end

View File

@ -17,7 +17,13 @@ module ProtectedRef
class_methods do
def protected_ref_access_levels(*types)
types.each do |type|
has_many :"#{type}_access_levels", dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
# We need to set `inverse_of` to make sure the `belongs_to`-object is set
# when creating children using `accepts_nested_attributes_for`.
#
# If we don't `protected_branch` or `protected_tag` would be empty and
# `project` cannot be delegated to it, which in turn would cause validations
# to fail.
has_many :"#{type}_access_levels", dependent: :destroy, inverse_of: self.model_name.singular # rubocop:disable Cop/ActiveRecordDependent
validates :"#{type}_access_levels", length: { is: 1, message: "are restricted to a single instance per #{self.model_name.human}." }
@ -25,8 +31,8 @@ module ProtectedRef
end
end
def protected_ref_accessible_to?(ref, user, action:)
access_levels_for_ref(ref, action: action).any? do |access_level|
def protected_ref_accessible_to?(ref, user, action:, protected_refs: nil)
access_levels_for_ref(ref, action: action, protected_refs: protected_refs).any? do |access_level|
access_level.check_access(user)
end
end
@ -37,8 +43,9 @@ module ProtectedRef
end
end
def access_levels_for_ref(ref, action:)
self.matching(ref).map(&:"#{action}_access_levels").flatten
def access_levels_for_ref(ref, action:, protected_refs: nil)
self.matching(ref, protected_refs: protected_refs)
.map(&:"#{action}_access_levels").flatten
end
def matching(ref_name, protected_refs: nil)

View File

@ -236,10 +236,21 @@ class MergeRequestDiff < ActiveRecord::Base
def create_merge_request_diff_files(diffs)
rows = diffs.map.with_index do |diff, index|
diff.to_hash.merge(
diff_hash = diff.to_hash.merge(
binary: false,
merge_request_diff_id: self.id,
relative_order: index
)
# Compatibility with old diffs created with Psych.
diff_hash.tap do |hash|
diff_text = hash[:diff]
if diff_text.encoding == Encoding::BINARY && !diff_text.ascii_only?
hash[:binary] = true
hash[:diff] = [diff_text].pack('m0')
end
end
end
Gitlab::Database.bulk_insert('merge_request_diff_files', rows)
@ -268,9 +279,7 @@ class MergeRequestDiff < ActiveRecord::Base
st_diffs
end
elsif merge_request_diff_files.present?
merge_request_diff_files
.as_json(only: Gitlab::Git::Diff::SERIALIZE_KEYS)
.map(&:with_indifferent_access)
merge_request_diff_files.map(&:to_hash)
end
end

View File

@ -8,4 +8,14 @@ class MergeRequestDiffFile < ActiveRecord::Base
encode_utf8(diff) if diff.respond_to?(:encoding)
end
def diff
binary? ? super.unpack('m0').first : super
end
def to_hash
keys = Gitlab::Git::Diff::SERIALIZE_KEYS - [:diff]
as_json(only: keys).merge(diff: diff).with_indifferent_access
end
end

View File

@ -3,10 +3,8 @@ class JiraService < IssueTrackerService
validates :url, url: true, presence: true, if: :activated?
validates :api_url, url: true, allow_blank: true
validates :project_key, presence: true, if: :activated?
prop_accessor :username, :password, :url, :api_url, :project_key,
:jira_issue_transition_id, :title, :description
prop_accessor :username, :password, :url, :api_url, :jira_issue_transition_id, :title, :description
before_update :reset_password
@ -54,10 +52,6 @@ class JiraService < IssueTrackerService
@client ||= JIRA::Client.new(options)
end
def jira_project
@jira_project ||= jira_request { client.Project.find(project_key) }
end
def help
"You need to configure JIRA before enabling this service. For more details
read the
@ -88,18 +82,12 @@ class JiraService < IssueTrackerService
[
{ type: 'text', name: 'url', title: 'Web URL', placeholder: 'https://jira.example.com', required: true },
{ type: 'text', name: 'api_url', title: 'JIRA API URL', placeholder: 'If different from Web URL' },
{ type: 'text', name: 'project_key', placeholder: 'Project Key', required: true },
{ type: 'text', name: 'username', placeholder: '', required: true },
{ type: 'password', name: 'password', placeholder: '', required: true },
{ type: 'text', name: 'jira_issue_transition_id', placeholder: '' }
{ type: 'text', name: 'jira_issue_transition_id', title: 'Transition ID', placeholder: '' }
]
end
# URLs to redirect from Gitlab issues pages to jira issue tracker
def project_url
"#{url}/issues/?jql=project=#{project_key}"
end
def issues_url
"#{url}/browse/:id"
end
@ -184,7 +172,7 @@ class JiraService < IssueTrackerService
def test_settings
return unless client_url.present?
# Test settings by getting the project
jira_request { jira_project.present? }
jira_request { client.ServerInfo.all.attrs }
end
private

View File

@ -471,8 +471,17 @@ class Repository
end
cache_method :root_ref
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/314
def exists?
refs_directory_exists?
return false unless path_with_namespace
Gitlab::GitalyClient.migrate(:repository_exists) do |enabled|
if enabled
raw_repository.exists?
else
refs_directory_exists?
end
end
end
cache_method :exists?
@ -1095,8 +1104,6 @@ class Repository
end
def refs_directory_exists?
return false unless path_with_namespace
File.exist?(File.join(path_to_repo, 'refs'))
end

View File

@ -1,7 +1,8 @@
class SystemNoteMetadata < ActiveRecord::Base
ICON_TYPES = %w[
commit description merge confidential visible label assignee cross_reference
title time_tracking branch milestone discussion task moved opened closed merged
title time_tracking branch milestone discussion task moved
opened closed merged duplicate
outdated
].freeze

View File

@ -1,17 +1,15 @@
module Ci
class BuildPolicy < CommitStatusPolicy
condition(:protected_action) do
next false unless @subject.action?
condition(:protected_ref) do
access = ::Gitlab::UserAccess.new(@user, project: @subject.project)
if @subject.tag?
!access.can_create_tag?(@subject.ref)
else
!access.can_merge_to_branch?(@subject.ref)
!access.can_update_branch?(@subject.ref)
end
end
rule { protected_action }.prevent :update_build
rule { protected_ref }.prevent :update_build
end
end

View File

@ -1,5 +1,17 @@
module Ci
class PipelinePolicy < BasePolicy
delegate { @subject.project }
condition(:protected_ref) do
access = ::Gitlab::UserAccess.new(@user, project: @subject.project)
if @subject.tag?
!access.can_create_tag?(@subject.ref)
else
!access.can_update_branch?(@subject.ref)
end
end
rule { protected_ref }.prevent :update_pipeline
end
end

View File

@ -44,7 +44,7 @@ class GlobalPolicy < BasePolicy
prevent :log_in
end
rule { ~restricted_public_level }.policy do
rule { admin | ~restricted_public_level }.policy do
enable :read_users_list
end
end

View File

@ -16,7 +16,8 @@ class BuildDetailsEntity < JobEntity
end
expose :path do |build|
project_merge_request_path(project, build.merge_request)
project_merge_request_path(build.merge_request.project,
build.merge_request)
end
end

View File

@ -9,7 +9,7 @@ class DeployKeyEntity < Grape::Entity
expose :created_at
expose :updated_at
expose :projects, using: ProjectEntity do |deploy_key|
deploy_key.projects.select { |project| options[:user].can?(:read_project, project) }
deploy_key.projects.without_deleted.select { |project| options[:user].can?(:read_project, project) }
end
expose :can_edit

View File

@ -15,12 +15,40 @@ module Ci
pipeline_schedule: schedule
)
result = validate(current_user || trigger_request.trigger.owner,
ignore_skip_ci: ignore_skip_ci,
save_on_errors: save_on_errors)
return result if result
Ci::Pipeline.transaction do
update_merge_requests_head_pipeline if pipeline.save
Ci::CreatePipelineStagesService
.new(project, current_user)
.execute(pipeline)
end
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
pipeline.tap(&:process!)
end
private
def validate(triggering_user, ignore_skip_ci:, save_on_errors:)
unless project.builds_enabled?
return error('Pipeline is disabled')
end
unless trigger_request || can?(current_user, :create_pipeline, project)
return error('Insufficient permissions to create a new pipeline')
unless allowed_to_trigger_pipeline?(triggering_user)
if can?(triggering_user, :create_pipeline, project)
return error("Insufficient permissions for protected ref '#{ref}'")
else
return error('Insufficient permissions to create a new pipeline')
end
end
unless branch? || tag?
@ -46,23 +74,28 @@ module Ci
unless pipeline.has_stage_seeds?
return error('No stages / jobs for this pipeline.')
end
Ci::Pipeline.transaction do
update_merge_requests_head_pipeline if pipeline.save
Ci::CreatePipelineStagesService
.new(project, current_user)
.execute(pipeline)
end
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
pipeline.tap(&:process!)
end
private
def allowed_to_trigger_pipeline?(triggering_user)
if triggering_user
allowed_to_create?(triggering_user)
else # legacy triggers don't have a corresponding user
!project.protected_for?(ref)
end
end
def allowed_to_create?(triggering_user)
access = Gitlab::UserAccess.new(triggering_user, project: project)
can?(triggering_user, :create_pipeline, project) &&
if branch?
access.can_update_branch?(ref)
elsif tag?
access.can_create_tag?(ref)
else
true # Allow it for now and we'll reject when we check ref existence
end
end
def update_merge_requests_head_pipeline
return unless pipeline.latest?
@ -113,15 +146,21 @@ module Ci
end
def branch?
project.repository.ref_exists?(Gitlab::Git::BRANCH_REF_PREFIX + ref)
return @is_branch if defined?(@is_branch)
@is_branch =
project.repository.ref_exists?(Gitlab::Git::BRANCH_REF_PREFIX + ref)
end
def tag?
project.repository.ref_exists?(Gitlab::Git::TAG_REF_PREFIX + ref)
return @is_tag if defined?(@is_tag)
@is_tag =
project.repository.ref_exists?(Gitlab::Git::TAG_REF_PREFIX + ref)
end
def ref
Gitlab::Git.ref_name(origin_ref)
@ref ||= Gitlab::Git.ref_name(origin_ref)
end
def valid_sha?

View File

@ -1,12 +1,14 @@
module Ci
class CreateTriggerRequestService
def execute(project, trigger, ref, variables = nil)
module CreateTriggerRequestService
Result = Struct.new(:trigger_request, :pipeline)
def self.execute(project, trigger, ref, variables = nil)
trigger_request = trigger.trigger_requests.create(variables: variables)
pipeline = Ci::CreatePipelineService.new(project, trigger.owner, ref: ref)
.execute(:trigger, ignore_skip_ci: true, trigger_request: trigger_request)
trigger_request if pipeline.persisted?
Result.new(trigger_request, pipeline)
end
end
end

View File

@ -58,6 +58,7 @@ class IssuableBaseService < BaseService
params.delete(:assignee_ids)
params.delete(:assignee_id)
params.delete(:due_date)
params.delete(:canonical_issue_id)
end
filter_assignee(issuable)

View File

@ -7,6 +7,14 @@ module Issues
issue_data
end
def reopen_service
Issues::ReopenService
end
def close_service
Issues::CloseService
end
private
def create_assignee_note(issue, old_assignees)

View File

@ -0,0 +1,24 @@
module Issues
class DuplicateService < Issues::BaseService
def execute(duplicate_issue, canonical_issue)
return if canonical_issue == duplicate_issue
return unless can?(current_user, :update_issue, duplicate_issue)
return unless can?(current_user, :create_note, canonical_issue)
create_issue_duplicate_note(duplicate_issue, canonical_issue)
create_issue_canonical_note(canonical_issue, duplicate_issue)
close_service.new(project, current_user, {}).execute(duplicate_issue)
end
private
def create_issue_duplicate_note(duplicate_issue, canonical_issue)
SystemNoteService.mark_duplicate_issue(duplicate_issue, duplicate_issue.project, current_user, canonical_issue)
end
def create_issue_canonical_note(canonical_issue, duplicate_issue)
SystemNoteService.mark_canonical_issue_of_duplicate(canonical_issue, canonical_issue.project, current_user, duplicate_issue)
end
end
end

View File

@ -5,6 +5,7 @@ module Issues
def execute(issue)
handle_move_between_iids(issue)
filter_spam_check_params
change_issue_duplicate(issue)
update(issue)
end
@ -53,14 +54,6 @@ module Issues
end
end
def reopen_service
Issues::ReopenService
end
def close_service
Issues::CloseService
end
def handle_move_between_iids(issue)
return unless params[:move_between_iids]
@ -72,6 +65,15 @@ module Issues
issue.move_between(issue_before, issue_after)
end
def change_issue_duplicate(issue)
canonical_issue_id = params.delete(:canonical_issue_id)
canonical_issue = IssuesFinder.new(current_user).find_by(id: canonical_issue_id)
if canonical_issue
Issues::DuplicateService.new(project, current_user).execute(issue, canonical_issue)
end
end
private
def get_issue_if_allowed(project, iid)

View File

@ -15,40 +15,48 @@ module Projects
def execute
return false unless can?(current_user, :remove_project, project)
repo_path = project.path_with_namespace
wiki_path = repo_path + '.wiki'
# Flush the cache for both repositories. This has to be done _before_
# removing the physical repositories as some expiration code depends on
# Git data (e.g. a list of branch names).
flush_caches(project, wiki_path)
flush_caches(project)
Projects::UnlinkForkService.new(project, current_user).execute
Project.transaction do
project.team.truncate
project.destroy!
attempt_destroy_transaction(project)
unless remove_legacy_registry_tags
raise_error('Failed to remove some tags in project container registry. Please try again or contact administrator.')
end
unless remove_repository(repo_path)
raise_error('Failed to remove project repository. Please try again or contact administrator.')
end
unless remove_repository(wiki_path)
raise_error('Failed to remove wiki repository. Please try again or contact administrator.')
end
end
log_info("Project \"#{project.path_with_namespace}\" was removed")
system_hook_service.execute_hooks_for(project, :destroy)
log_info("Project \"#{project.full_path}\" was removed")
true
rescue => error
attempt_rollback(project, error.message)
false
rescue Exception => error # rubocop:disable Lint/RescueException
# Project.transaction can raise Exception
attempt_rollback(project, error.message)
raise
end
private
def repo_path
project.path_with_namespace
end
def wiki_path
repo_path + '.wiki'
end
def trash_repositories!
unless remove_repository(repo_path)
raise_error('Failed to remove project repository. Please try again or contact administrator.')
end
unless remove_repository(wiki_path)
raise_error('Failed to remove wiki repository. Please try again or contact administrator.')
end
end
def remove_repository(path)
# Skip repository removal. We use this flag when remove user or group
return true if params[:skip_repo] == true
@ -70,6 +78,26 @@ module Projects
end
end
def attempt_rollback(project, message)
return unless project
project.update_attributes(delete_error: message, pending_delete: false)
log_error("Deletion failed on #{project.full_path} with the following message: #{message}")
end
def attempt_destroy_transaction(project)
Project.transaction do
unless remove_legacy_registry_tags
raise_error('Failed to remove some tags in project container registry. Please try again or contact administrator.')
end
trash_repositories!
project.team.truncate
project.destroy!
end
end
##
# This method makes sure that we correctly remove registry tags
# for legacy image repository (when repository path equals project path).
@ -96,7 +124,7 @@ module Projects
"#{path}+#{project.id}#{DELETED_FLAG}"
end
def flush_caches(project, wiki_path)
def flush_caches(project)
project.repository.before_delete
Repository.new(wiki_path, project).before_delete

View File

@ -130,7 +130,11 @@ module Projects
end
def max_size
current_application_settings.max_pages_size.megabytes || MAX_SIZE
max_pages_size = current_application_settings.max_pages_size.megabytes
return MAX_SIZE if max_pages_size.zero?
[max_pages_size, MAX_SIZE].min
end
def tmp_path

View File

@ -471,6 +471,24 @@ module QuickActions
end
end
desc 'Mark this issue as a duplicate of another issue'
explanation do |duplicate_reference|
"Marks this issue as a duplicate of #{duplicate_reference}."
end
params '#issue'
condition do
issuable.is_a?(Issue) &&
issuable.persisted? &&
current_user.can?(:"update_#{issuable.to_ability_name}", issuable)
end
command :duplicate do |duplicate_param|
canonical_issue = extract_references(duplicate_param, :issue).first
if canonical_issue.present?
@updates[:canonical_issue_id] = canonical_issue.id
end
end
def extract_users(params)
return [] if params.nil?

View File

@ -552,6 +552,44 @@ module SystemNoteService
create_note(NoteSummary.new(noteable, project, author, body, action: 'moved'))
end
# Called when a Noteable has been marked as a duplicate of another Issue
#
# noteable - Noteable object
# project - Project owning noteable
# author - User performing the change
# canonical_issue - Issue that this is a duplicate of
#
# Example Note text:
#
# "marked this issue as a duplicate of #1234"
#
# "marked this issue as a duplicate of other_project#5678"
#
# Returns the created Note object
def mark_duplicate_issue(noteable, project, author, canonical_issue)
body = "marked this issue as a duplicate of #{canonical_issue.to_reference(project)}"
create_note(NoteSummary.new(noteable, project, author, body, action: 'duplicate'))
end
# Called when a Noteable has been marked as the canonical Issue of a duplicate
#
# noteable - Noteable object
# project - Project owning noteable
# author - User performing the change
# duplicate_issue - Issue that was a duplicate of this
#
# Example Note text:
#
# "marked #1234 as a duplicate of this issue"
#
# "marked other_project#5678 as a duplicate of this issue"
#
# Returns the created Note object
def mark_canonical_issue_of_duplicate(noteable, project, author, duplicate_issue)
body = "marked #{duplicate_issue.to_reference(project)} as a duplicate of this issue"
create_note(NoteSummary.new(noteable, project, author, body, action: 'duplicate'))
end
private
def notes_for_mentioner(mentioner, noteable, notes)

View File

@ -150,7 +150,7 @@
.well-segment.well-centered
= link_to admin_groups_path do
%h3.text-center
Groups
Groups:
= number_with_delimiter(Group.count)
%hr
= link_to 'New group', new_admin_group_path, class: "btn btn-new"

View File

@ -0,0 +1,6 @@
- project = local_assigns.fetch(:project)
- return unless project.delete_error.present?
.project-deletion-failed-message.alert.alert-warning
This project was scheduled for deletion, but failed with the following message:
= project.delete_error

View File

@ -0,0 +1,8 @@
- project = local_assigns.fetch(:project)
- flash_message_container = show_new_nav? ? :new_global_flash : :flash_message
= content_for flash_message_container do
= render partial: 'deletion_failed', locals: { project: project }
- if current_user && can?(current_user, :download_code, project)
= render 'shared/no_ssh'
= render 'shared/no_password'

View File

@ -1,10 +1,6 @@
- @no_container = true
- flash_message_container = show_new_nav? ? :new_global_flash : :flash_message
= content_for flash_message_container do
- if current_user && can?(current_user, :download_code, @project)
= render 'shared/no_ssh'
= render 'shared/no_password'
= render partial: 'flash_messages', locals: { project: @project }
= render "projects/head"
= render "home_panel"

View File

@ -1,6 +1,7 @@
- @no_container = true
- page_title "Labels"
- hide_class = ''
- can_admin_label = can?(current_user, :admin_label, @project)
- if show_new_nav? && can?(current_user, :admin_label, @project)
- content_for :breadcrumbs_extra do
@ -12,15 +13,17 @@
%div{ class: container_class }
.top-area.adjust
.nav-text
Labels can be applied to issues and merge requests. Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging.
Labels can be applied to issues and merge requests.
- if can_admin_label
Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging.
.nav-controls{ class: ("visible-xs" if show_new_nav?) }
- if can?(current_user, :admin_label, @project)
- if can_admin_label
.nav-controls{ class: ("visible-xs" if show_new_nav?) }
= link_to new_project_label_path(@project), class: "btn btn-new" do
New label
.labels
- if can?(current_user, :admin_label, @project)
- if can_admin_label
-# Only show it in the first page
- hide = @available_labels.empty? || (params[:page].present? && params[:page] != '1')
.prioritized-labels{ class: ('hide' if hide) }
@ -33,7 +36,7 @@
- if @labels.present?
.other-labels
- if can?(current_user, :admin_label, @project)
- if can_admin_label
%h5{ class: ('hide' if hide) } Other Labels
%ul.content-list.manage-labels-list.js-other-labels
= render partial: 'shared/label', subject: @project, collection: @labels, as: :label

View File

@ -3,7 +3,7 @@
= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: project_new_merge_request_path(@project), method: :get, html: { class: "merge-request-form form-inline js-requires-input" } do |f|
.hide.alert.alert-danger.mr-compare-errors
.merge-request-branches.row
.merge-request-branches.js-merge-request-new-compare.row{ 'data-target-project-url': project_new_merge_request_update_branches_path(@source_project), 'data-source-branch-url': project_new_merge_request_branch_from_path(@source_project), 'data-target-branch-url': project_new_merge_request_branch_to_path(@source_project) }
.col-md-6
.panel.panel-default.panel-new-merge-request
.panel-heading
@ -66,10 +66,3 @@
- if @merge_request.errors.any?
= form_errors(@merge_request)
= f.submit 'Compare branches and continue', class: "btn btn-new mr-compare-btn"
:javascript
new Compare({
targetProjectUrl: "#{project_new_merge_request_update_branches_path(@source_project)}",
sourceBranchUrl: "#{project_new_merge_request_branch_from_path(@source_project)}",
targetBranchUrl: "#{project_new_merge_request_branch_to_path(@source_project)}"
});

View File

@ -17,7 +17,7 @@
= f.hidden_field :target_project_id
= f.hidden_field :target_branch
.mr-compare.merge-request
.mr-compare.merge-request.js-merge-request-new-submit{ 'data-mr-submit-action': "#{j params[:tab].presence || 'new'}" }
- if @commits.empty?
.commits-empty
%h4
@ -50,8 +50,3 @@
.mr-loading-status
= spinner
:javascript
var merge_request = new MergeRequest({
action: "#{j params[:tab].presence || 'new'}",
});

View File

@ -3,10 +3,10 @@
- page_description @merge_request.description
- page_card_attributes @merge_request.card_attributes
- content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('diff_notes')
= webpack_bundle_tag('common_vue')
= webpack_bundle_tag('diff_notes')
.merge-request{ 'data-url' => merge_request_path(@merge_request, format: :json), 'data-project-path' => project_path(@merge_request.project) }
.merge-request{ 'data-mr-action': "#{j params[:tab].presence || 'show'}", 'data-url' => merge_request_path(@merge_request, format: :json), 'data-project-path' => project_path(@merge_request.project) }
= render "projects/merge_requests/mr_title"
.merge-request-details.issuable-details{ data: { id: @merge_request.project.id } }
@ -15,13 +15,13 @@
- if @merge_request.source_branch_exists?
= render "projects/merge_requests/how_to_merge"
-# haml-lint:disable InlineJavaScript
:javascript
window.gl.mrWidgetData = #{serialize_issuable(@merge_request)}
#js-vue-mr-widget.mr-widget
- content_for :page_specific_javascripts do
= webpack_bundle_tag 'common_vue'
= webpack_bundle_tag 'vue_merge_request_widget'
.content-block.content-block-small.emoji-list-container
@ -88,10 +88,3 @@
= render "projects/commit/change", type: 'revert', commit: @merge_request.merge_commit, title: @merge_request.title
- if @merge_request.can_be_cherry_picked?
= render "projects/commit/change", type: 'cherry-pick', commit: @merge_request.merge_commit, title: @merge_request.title
:javascript
$(function () {
window.mergeRequest = new MergeRequest({
action: "#{j params[:tab].presence || 'show'}",
});
});

View File

@ -72,7 +72,7 @@
%div
- if fogbugz_import_enabled?
= link_to new_import_fogbugz_path, class: 'btn import_fogbugz' do
= icon('bug', text: 'Fogbugz')
= icon('bug', text: 'FogBugz')
%div
- if gitea_import_enabled?
= link_to new_import_gitea_url, class: 'btn import_gitea' do

View File

@ -1,15 +1,11 @@
- @no_container = true
- breadcrumb_title "Project"
- @content_class = "limit-container-width" unless fluid_layout
- flash_message_container = show_new_nav? ? :new_global_flash : :flash_message
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity")
= content_for flash_message_container do
- if current_user && can?(current_user, :download_code, @project)
= render 'shared/no_ssh'
= render 'shared/no_password'
= render partial: 'flash_messages', locals: { project: @project }
= render "projects/head"
= render "projects/last_push"

View File

@ -1,6 +1,6 @@
- if @projects.any?
.project-item-select-holder
= project_select_tag :project_path, class: "project-item-select", data: { include_groups: local_assigns[:include_groups], order_by: 'last_activity_at' }, with_feature_enabled: local_assigns[:with_feature_enabled]
%a.btn.btn-new.new-project-item-select-button{ data: { relative_path: local_assigns[:path] } }
= project_select_tag :project_path, class: "project-item-select", data: { include_groups: local_assigns[:include_groups], order_by: 'last_activity_at', relative_path: local_assigns[:path] }, with_feature_enabled: local_assigns[:with_feature_enabled]
%a.btn.btn-new.new-project-item-select-button
= local_assigns[:label]
= icon('caret-down')

View File

@ -0,0 +1,3 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14" viewBox="0 0 14 14">
<path d="M13 12.75v-8.5q0-0.102-0.074-0.176t-0.176-0.074h-8.5q-0.102 0-0.176 0.074t-0.074 0.176v8.5q0 0.102 0.074 0.176t0.176 0.074h8.5q0.102 0 0.176-0.074t0.074-0.176zM14 4.25v8.5q0 0.516-0.367 0.883t-0.883 0.367h-8.5q-0.516 0-0.883-0.367t-0.367-0.883v-8.5q0-0.516 0.367-0.883t0.883-0.367h8.5q0.516 0 0.883 0.367t0.367 0.883zM11 1.25v1.25h-1v-1.25q0-0.102-0.074-0.176t-0.176-0.074h-8.5q-0.102 0-0.176 0.074t-0.074 0.176v8.5q0 0.102 0.074 0.176t0.176 0.074h1.25v1h-1.25q-0.516 0-0.883-0.367t-0.367-0.883v-8.5q0-0.516 0.367-0.883t0.883-0.367h8.5q0.516 0 0.883 0.367t0.367 0.883z"></path>
</svg>

After

Width:  |  Height:  |  Size: 735 B

View File

@ -4,5 +4,5 @@
= link_to user, title: user.name, class: "darken" do
= image_tag avatar_icon(user, 32), class: "avatar s32"
%strong= truncate(user.name, length: 40)
%br
%small.cgray= user.username
%div
%small.cgray= user.username

View File

@ -6,15 +6,12 @@ class PipelineScheduleWorker
Ci::PipelineSchedule.active.where("next_run_at < ?", Time.now)
.preload(:owner, :project).find_each do |schedule|
begin
unless schedule.runnable_by_owner?
schedule.deactivate!
next
end
Ci::CreatePipelineService.new(schedule.project,
schedule.owner,
ref: schedule.ref)
pipeline = Ci::CreatePipelineService.new(schedule.project,
schedule.owner,
ref: schedule.ref)
.execute(:schedule, save_on_errors: false, schedule: schedule)
schedule.deactivate! unless pipeline.persisted?
rescue => e
Rails.logger.error "#{schedule.id}: Failed to create a scheduled pipeline: #{e.message}"
ensure

View File

@ -3,14 +3,11 @@ class ProjectDestroyWorker
include DedicatedSidekiqQueue
def perform(project_id, user_id, params)
begin
project = Project.unscoped.find(project_id)
rescue ActiveRecord::RecordNotFound
return
end
project = Project.find(project_id)
user = User.find(user_id)
::Projects::DestroyService.new(project, user, params.symbolize_keys).execute
rescue ActiveRecord::RecordNotFound => error
logger.error("Failed to delete project (#{project_id}): #{error.message}")
end
end

View File

@ -0,0 +1,4 @@
---
title: Declare related resources into V4 API entities
merge_request:
author:

View File

@ -0,0 +1,4 @@
---
title: Added /duplicate quick action to close a duplicate issue
merge_request: 12845
author: Ryan Scott

View File

@ -0,0 +1,4 @@
---
title: Handle errors while a project is being deleted asynchronously.
merge_request: 11088
author:

View File

@ -0,0 +1,4 @@
---
title: Fix vertical alignment in firefox and safari for pipeline mini graph
merge_request:
author:

View File

@ -0,0 +1,5 @@
---
title: Disallow running the pipeline if ref is protected and user cannot merge the
branch or create the tag
merge_request: 11910
author:

View File

@ -0,0 +1,4 @@
---
title: Remove project_key from the Jira configuration
merge_request: 12050
author:

View File

@ -0,0 +1,4 @@
---
title: Add CSRF token verification to API
merge_request: 12154
author: Vitaliy @blackst0ne Klachkov

View File

@ -0,0 +1,4 @@
---
title: Added link to the MR widget that directs to the monitoring dashboard
merge_request:
author:

View File

@ -0,0 +1,4 @@
---
title: Remove help message about prioritized labels for non-members
merge_request: 12912
author: Takuya Noguchi

View File

@ -0,0 +1,4 @@
---
title: Add link to doc/api/ci/lint.md
merge_request: 12914
author: Takuya Noguchi

View File

@ -0,0 +1,4 @@
---
title: Pending delete projects should not show in deploy keys.
merge_request: 13088
author:

View File

@ -1,4 +0,0 @@
---
title: Fix margins in the mini graph for pipeline in commits box
merge_request:
author:

View File

@ -1,4 +0,0 @@
---
title: Fix anonymous access to public projects in groups with pending invites
merge_request:
author:

View File

@ -0,0 +1,4 @@
---
title: Fixes 500 error caused by pending delete projects in admin dashboard
merge_request: 13067
author:

View File

@ -0,0 +1,4 @@
---
title: Allow admin to read_users_list even if it's restricted
merge_request: 13066
author:

View File

@ -0,0 +1,5 @@
---
title: Fix creating merge request diffs when diff contains bytes that are invalid
in UTF-8
merge_request:
author:

View File

@ -0,0 +1,4 @@
---
title: Add instrumentation to MarkupHelper#link_to_gfm
merge_request: 13069
author:

View File

@ -0,0 +1,4 @@
---
title: Prevent LDAP login callback from being called with a GET request
merge_request: 13059
author:

View File

@ -1,4 +0,0 @@
---
title: Fix some invalid entries in PO files
merge_request: 13032
author:

View File

@ -1,5 +0,0 @@
---
title: Fix cross site request protection when logging in as a regular user when LDAP
is enabled
merge_request: 13049
author:

View File

@ -0,0 +1,5 @@
---
title: Free up some top level words, reject top level groups named like files in the
public folder
merge_request: 12932
author:

View File

@ -0,0 +1,4 @@
---
title: Support custom directory in gitlab:backup:create task
merge_request: 12984
author: Markus Koller

View File

@ -0,0 +1,4 @@
---
title: Fix job merge request link to a forked source project
merge_request: 12965
author:

View File

@ -0,0 +1,4 @@
---
title: Handle maximum pages artifacts size correctly
merge_request: 13072
author:

View File

@ -1,4 +0,0 @@
---
title: Fix editing project with container images present
merge_request: 13028
author:

View File

@ -1,4 +0,0 @@
---
title: Fix pipeline_schedules pages throwing error 500 (when ref is empty)
merge_request: 12983
author:

View File

@ -1,4 +0,0 @@
---
title: Fixed issue boards sidebar close icon size
merge_request:
author:

View File

@ -0,0 +1,4 @@
---
title: Add LDAP SSL certificate verification option
merge_request:
author:

View File

@ -0,0 +1,4 @@
---
title: Improve redirect route query performance
merge_request: 13062
author:

View File

@ -1,4 +0,0 @@
---
title: Fixed duplicate new milestone buttons when new navigation is turned on
merge_request:
author:

View File

@ -0,0 +1,4 @@
---
title: Fix sizing of custom header logo in new navigation
merge_request:
author:

View File

@ -0,0 +1,4 @@
---
title: Ensure filesystem metrics test files are deleted
merge_request:
author:

View File

@ -1,4 +0,0 @@
---
title: Fix bug causing metrics files to be truncated
merge_request: 35420
author:

View File

@ -0,0 +1,4 @@
---
title: Enable gitaly_post_upload_pack by default
merge_request: 13078
author:

View File

@ -0,0 +1,5 @@
---
title: Fix the /projects/:id/repository/branches endpoint to handle dots in the branch
name when the project full patch contains a `/`
merge_request: 13115
author:

View File

@ -0,0 +1,4 @@
---
title: Add author_id & assignee_id param to /issues API
merge_request: 13004
author:

View File

@ -228,7 +228,8 @@ production: &base
# ==========================
## LDAP settings
# You can inspect a sample of the LDAP users with login access by running:
# You can test connections and inspect a sample of the LDAP users with login
# access by running:
# bundle exec rake gitlab:ldap:check RAILS_ENV=production
ldap:
enabled: false
@ -251,13 +252,45 @@ production: &base
# Example: 'Paris' or 'Acme, Ltd.'
label: 'LDAP'
# Example: 'ldap.mydomain.com'
host: '_your_ldap_server'
port: 389
uid: 'sAMAccountName'
method: 'plain' # "tls" or "ssl" or "plain"
# This port is an example, it is sometimes different but it is always an integer and not a string
port: 389 # usually 636 for SSL
uid: 'sAMAccountName' # This should be the attribute, not the value that maps to uid.
# Examples: 'america\\momo' or 'CN=Gitlab Git,CN=Users,DC=mydomain,DC=com'
bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
password: '_the_password_of_the_bind_user'
# Encryption method. The "method" key is deprecated in favor of
# "encryption".
#
# Examples: "start_tls" or "simple_tls" or "plain"
#
# Deprecated values: "tls" was replaced with "start_tls" and "ssl" was
# replaced with "simple_tls".
#
encryption: 'plain'
# Enables SSL certificate verification if encryption method is
# "start_tls" or "simple_tls". (Defaults to false for backward-
# compatibility)
verify_certificates: false
# Specifies the path to a file containing a PEM-format CA certificate,
# e.g. if you need to use an internal CA.
#
# Example: '/etc/ca.pem'
#
ca_cert: ''
# Specifies the SSL version for OpenSSL to use, if the OpenSSL default
# is not appropriate.
#
# Example: 'TLSv1_1'
#
ssl_version: ''
# Set a timeout, in seconds, for LDAP queries. This helps avoid blocking
# a request if the LDAP server becomes unresponsive.
# A value of 0 means there is no timeout.
@ -286,17 +319,20 @@ production: &base
# Base where we can search for users
#
# Ex. ou=People,dc=gitlab,dc=example
# Ex. 'ou=People,dc=gitlab,dc=example' or 'DC=mydomain,DC=com'
#
base: ''
# Filter LDAP users
#
# Format: RFC 4515 http://tools.ietf.org/search/rfc4515
# Format: RFC 4515 https://tools.ietf.org/search/rfc4515
# Ex. (employeeType=developer)
#
# Note: GitLab does not support omniauth-ldap's custom filter syntax.
#
# Example for getting only specific users:
# '(&(objectclass=user)(|(samaccountname=momo)(samaccountname=toto)))'
#
user_filter: ''
# LDAP attributes that GitLab will use to create an account for the LDAP user.
@ -674,7 +710,7 @@ test:
host: 127.0.0.1
port: 3890
uid: 'uid'
method: 'plain' # "tls" or "ssl" or "plain"
encryption: 'plain' # "start_tls" or "simple_tls" or "plain"
base: 'dc=example,dc=com'
user_filter: ''
group_base: 'ou=groups,dc=example,dc=com'

View File

@ -145,6 +145,24 @@ if Settings.ldap['enabled'] || Rails.env.test?
server['attributes'] = {} if server['attributes'].nil?
server['provider_name'] ||= "ldap#{key}".downcase
server['provider_class'] = OmniAuth::Utils.camelize(server['provider_name'])
# For backwards compatibility
server['encryption'] ||= server['method']
server['encryption'] = 'simple_tls' if server['encryption'] == 'ssl'
server['encryption'] = 'start_tls' if server['encryption'] == 'tls'
# Certificates are not verified for backwards compatibility.
# This default should be flipped to true in 9.5.
if server['verify_certificates'].nil?
server['verify_certificates'] = false
message = <<-MSG.strip_heredoc
LDAP SSL certificate verification is disabled for backwards-compatibility.
Please add the "verify_certificates" option to gitlab.yml for each LDAP
server. Certificate verification will be enabled by default in GitLab 9.5.
MSG
Rails.logger.warn(message)
end
end
end
@ -441,10 +459,6 @@ Settings.backup['pg_schema'] = nil
Settings.backup['path'] = Settings.absolute(Settings.backup['path'] || "tmp/backups/")
Settings.backup['archive_permissions'] ||= 0600
Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil })
# Convert upload connection settings to use symbol keys, to make Fog happy
if Settings.backup['upload']['connection']
Settings.backup['upload']['connection'] = Hash[Settings.backup['upload']['connection'].map { |k, v| [k.to_sym, v] }]
end
Settings.backup['upload']['multipart_chunk_size'] ||= 104857600
Settings.backup['upload']['encryption'] ||= nil
Settings.backup['upload']['storage_class'] ||= nil

View File

@ -6,7 +6,7 @@ Prometheus::Client.configure do |config|
config.initial_mmap_file_size = 4 * 1024
config.multiprocess_files_dir = ENV['prometheus_multiproc_dir']
if Rails.env.development? && Rails.env.test?
if Rails.env.development? || Rails.env.test?
config.multiprocess_files_dir ||= Rails.root.join('tmp/prometheus_multiproc_dir')
end
end

View File

@ -114,6 +114,9 @@ def instrument_classes(instrumentation)
# This is a Rails scope so we have to instrument it manually.
instrumentation.instrument_method(Project, :visible_to_user)
# Needed for https://gitlab.com/gitlab-org/gitlab-ce/issues/34509
instrumentation.instrument_method(MarkupHelper, :link_to_gfm)
# Needed for https://gitlab.com/gitlab-org/gitlab-ce/issues/30224#note_32306159
instrumentation.instrument_instance_method(MergeRequestDiff, :load_commits)
end

View File

@ -0,0 +1,35 @@
if defined?(GrapeRouteHelpers)
module GrapeRouteHelpers
class DecoratedRoute
# GrapeRouteHelpers gem tries to parse the versions
# from a string, not supporting Grape `version` array definition.
#
# Without the following fix, we get this on route helpers generation:
#
# => undefined method `scan' for ["v3", "v4"]
#
# 2.0.0 implementation of this method:
#
# ```
# def route_versions
# version_pattern = /[^\[",\]\s]+/
# if route_version
# route_version.scan(version_pattern)
# else
# [nil]
# end
# end
# ```
def route_versions
return [nil] if route_version.nil? || route_version.empty?
if route_version.is_a?(String)
version_pattern = /[^\[",\]\s]+/
route_version.scan(version_pattern)
else
route_version
end
end
end
end
end

View File

@ -16,7 +16,7 @@ OmniAuth.config.allowed_request_methods = [:post]
# In case of auto sign-in, the GET method is used (users don't get to click on a button)
OmniAuth.config.allowed_request_methods << :get if Gitlab.config.omniauth.auto_sign_in_with_provider.present?
OmniAuth.config.before_request_phase do |env|
OmniAuth::RequestForgeryProtection.call(env)
Gitlab::RequestForgeryProtection.call(env)
end
if Gitlab.config.omniauth.enabled

Some files were not shown because too many files have changed in this diff Show More