Commit 85e50301 authored by tiagonbotelho's avatar tiagonbotelho

Merge branch 'master' into rename-repo-files

parents 28f85155 cd546a78
Please view this file on the master branch, on stable branches it's out of date.
v 8.11.0 (unreleased)
- Fix of 'Commits being passed to custom hooks are already reachable when using the UI'
v 8.10.0 (unreleased)
- Fix profile activity heatmap to show correct day name (eanplatter)
- Expose {should,force}_remove_source_branch (Ben Boeckel)
- Add the functionality to be able to rename a file. !5049 (tiagonbotelho)
- Disable PostgreSQL statement timeout during migrations
......@@ -26,6 +29,7 @@ v 8.10.0 (unreleased)
- Add a new column `artifacts_size` to table `ci_builds` !4964
- Let Workhorse serve format-patch diffs
- Display tooltip for mentioned users and groups !5261 (winniehell)
- Allow build email service to be tested
- Added day name to contribution calendar tooltips
- Make images fit to the size of the viewport !4810
- Fix check for New Branch button on Issue page !4630 (winniehell)
......@@ -34,6 +38,7 @@ v 8.10.0 (unreleased)
- Fix issue, preventing users w/o push access to sort tags !5105 (redetection)
- Add Spring EmojiOne updates.
- Fix fetching LFS objects for private CI projects
- Add the new 2016 Emoji! Adds 72 new emoji including bacon, facepalm, and selfie. !5237
- Add syntax for multiline blockquote using `>>>` fence !3954
- Fix viewing notification settings when a project is pending deletion
- Updated compare dropdown menus to use GL dropdown
......@@ -56,6 +61,7 @@ v 8.10.0 (unreleased)
- Add "Enabled Git access protocols" to Application Settings
- Diffs will create button/diff form on demand no on server side
- Reduce size of HTML used by diff comment forms
- Protected branches have a "Developers can Merge" setting. !4892 (original implementation by Mathias Vestergaard)
- Fix user creation with stronger minimum password requirements !4054 (nathan-pmt)
- Only show New Snippet button to users that can create snippets.
- PipelinesFinder uses git cache data
......@@ -102,6 +108,7 @@ v 8.10.0 (unreleased)
- Add min value for project limit field on user's form !3622 (jastkand)
- Reset project pushes_since_gc when we enqueue the git gc call
- Add reminder to not paste private SSH keys !4399 (Ingo Blechschmidt)
- Collapsed diffs lines/size don't acumulate to overflow diffs.
- Remove duplicate `description` field in `MergeRequest` entities (Ben Boeckel)
- Style of import project buttons were fixed in the new project page. !5183 (rdemirbay)
- Fix GitHub client requests when rate limit is disabled
......@@ -113,9 +120,13 @@ v 8.10.0 (unreleased)
- Fix last update timestamp on issues not preserved on gitlab.com and project imports
- Fix issues importing projects from EE to CE
- Fix creating group with space in group path
- Improve cron_jobs loading error messages !5318
- Create Todos for Issue author when assign or mention himself (Katarzyna Kobierska)
- Limit the number of retries on error to 3 for exporting projects
- Allow empty repositories on project import/export
- Render only commit message title in builds (Katarzyna Kobierska Ula Budziszewska)
- Allow bulk (un)subscription from issues in issue index
- Fix MR diff encoding issues exporting GitLab projects
v 8.9.6
- Fix importing of events under notes for GitLab projects. !5154
......
......@@ -52,7 +52,7 @@ gem 'browser', '~> 2.2'
# Extracting information from a git repository
# Provide access to Gitlab::Git library
gem 'gitlab_git', '~> 10.2'
gem 'gitlab_git', '~> 10.3.2'
# LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes
......@@ -223,7 +223,7 @@ gem 'jquery-turbolinks', '~> 2.1.0'
gem 'addressable', '~> 2.3.8'
gem 'bootstrap-sass', '~> 3.3.0'
gem 'font-awesome-rails', '~> 4.6.1'
gem 'gemojione', '~> 2.6'
gem 'gemojione', '~> 3.0'
gem 'gon', '~> 6.0.1'
gem 'jquery-atwho-rails', '~> 1.3.2'
gem 'jquery-rails', '~> 4.1.0'
......@@ -349,3 +349,6 @@ gem 'health_check', '~> 2.1.0'
# System information
gem 'vmstat', '~> 2.1.0'
gem 'sys-filesystem', '~> 1.1.6'
# Secure headers for Content Security Policy
gem 'secure_headers', '~> 3.3'
......@@ -255,7 +255,7 @@ GEM
ruby-progressbar (~> 1.4)
gemnasium-gitlab-service (0.2.6)
rugged (~> 0.21)
gemojione (2.6.1)
gemojione (3.0.1)
json
get_process_mem (0.2.0)
gherkin-ruby (0.3.2)
......@@ -274,7 +274,7 @@ GEM
diff-lcs (~> 1.1)
mime-types (>= 1.16, < 3)
posix-spawn (~> 0.3)
gitlab_git (10.3.0)
gitlab_git (10.3.2)
activesupport (~> 4.0)
charlock_holmes (~> 0.7.3)
github-linguist (~> 4.7.0)
......@@ -645,6 +645,8 @@ GEM
sdoc (0.3.20)
json (>= 1.1.3)
rdoc (~> 3.10)
secure_headers (3.3.2)
useragent
seed-fu (2.3.6)
activerecord (>= 3.1)
activesupport (>= 3.1)
......@@ -767,6 +769,7 @@ GEM
get_process_mem (~> 0)
unicorn (>= 4, < 6)
uniform_notifier (1.9.0)
useragent (0.16.7)
uuid (2.3.8)
macaddr (~> 1.0)
version_sorter (2.0.0)
......@@ -857,11 +860,11 @@ DEPENDENCIES
foreman (~> 0.78.0)
fuubar (~> 2.0.0)
gemnasium-gitlab-service (~> 0.2)
gemojione (~> 2.6)
gemojione (~> 3.0)
github-linguist (~> 4.7.0)
github-markup (~> 1.4)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab_git (~> 10.2)
gitlab_git (~> 10.3.2)
gitlab_meta (= 7.0)
gitlab_omniauth-ldap (~> 1.2.1)
gollum-lib (~> 4.2)
......@@ -944,6 +947,7 @@ DEPENDENCIES
sass-rails (~> 5.0.0)
scss_lint (~> 0.47.0)
sdoc (~> 0.3.20)
secure_headers (~> 3.3)
seed-fu (~> 2.3.5)
select2-rails (~> 3.5.9)
sentry-raven (~> 1.1.0)
......
# GitLab Maintenance Policy
GitLab is a fast moving and evolving project. We currently don't have the resources to support many releases concurrently. We support exactly one stable release at any given time.
GitLab follows the [Semantic Versioning](http://semver.org/) for its releases:
`(Major).(Minor).(Patch)` in a [pragmatic way].
GitLab follows the [Semantic Versioning](http://semver.org/) for its releases: `(Major).(Minor).(Patch)` in a [pragmatic way](https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e).
- **Major version**: Whenever there is something significant or any backwards
incompatible changes are introduced to the public API.
- **Minor version**: When new, backwards compatible functionality is introduced
to the public API or a minor feature is introduced, or when a set of smaller
features is rolled out.
- **Patch number**: When backwards compatible bug fixes are introduced that fix
incorrect behavior.
- **Major version**: Whenever there is something significant or any backwards incompatible changes are introduced to the public API.
- **Minor version**: When new, backwards compatible functionality is introduced to the public API or a minor feature is introduced, or when a set of smaller features is rolled out.
- **Patch number**: When backwards compatible bug fixes are introduced that fix incorrect behavior.
The current stable release will receive security patches and bug fixes
(eg. `8.9.0` -> `8.9.1`). Feature releases will mark the next supported stable
release where the minor version is increased numerically by increments of one
(eg. `8.9 -> 8.10`).
The current stable release will receive security patches and bug fixes (eg. `5.0` -> `5.0.1`). Feature releases will mark the next supported stable release where the minor version is increased numerically by increments of one (eg. `5.0 -> 5.1`).
Our current policy is to support one stable release at any given time, but for
medium-level security issues, we may consider [backporting to the previous two
monthly releases][rel-sec].
We encourage everyone to run the latest stable release to ensure that you can easily upgrade to the most secure and feature rich GitLab experience. In order to make sure you can easily run the most recent stable release, we are working hard to keep the update process simple and reliable.
We encourage everyone to run the latest stable release to ensure that you can
easily upgrade to the most secure and feature-rich GitLab experience. In order
to make sure you can easily run the most recent stable release, we are working
hard to keep the update process simple and reliable.
More information about the release procedures can be found in the doc/release directory.
More information about the release procedures can be found in our
[release-tools documentation][rel]. You may also want to read our
[Responsible Disclosure Policy][disclosure].
[rel-sec]: https://gitlab.com/gitlab-org/release-tools/blob/master/doc/security.md#backporting
[rel]: https://gitlab.com/gitlab-org/release-tools/blob/master/doc/
[disclosure]: https://about.gitlab.com/disclosure/
[pragmatic way]: https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e
app/assets/images/emoji.png

1000 KB | W: | H:

app/assets/images/emoji.png

1.04 MB | W: | H:

app/assets/images/emoji.png
app/assets/images/emoji.png
app/assets/images/emoji.png
app/assets/images/emoji.png
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/emoji@2x.png

2.38 MB | W: | H:

app/assets/images/emoji@2x.png

2.53 MB | W: | H:

app/assets/images/emoji@2x.png
app/assets/images/emoji@2x.png
app/assets/images/emoji@2x.png
app/assets/images/emoji@2x.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -250,6 +250,8 @@ class GitLabDropdown
if self.options.clicked
self.options.clicked(selected, $el, e)
$el.trigger('blur')
# Finds an element inside wrapper element
getElement: (selector) ->
@dropdown.find selector
......
......@@ -85,12 +85,13 @@ class @IssuableBulkActions
getFormDataAsObject: ->
formData =
update:
state_event : @form.find('input[name="update[state_event]"]').val()
assignee_id : @form.find('input[name="update[assignee_id]"]').val()
milestone_id : @form.find('input[name="update[milestone_id]"]').val()
issues_ids : @form.find('input[name="update[issues_ids]"]').val()
add_label_ids : []
remove_label_ids : []
state_event : @form.find('input[name="update[state_event]"]').val()
assignee_id : @form.find('input[name="update[assignee_id]"]').val()
milestone_id : @form.find('input[name="update[milestone_id]"]').val()
issues_ids : @form.find('input[name="update[issues_ids]"]').val()
subscription_event : @form.find('input[name="update[subscription_event]"]').val()
add_label_ids : []
remove_label_ids : []
if @willUpdateLabels
@getLabelsToApply().map (id) ->
......
......@@ -2,7 +2,7 @@
w.gl ?= {}
w.gl.utils ?= {}
w.gl.utils.days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
w.gl.utils.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
w.gl.utils.formatDate = (datetime) ->
dateFormat(datetime, 'mmm d, yyyy h:MMtt Z')
......
$ ->
$(".protected-branches-list :checkbox").change (e) ->
name = $(this).attr("name")
if name == "developers_can_push"
if name == "developers_can_push" || name == "developers_can_merge"
id = $(this).val()
checked = $(this).is(":checked")
can_push = $(this).is(":checked")
url = $(this).data("url")
$.ajax
type: "PUT"
type: "PATCH"
url: url
dataType: "json"
data:
id: id
protected_branch:
developers_can_push: checked
"#{name}": can_push
success: ->
row = $(e.target)
......
class @SubscriptionSelect
constructor: ->
$('.js-subscription-event').each (i, el) ->
fieldName = $(el).data("field-name")
$(el).glDropdown(
selectable: true
fieldName: fieldName
toggleLabel: (selected, el, instance) =>
label = 'Subscription'
$item = instance.dropdown.find('.is-active')
label = $item.text() if $item.length
label
clicked: (item, $el, e)->
e.preventDefault()
id: (obj, el) ->
$(el).data("id")
)
......@@ -70,7 +70,7 @@
}
&.wiki {
padding: $gl-padding;
padding: 30px $gl-padding;
.highlight {
margin-bottom: 9px;
......
......@@ -37,39 +37,41 @@
}
h1 {
font-size: 1.3em;
font-size: 2em;
font-weight: 600;
margin: 24px 0 12px;
padding: 0 0 10px;
border-bottom: 1px solid #e7e9ed;
margin: 1em 0 10px;
padding: 0 0 0.3em;
border-bottom: 1px solid $btn-default-border;
color: $gl-gray-dark;
}
h2 {
font-size: 1.2em;
font-size: 1.6em;
font-weight: 600;
margin: 24px 0 12px;
margin: 1em 0 10px;
padding-bottom: 0.3em;
border-bottom: 1px solid $btn-default-border;
color: $gl-gray-dark;
}
h3 {
margin: 24px 0 12px;
font-size: 1.1em;
margin: 1em 0 10px;
font-size: 1.4em;
}
h4 {
margin: 24px 0 12px;
font-size: 0.98em;
margin: 1em 0 10px;
font-size: 1.25em;
}
h5 {
margin: 24px 0 12px;
font-size: 0.95em;
margin: 1em 0 10px;
font-size: 1em;
}
h6 {
margin: 24px 0 12px;
font-size: 0.90em;
margin: 1em 0 10px;
font-size: 0.95em;
}
blockquote {
......@@ -115,7 +117,7 @@
ul, ol {
padding: 0;
margin: 6px 0 6px 28px !important;
margin: 3px 0 3px 28px !important;
}
li {
......
......@@ -16,7 +16,7 @@ $border-color: #e5e5e5;
$focus-border-color: #3aabf0;
$table-border-color: #f0f0f0;
$background-color: #fafafa;
$dark-background-color: #f7f7f7;
$dark-background-color: #f5f5f5;
$table-text-gray: #8f8f8f;
/*
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -270,7 +270,7 @@
.item-title {
@media (min-width: $screen-sm-min) {
width: 49%;
width: 45%;
}
}
......
......@@ -19,7 +19,7 @@
border-top: 1px solid $table-border-gray;
td, th {
line-height: 23px;
line-height: 21px;
}
&:hover {
......
......@@ -10,7 +10,6 @@ module DiffForPath
diff_commit = commit_for_diff(diff_file)
blob = diff_file.blob(diff_commit)
@expand_all_diffs = true
locals = {
diff_file: diff_file,
......
......@@ -226,6 +226,7 @@ class Projects::IssuesController < Projects::ApplicationController
:assignee_id,
:milestone_id,
:state_event,
:subscription_event,
label_ids: [],
add_label_ids: [],
remove_label_ids: []
......
......@@ -50,6 +50,6 @@ class Projects::ProtectedBranchesController < Projects::ApplicationController
end
def protected_branch_params
params.require(:protected_branch).permit(:name, :developers_can_push)
params.require(:protected_branch).permit(:name, :developers_can_push, :developers_can_merge)
end
end
......@@ -45,8 +45,9 @@ class Projects::ServicesController < Projects::ApplicationController
end
def test
data = Gitlab::PushDataBuilder.build_sample(project, current_user)
data = @service.test_data(project, current_user)
outcome = @service.test(data)
if outcome[:success]
message = { notice: 'We sent a request to the provided URL' }
else
......
......@@ -12,7 +12,7 @@ module BranchesHelper
def can_push_branch?(project, branch_name)
return false unless project.repository.branch_exists?(branch_name)
::Gitlab::GitAccess.new(current_user, project, 'web').can_push_to_branch?(branch_name)
::Gitlab::UserAccess.new(current_user, project: project).can_push_to_branch?(branch_name)
end
def project_branches
......
......@@ -9,7 +9,7 @@ module DiffHelper
end
def expand_all_diffs?
@expand_all_diffs || params[:expand_all_diffs].present?
params[:expand_all_diffs].present?
end
def diff_view
......@@ -23,13 +23,14 @@ module DiffHelper
end
def diff_options
default_options = Commit.max_diff_options
options = { ignore_whitespace_change: hide_whitespace?, no_collapse: expand_all_diffs? }
if action_name == 'diff_for_path'
default_options[:paths] = params.values_at(:old_path, :new_path)
options[:no_collapse] = true
options[:paths] = params.values_at(:old_path, :new_path)
end
default_options.merge(ignore_whitespace_change: hide_whitespace?)
Commit.max_diff_options.merge(options)
end
def safe_diff_files(diffs, diff_refs: nil, repository: nil)
......
......@@ -6,6 +6,7 @@ module Emails
add_project_headers
add_build_headers('failed')
mail(to: to, subject: subject("Build failed for #{@project.name}", @build.short_sha))
end
......
......@@ -51,6 +51,10 @@ module Ci
commit.try(:message)
end
def git_commit_title
commit.try(:title)
end
def short_sha
Ci::Pipeline.truncate_sha(sha)
end
......
......@@ -552,7 +552,13 @@ class MergeRequest < ActiveRecord::Base
end
def can_be_merged_by?(user)
::Gitlab::GitAccess.new(user, project, 'web').can_push_to_branch?(target_branch)
access = ::Gitlab::UserAccess.new(user, project: project)
access.can_push_to_branch?(target_branch) || access.can_merge_to_branch?(target_branch)
end
def can_be_merged_via_command_line_by?(user)
access = ::Gitlab::UserAccess.new(user, project: project)
access.can_push_to_branch?(target_branch)
end
def mergeable_ci_state?
......
class MergeRequestDiff < ActiveRecord::Base
include Sortable
include Importable
include EncodingHelper
# Prevent store of diff if commits amount more then 500
COMMITS_SAFE_SIZE = 100
......@@ -211,6 +212,14 @@ class MergeRequestDiff < ActiveRecord::Base
branch_base_commit.try(:sha)
end
def utf8_st_diffs
st_diffs.map do |diff|
diff.each do |k, v|
diff[k] = encode_utf8(v) if v.respond_to?(:encoding)
end
end
end
#
# #save or #update_attributes providing changes on serialized attributes do a lot of
# serialization and deserialization calls resulting in bad performance.
......
......@@ -838,6 +838,10 @@ class Project < ActiveRecord::Base
protected_branches.matching(branch_name).any?(&:developers_can_push)
end
def developers_can_merge_to_protected_branch?(branch_name)
protected_branches.matching(branch_name).any?(&:developers_can_merge)
end
def forked?
!(forked_project_link.nil? || forked_project_link.forked_from_project.nil?)
end
......
......@@ -42,6 +42,19 @@ class BuildsEmailService < Service
end
end
def can_test?
project.builds.count > 0
end
def disabled_title
"Please setup a build on your repository."
end
def test_data(project = nil, user = nil)
build = project.builds.last
Gitlab::BuildDataBuilder.build(build)
end
def fields
[
{ type: 'textarea', name: 'recipients', placeholder: 'Emails separated by comma' },
......@@ -50,6 +63,20 @@ class BuildsEmailService < Service
]
end
def test(data)
begin
# bypass build status verification when testing
data[:build_status] = "failed"
data[:build_allow_failure] = false
result = execute(data)
rescue StandardError => error
return { success: false, result: error }
end
{ success: true, result: result }
end
def should_build_be_notified?(data)
case data[:build_status]
when 'success'
......
......@@ -704,6 +704,7 @@ class Repository
options[:commit] = {
message: message,
branch: ref,
update_ref: false,
}
raw_repository.mkdir(path, options)
......@@ -719,6 +720,7 @@ class Repository
options[:commit] = {
message: message,
branch: ref,
update_ref: false,
}
options[:file] = {
......@@ -765,7 +767,8 @@ class Repository
options[:author] = committer
options[:commit] = {
message: message,
branch: ref
branch: ref,
update_ref: false,
}
options[:file] = {
......@@ -795,9 +798,9 @@ class Repository
end
end
def merge(user, source_sha, target_branch, options = {})
our_commit = rugged.branches[target_branch].target
their_commit = rugged.lookup(source_sha)
def merge(user, merge_request, options = {})
our_commit = rugged.branches[merge_request.target_branch].target
their_commit = rugged.lookup(merge_request.diff_head_sha)
raise "Invalid merge target" if our_commit.nil?
raise "Invalid merge source" if their_commit.nil?
......@@ -805,14 +808,15 @@ class Repository
merge_index = rugged.merge_commits(our_commit, their_commit)
return false if merge_index.conflicts?
commit_with_hooks(user, target_branch) do |ref|
commit_with_hooks(user, merge_request.target_branch) do
actual_options = options.merge(
parents: [our_commit, their_commit],
tree: merge_index.write_tree(rugged),
update_ref: ref
)
Rugged::Commit.create(rugged, actual_options)
commit_id = Rugged::Commit.create(rugged, actual_options)
merge_request.update(in_progress_merge_commit_sha: commit_id)
commit_id
end
end
......@@ -822,15 +826,14 @@ class Repository
return false unless revert_tree_id
commit_with_hooks(user, base_branch) do |ref|
commit_with_hooks(user, base_branch) do
committer = user_to_committer(user)
source_sha = Rugged::Commit.create(rugged,
message: commit.revert_message,
author: committer,
committer: committer,
tree: revert_tree_id,
parents: [rugged.lookup(source_sha)],
update_ref: ref)
parents: [rugged.lookup(source_sha)])
end
end
......@@ -840,7 +843,7 @@ class Repository
return false unless cherry_pick_tree_id
commit_with_hooks(user, base_branch) do |ref|
commit_with_hooks(user, base_branch) do
committer = user_to_committer(user)
source_sha = Rugged::Commit.create(rugged,
message: commit.message,
......@@ -851,8 +854,7 @@ class Repository
},
committer: committer,
tree: cherry_pick_tree_id,
parents: [rugged.lookup(source_sha)],
update_ref: ref)
parents: [rugged.lookup(source_sha)])
end
end
......@@ -953,20 +955,6 @@ class Repository
Gitlab::Popen.popen(args, path_to_repo)
end
def with_tmp_ref(oldrev = nil)
random_string = SecureRandom.hex
tmp_ref = "refs/tmp/#{random_string}/head"
if oldrev && !Gitlab::Git.blank_ref?(oldrev)
rugged.references.create(tmp_ref, oldrev)
end
# Make commit in tmp ref
yield(tmp_ref)
ensure
rugged.references.delete(tmp_ref) rescue nil
end
def commit_with_hooks(current_user, branch)
update_autocrlf_option
......@@ -979,33 +967,31 @@ class Repository
oldrev = target_branch.target
end
with_tmp_ref(oldrev) do |tmp_ref|
# Make commit in tmp ref
newrev = yield(tmp_ref)
# Make commit
newrev = yield(ref)
unless newrev
raise CommitError.new('Failed to create commit')
end
unless newrev
raise CommitError.new('Failed to create commit')
end
GitHooksService.new.execute(current_user, path_to_repo, oldrev, newrev, ref) do
if was_empty || !target_branch
# Create branch
rugged.references.create(ref, newrev)
GitHooksService.new.execute(current_user, path_to_repo, oldrev, newrev, ref) do
if was_empty || !target_branch
# Create branch
rugged.references.create(ref, newrev)
else
# Update head
current_head = find_branch(branch).target
# Make sure target branch was not changed during pre-receive hook
if current_head == oldrev
rugged.references.update(ref, newrev)
else
# Update head
current_head = find_branch(branch).target
# Make sure target branch was not changed during pre-receive hook
if current_head == oldrev
rugged.references.update(ref, newrev)
else
raise CommitError.new('Commit was rejected because branch received new push')
end
raise CommitError.new('Commit was rejected because branch received new push')
end
end
newrev
end
newrev
end
def ls_files(ref)
......
......@@ -76,6 +76,10 @@ class Service < ActiveRecord::Base
[]
end
def test_data(project, user)
Gitlab::PushDataBuilder.build_sample(project, user)
end
def supported_events
%w(push tag_push issue merge_request wiki_page)
end
......@@ -94,6 +98,11 @@ class Service < ActiveRecord::Base
!project.empty_repo?
end
# reason why service cannot be tested
def disabled_title
"Please setup a project repository."
end
# Provide convenient accessor methods
# for each serialized property.
# Also keep track of updated properties in a similar way as ActiveModel::Dirty
......
......@@ -23,7 +23,7 @@ module Commits
private
def check_push_permissions
allowed = ::Gitlab::GitAccess.new(current_user, project, 'web').can_push_to_branch?(@target_branch)
allowed = ::Gitlab::UserAccess.new(current_user, project: project).can_push_to_branch?(@target_branch)
unless allowed
raise ValidationError.new('You are not allowed to push into this branch')
......@@ -31,7 +31,7 @@ module Commits
true
end
def create_target_branch(new_branch)
# Temporary branch exists and contains the change commit
return success if repository.find_branch(new_branch)
......
......@@ -15,21 +15,19 @@ class CreateBranchService < BaseService
return error('Branch already exists')
end
new_branch = nil
if source_project != @project
repository.with_tmp_ref do |tmp_ref|
repository.fetch_ref(
source_project.repository.path_to_repo,
"refs/heads/#{ref}",
tmp_ref
)
new_branch = repository.add_branch(current_user, branch_name, tmp_ref)
end
else
new_branch = repository.add_branch(current_user, branch_name, ref)
end
new_branch = if source_project != @project
repository.fetch_ref(
source_project.repository.path_to_repo,
"refs/heads/#{ref}",
"refs/heads/#{branch_name}"
)
repository.after_create_branch
repository.find_branch(branch_name)
else
repository.add_branch(current_user, branch_name, ref)
end
if new_branch
success(new_branch)
......
......@@ -44,7 +44,7 @@ module Files
end
def validate
allowed = ::Gitlab::GitAccess.new(current_user, project, 'web').can_push_to_branch?(@target_branch)
allowed = ::Gitlab::UserAccess.new(current_user, project: project).can_push_to_branch?(@target_branch)
unless allowed
raise_error("You are not allowed to push into this branch")
......
......@@ -89,7 +89,8 @@ class GitPushService < BaseService
# Set protection on the default branch if configured
if current_application_settings.default_branch_protection != PROTECTION_NONE
developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false
@project.protected_branches.create({ name: @project.default_branch, developers_can_push: developers_can_push })
developers_can_merge = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_MERGE ? true : false
@project.protected_branches.create({ name: @project.default_branch, developers_can_push: developers_can_push, developers_can_merge: developers_can_merge })
end
end
......
......@@ -101,6 +101,7 @@ class IssuableBaseService < BaseService
def update(issuable)
change_state(issuable)
change_subscription(issuable)
filter_params
old_labels = issuable.labels.to_a
......@@ -124,6 +125,15 @@ class IssuableBaseService < BaseService
end
end
def change_subscription(issuable)
case params.delete(:subscription_event)
when 'subscribe'
issuable.subscribe(current_user)
when 'unsubscribe'
issuable.unsubscribe(current_user)
end
end
def has_changes?(issuable, old_labels: [])
valid_attrs = [:title, :description, :assignee_id, :milestone_id, :target_branch]
......
......@@ -4,7 +4,7 @@ module Issues
issues_ids = params.delete(:issues_ids).split(",")
issue_params = params
%i(state_event milestone_id assignee_id add_label_ids remove_label_ids).each do |key|
%i(state_event milestone_id assignee_id add_label_ids remove_label_ids subscription_event).each do |key|
issue_params.delete(key) unless issue_params[key].present?
end
......
......@@ -34,7 +34,7 @@ module MergeRequests
committer: committer
}
commit_id = repository.merge(current_user, merge_request.diff_head_sha, merge_request.target_branch, options)
commit_id = repository.merge(current_user, merge_request, options)
merge_request.update(merge_commit_sha: commit_id)
rescue GitHooksService::PreReceiveError => e
merge_request.update(merge_error: e.message)
......@@ -43,6 +43,8 @@ module MergeRequests
merge_request.update(merge_error: "Something went wrong during merge")
Rails.logger.error(e.message)
false
ensure
merge_request.update(in_progress_merge_commit_sha: nil)
end
def after_merge
......
......@@ -48,7 +48,7 @@ module MergeRequests
end
def force_push?
Gitlab::ForcePushCheck.force_push?(@project, @oldrev, @newrev)
Gitlab::Checks::ForcePush.force_push?(@project, @oldrev, @newrev)
end
# Refresh merge request diff if we push to source or target branch of merge request
......
.emoji-menu
= text_field_tag :emoji_search, "", class: "emoji-search search-input form-control", placeholder: "Seach emojis"
= text_field_tag :emoji_search, "", class: "emoji-search search-input form-control", placeholder: "Search emoji"
.emoji-menu-content
- Gitlab::AwardEmoji.emoji_by_category.each do |category, emojis|
%h5.emoji-menu-title
......
......@@ -94,9 +94,9 @@
.block
.title
Commit message
Commit title
%p.build-light-text.append-bottom-0
#{@build.pipeline.git_commit_message}
#{@build.pipeline.git_commit_title}
- if @build.tags.any?
.block
......
......@@ -8,12 +8,12 @@
- elsif blob_text_viewable?(blob)
- if !project.repository.diffable?(blob)
.nothing-here-block This diff was suppressed by a .gitattributes entry.
- elsif diff_file.collapsed?
- url = url_for(params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path))
.nothing-here-block.diff-collapsed{data: { diff_for_path: url } }
This diff is collapsed. Click to expand it.
- elsif diff_file.diff_lines.length > 0
- if diff_file.collapsed_by_default? && !expand_all_diffs?
- url = url_for(params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path))
.nothing-here-block.diff-collapsed{data: { diff_for_path: url } }
This diff is collapsed. Click to expand it.
- elsif diff_view == 'parallel'
- if diff_view == 'parallel'
= render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob
- else
= render "projects/diffs/text_file", diff_file: diff_file
......
......@@ -6,7 +6,7 @@
.content-block.oneline-block.files-changed
.inline-parallel-buttons
- unless expand_all_diffs?
- if !expand_all_diffs? && diff_files.any? { |diff_file| diff_file.collapsed? }
= link_to 'Expand all', url_for(params.merge(expand_all_diffs: 1, format: 'html')), class: 'btn btn-default'
- if show_whitespace_toggle
- if current_controller?(:commit)
......
......@@ -4,7 +4,7 @@
%p
Please resolve these conflicts or
- if @merge_request.can_be_merged_by?(current_user)
- if @merge_request.can_be_merged_via_command_line_by?(current_user)
#{link_to "merge this request manually", "#modal_merge_info", class: "how_to_merge_link vlink", "data-toggle" => "modal"}.
- else
ask someone with write access to this repository to merge this request manually.
......@@ -8,6 +8,7 @@
.table-responsive
%table.table.protected-branches-list
%colgroup
%col{ width: "20%" }
%col{ width: "30%" }
%col{ width: "25%" }
%col{ width: "25%" }
......@@ -18,6 +19,7 @@
%th Protected Branch
%th Commit
%th Developers Can Push
%th Developers Can Merge
- if can_admin_project
%th
%tbody
......
......@@ -16,6 +16,8 @@
(branch was removed from repository)
%td
= check_box_tag("developers_can_push", protected_branch.id, protected_branch.developers_can_push, data: { url: url })
%td
= check_box_tag("developers_can_merge", protected_branch.id, protected_branch.developers_can_merge, data: { url: url })
- if can_admin_project
%td
= link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, protected_branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-warning btn-sm pull-right"
......@@ -36,6 +36,14 @@
= f.label :developers_can_push, "Developers can push", class: "label-light append-bottom-0"
%p.light.append-bottom-0
Allow developers to push to this branch
.form-group
= f.check_box :developers_can_merge, class: "pull-left"
.prepend-left-20
= f.label :developers_can_merge, "Developers can merge", class: "label-light append-bottom-0"
%p.light.append-bottom-0
Allow developers to accept merge requests to this branch
= f.submit "Protect", class: "btn-create btn protect-branch-btn", disabled: true
%hr
= render "branches_list"
......@@ -12,5 +12,5 @@
&nbsp;
- if @service.valid? && @service.activated?
- disabled = @service.can_test? ? '':'disabled'
= link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service.to_param), class: "btn #{disabled}"
= link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service), class: "btn #{disabled}", title: @service.disabled_title
= link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel"
......@@ -44,9 +44,15 @@
placeholder: "Search authors", data: { first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: @project.id, field_name: "update[assignee_id]" } })
.filter-item.inline
= dropdown_tag("Milestone", options: { title: "Assign milestone", toggle_class: 'js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update', filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", placeholder: "Search milestones", data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), use_id: true } })
.filter-item.inline.labels-filter
= render "shared/issuable/label_dropdown", classes: ['js-filter-bulk-update', 'js-multiselect'], show_create: false, show_footer: false, extra_options: false, filter_submit: false, show_footer: false, data_options: { persist_when_hide: "true", field_name: "update[label_ids][]", show_no: false, show_any: false, use_id: true }
.filter-item.inline
= dropdown_tag("Subscription", options: { toggle_class: "js-subscription-event", title: "Change subscription", dropdown_class: "dropdown-menu-selectable", data: { field_name: "update[subscription_event]" } } ) do
%ul
%li
%a{href: "#", data: {id: "subscribe"}} Subscribe
%li
%a{href: "#", data: {id: "unsubscribe"}} Unsubscribe
= hidden_field_tag 'update[issues_ids]', []
= hidden_field_tag :state_event, params[:state_event]
......@@ -63,6 +69,7 @@
new LabelsSelect();
new MilestoneSelect();
new IssueStatusSelect();
new SubscriptionSelect();
$('form.filter-form').on('submit', function (event) {
event.preventDefault();
Turbolinks.visit(this.action + '&' + $(this).serialize());
......
......@@ -76,7 +76,7 @@ module Gitlab
# Enable the asset pipeline
config.assets.enabled = true
config.assets.paths << Gemojione.index.images_path
config.assets.paths << Gemojione.images_path
config.assets.precompile << "*.png"
config.assets.precompile << "print.css"
config.assets.precompile << "notify.css"
......
# CSP headers have to have single quotes, so failures relating to quotes
# inside Ruby string arrays are irrelevant.
# rubocop:disable Lint/PercentStringArray
require 'gitlab/current_settings'
include Gitlab::CurrentSettings
# If Sentry is enabled and the Rails app is running in production mode,
# this will construct the Report URI for Sentry.
if Rails.env.production? && current_application_settings.sentry_enabled
uri = URI.parse(current_application_settings.sentry_dsn)
CSP_REPORT_URI = "#{uri.scheme}://#{uri.host}/api#{uri.path}/csp-report/?sentry_key=#{uri.user}"
else
CSP_REPORT_URI = ''
end
# Content Security Policy Headers
# For more information on CSP see:
# - https://gitlab.com/gitlab-org/gitlab-ce/issues/18231
# - https://developer.mozilla.org/en-US/docs/Web/Security/CSP/CSP_policy_directives
SecureHeaders::Configuration.default do |config|
# Mark all cookies as "Secure", "HttpOnly", and "SameSite=Strict".
config.cookies = {
secure: true,
httponly: true,
samesite: {
strict: true
}
}
config.x_content_type_options = "nosniff"
config.x_xss_protection = "1; mode=block"
config.x_download_options = "noopen"
config.x_permitted_cross_domain_policies = "none"
config.referrer_policy = "origin-when-cross-origin"
config.csp = {
# "Meta" values.
report_only: true,
preserve_schemes: true,
# "Directive" values.
# Default source allows nothing, more permissive values are set per-policy.
default_src: %w('none'),
# (Deprecated) Don't allow iframes.
frame_src: %w('none'),
# Only allow XMLHTTPRequests from the GitLab instance itself.
connect_src: %w('self'),
# Only load local fonts.
font_src: %w('self'),
# Load local images, any external image available over HTTPS.
img_src: %w(* 'self' data:),
# Audio and video can't be played on GitLab currently, so it's disabled.
media_src: %w('none'),
# Don't allow <object>, <embed>, or <applet> elements.
object_src: %w('none'),
# Allow local scripts and inline scripts.
script_src: %w('unsafe-inline' 'unsafe-eval' 'self'),
# Allow local stylesheets and inline styles.
style_src: %w('unsafe-inline' 'self'),
# The URIs that a user agent may use as the document base URL.
base_uri: %w('self'),
# Only allow local iframes and service workers
child_src: %w('self'),
# Only submit form information to the GitLab instance.
form_action: %w('self'),
# Disallow any parents from embedding a page in an iframe.
frame_ancestors: %w('none'),
# Don't allow any plugins (Flash, Shockwave, etc.)
plugin_types: %w(),
# Blocks all mixed (HTTP) content.
block_all_mixed_content: true,
# Upgrades insecure requests to HTTPS when possible.
upgrade_insecure_requests: true
}
# Reports are sent to Sentry if it's enabled.
if current_application_settings.sentry_enabled
config.csp[:report_uri] = %W(#{CSP_REPORT_URI})
end
# Allow Bootstrap Linter in development mode.
if Rails.env.development?
config.csp[:script_src] << "maxcdn.bootstrapcdn.com"
end
# reCAPTCHA
if current_application_settings.recaptcha_enabled
config.csp[:script_src] << "https://www.google.com/recaptcha/"
config.csp[:script_src] << "https://www.gstatic.com/recaptcha/"
config.csp[:frame_src] << "https://www.google.com/recaptcha/"
config.x_frame_options = "SAMEORIGIN"
end
# Gravatar
if current_application_settings.gravatar_enabled?
config.csp[:img_src] << "www.gravatar.com"
config.csp[:img_src] << "secure.gravatar.com"
config.csp[:img_src] << Gitlab.config.gravatar.host
end
# Piwik
if Gitlab.config.extra.has_key?('piwik_url') && Gitlab.config.extra.has_key?('piwik_site_id')
config.csp[:script_src] << Gitlab.config.extra.piwik_url
config.csp[:img_src] << Gitlab.config.extra.piwik_url
end
# Google Analytics
if Gitlab.config.extra.has_key?('google_analytics_id')
config.csp[:script_src] << "https://www.google-analytics.com"
end
end
......@@ -13,7 +13,14 @@ Sidekiq.configure_server do |config|
# UGLY Hack to get nested hash from settingslogic
cron_jobs = JSON.parse(Gitlab.config.cron_jobs.to_json)
# UGLY hack: Settingslogic doesn't allow 'class' key
cron_jobs.each { |k, v| cron_jobs[k]['class'] = cron_jobs[k].delete('job_class') }
cron_jobs_required_keys = %w(job_class cron)
cron_jobs.each do |k, v|
if cron_jobs[k] && cron_jobs_required_keys.all? { |s| cron_jobs[k].key?(s) }
cron_jobs[k]['class'] = cron_jobs[k].delete('job_class')
else
raise("Invalid cron_jobs config key: '#{k}'. Check your gitlab config file.")
end
end
Sidekiq::Cron::Job.load_from_hash! cron_jobs
# Database pool should be at least `sidekiq_concurrency` + 2
......
class AddDevelopersCanMergeToProtectedBranches < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
def change
add_column_with_default :protected_branches, :developers_can_merge, :boolean, default: false, allow_null: false
end
end
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddColumnInProgressMergeCommitShaToMergeRequests < ActiveRecord::Migration
def change
add_column :merge_requests, :in_progress_merge_commit_sha, :string
end
end
......@@ -628,8 +628,8 @@ ActiveRecord::Schema.define(version: 20160716115710) do
t.integer "merge_user_id"
t.string "merge_commit_sha"
t.datetime "deleted_at"
t.string "in_progress_merge_commit_sha"
end
add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree
add_index "merge_requests", ["author_id"], name: "index_merge_requests_on_author_id", using: :btree
add_index "merge_requests", ["created_at", "id"], name: "index_merge_requests_on_created_at_and_id", using: :btree
......@@ -862,11 +862,12 @@ ActiveRecord::Schema.define(version: 20160716115710) do
add_index "projects", ["visibility_level"], name: "index_projects_on_visibility_level", using: :btree
create_table "protected_branches", force: :cascade do |t|
t.integer "project_id", null: false
t.string "name", null: false
t.integer "project_id", null: false
t.string "name", null: false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "developers_can_push", default: false, null: false
t.boolean "developers_can_push", default: false, null: false
t.boolean "developers_can_merge", default: false, null: false
end
add_index "protected_branches", ["project_id"], name: "index_protected_branches_on_project_id", using: :btree
......
......@@ -757,12 +757,13 @@ Introduced in GitLab 8.6 and GitLab Runner v1.1.1.
This feature should be used in conjunction with [`artifacts`](#artifacts) and
allows you to define the artifacts to pass between different builds.
Note that `artifacts` from previous [stages](#stages) are passed by default.
Note that `artifacts` from all previous [stages](#stages) are passed by default.
To use this feature, define `dependencies` in context of the job and pass
a list of all previous builds from which the artifacts should be downloaded.
You can only define builds from stages that are executed before the current one.
An error will be shown if you define builds from the current stage or next ones.
Defining an empty array will skip downloading any artifacts for that job.
---
......
......@@ -53,3 +53,8 @@ Generating a sprite file containing all the Emoji can be done by running:
```
bundle exec rake gemojione:sprite
```
If new emoji are added, the spritesheet may change size. To compensate for
such changes, first generate the `emoji.png` spritesheet with the above Rake
task, then check the dimensions of the new spritesheet and update the
`SPRITESHEET_WIDTH` and `SPRITESHEET_HEIGHT` constants accordingly.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -17,7 +17,7 @@ module API
def current_user
@current_user ||= (find_user_by_private_token || doorkeeper_guard)
unless @current_user && Gitlab::UserAccess.allowed?(@current_user)
unless @current_user && Gitlab::UserAccess.new(@current_user).allowed?
return nil
end
......
......@@ -14,9 +14,10 @@ module Gitlab
OWNER = 50
# Branch protection settings
PROTECTION_NONE = 0
PROTECTION_DEV_CAN_PUSH = 1
PROTECTION_FULL = 2
PROTECTION_NONE = 0
PROTECTION_DEV_CAN_PUSH = 1
PROTECTION_FULL = 2
PROTECTION_DEV_CAN_MERGE = 3
class << self
def values
......@@ -54,6 +55,7 @@ module Gitlab
def protection_options
{
"Not protected: Both developers and masters can push new commits, force push, or delete the branch." => PROTECTION_NONE,
"Protected against pushes: Developers cannot push new commits, but are allowed to accept merge requests to the branch." => PROTECTION_DEV_CAN_MERGE,
"Partially protected: Developers can push new commits, but cannot force push or delete the branch. Masters can do all of those." => PROTECTION_DEV_CAN_PUSH,
"Fully protected: Developers cannot push new commits, force push, or delete the branch. Only masters can do any of those." => PROTECTION_FULL,
}
......
module Gitlab
class AwardEmoji
CATEGORIES = {
other: "Other",
objects: "Objects",
places: "Places",
travel_places: "Travel",
emoticons: "Emoticons",
objects_symbols: "Symbols",
travel: "Travel",
symbols: "Symbols",
nature: "Nature",
celebration: "Celebration",
people: "People",
activity: "Activity",
flags: "Flags",
food_drink: "Food"
}.with_indifferent_access
CATEGORY_ALIASES = {
symbols: "objects_symbols",
foods: "food_drink",
travel: "travel_places"
food: "Food"
}.with_indifferent_access
def self.normalize_emoji_name(name)
......@@ -35,7 +25,7 @@ module Gitlab
# Skip Fitzpatrick(tone) modifiers
next if data["category"] == "modifier"
category = CATEGORY_ALIASES[data["category"]] || data["category"]
category = data["category"]
@emoji_by_category[category] << data
end
......@@ -57,9 +47,9 @@ module Gitlab
def self.aliases
@aliases ||=
begin
json_path = File.join(Rails.root, 'fixtures', 'emojis', 'aliases.json' )
JSON.parse(File.read(json_path))
end
json_path = File.join(Rails.root, 'fixtures', 'emojis', 'aliases.json')
JSON.parse(File.read(json_path))
end
end
# Returns an Array of Emoji names and their asset URLs.
......
module Gitlab
module Checks
class ChangeAccess
attr_reader :user_access, :project
def initialize(change, user_access:, project:)
@oldrev, @newrev, @ref = change.split(' ')
@branch_name = branch_name(@ref)
@user_access = user_access
@project = project
end
def exec
error = protected_branch_checks || tag_checks || push_checks
if error
GitAccessStatus.new(false, error)
else
GitAccessStatus.new(true)
end
end
protected
def protected_branch_checks
return unless project.protected_branch?(@branch_name)
if forced_push? && user_access.cannot_do_action?(:force_push_code_to_protected_branches)
return "You are not allowed to force push code to a protected branch on this project."
elsif Gitlab::Git.blank_ref?(@newrev) && user_access.cannot_do_action?(:remove_protected_branches)
return "You are not allowed to delete protected branches from this project."
end
if matching_merge_request?
if user_access.can_merge_to_branch?(@branch_name) || user_access.can_push_to_branch?(@branch_name)
return
else
"You are not allowed to merge code into protected branches on this project."
end
else
if user_access.can_push_to_branch?(@branch_name)
return
else
"You are not allowed to push code to protected branches on this project."
end
end
end
def tag_checks
tag_ref = tag_name(@ref)
if tag_ref && protected_tag?(tag_ref) && user_access.cannot_do_action?(:admin_project)
"You are not allowed to change existing tags on this project."
end
end
def push_checks
if user_access.cannot_do_action?(:push_code)
"You are not allowed to push code to this project."
end
end
private
def protected_tag?(tag_name)
project.repository.tag_exists?(tag_name)
end
def forced_push?
Gitlab::Checks::ForcePush.force_push?(@project, @oldrev, @newrev)
end
def matching_merge_request?
Checks::MatchingMergeRequest.new(@newrev, @branch_name, @project).match?
end
def branch_name(ref)
ref = @ref.to_s
if Gitlab::Git.branch_ref?(ref)
Gitlab::Git.ref_name(ref)
else
nil
end
end
def tag_name(ref)
ref = @ref.to_s
if Gitlab::Git.tag_ref?(ref)
Gitlab::Git.ref_name(ref)
else
nil
end
end
end
end
end
module Gitlab
module Checks
class ForcePush
def self.force_push?(project, oldrev, newrev)
return false if project.empty_repo?
# Created or deleted branch
if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev)
false
else
missed_refs, _ = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev}))
missed_refs.split("\n").size > 0
end
end
end
end
end
module Gitlab
module Checks
class MatchingMergeRequest
def initialize(newrev, branch_name, project)
@newrev = newrev
@branch_name = branch_name
@project = project
end
def match?
@project.merge_requests
.with_state(:locked)
.where(in_progress_merge_commit_sha: @newrev, target_branch: @branch_name)
.exists?
end
end
end
end
......@@ -5,7 +5,7 @@ module Gitlab
delegate :new_file, :deleted_file, :renamed_file,
:old_path, :new_path, :a_mode, :b_mode,
:submodule?, :too_large?, to: :diff, prefix: false
:submodule?, :too_large?, :collapsed?, to: :diff, prefix: false
def initialize(diff, repository:, diff_refs: nil)
@diff = diff
......@@ -68,10 +68,6 @@ module Gitlab
@lines ||= Gitlab::Diff::Parser.new.parse(raw_diff.each_line).to_a
end
def collapsed_by_default?
diff.diff.bytesize > 10240 # 10 KB
end
def highlighted_diff_lines
@highlighted_diff_lines ||= Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight
end
......
module Gitlab
class ForcePushCheck
def self.force_push?(project, oldrev, newrev)
return false if project.empty_repo?
# Created or deleted branch
if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev)
false
else
missed_refs, _ = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev}))
missed_refs.split("\n").size > 0
end
end
end
end
# Check a user's access to perform a git action. All public methods in this
# class return an instance of `GitlabAccessStatus`
module Gitlab
class GitAccess
DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }
PUSH_COMMANDS = %w{ git-receive-pack }
attr_reader :actor, :project, :protocol
attr_reader :actor, :project, :protocol, :user_access
def initialize(actor, project, protocol)
@actor = actor
@project = project
@protocol = protocol
end
def user
return @user if defined?(@user)
@user =
case actor
when User
actor
when DeployKey
nil
when Key
actor.user
end
end
def deploy_key
actor if actor.is_a?(DeployKey)
end
def can_push_to_branch?(ref)
return false unless user
if project.protected_branch?(ref) && !project.developers_can_push_to_protected_branch?(ref)
user.can?(:push_code_to_protected_branches, project)
else
user.can?(:push_code, project)
end
end
def can_read_project?
if user
user.can?(:read_project, project)
elsif deploy_key
deploy_key.projects.include?(project)
else
false
end
@user_access = UserAccess.new(user, project: project)
end
def check(cmd, changes = nil)
......@@ -56,11 +21,11 @@ module Gitlab
return build_status_object(false, "No user or key was provided.")
end
if user && !user_allowed?
if user && !user_access.allowed?
return build_status_object(false, "Your account has been blocked.")
end
unless project && can_read_project?
unless project && (user_access.can_read_project? || deploy_key_can_read_project?)
return build_status_object(false, 'The project you were looking for could not be found.')
end
......@@ -95,7 +60,7 @@ module Gitlab
end
def user_download_access_check
unless user.can?(:download_code, project)
unless user_access.can_do_action?(:download_code)
return build_status_object(false, "You are not allowed to download code from this project.")
end
......@@ -125,46 +90,8 @@ module Gitlab
build_status_object(true)
end
def can_user_do_action?(action)
@permission_cache ||= {}
@permission_cache[action] ||= user.can?(action, project)
end
def change_access_check(change)
oldrev, newrev, ref = change.split(' ')
action =
if project.protected_branch?(branch_name(ref))
protected_branch_action(oldrev, newrev, branch_name(ref))
elsif (tag_ref = tag_name(ref)) && protected_tag?(tag_ref)
# Prevent any changes to existing git tag unless user has permissions
:admin_project
else
:push_code
end
unless can_user_do_action?(action)
status =
case action
when :force_push_code_to_protected_branches
build_status_object(false, "You are not allowed to force push code to a protected branch on this project.")
when :remove_protected_branches
build_status_object(false, "You are not allowed to deleted protected branches from this project.")
when :push_code_to_protected_branches
build_status_object(false, "You are not allowed to push code to protected branches on this project.")
when :admin_project
build_status_object(false, "You are not allowed to change existing tags on this project.")
else # :push_code
build_status_object(false, "You are not allowed to push code to this project.")
end
return status
end
build_status_object(true)
end
def forced_push?(oldrev, newrev)
Gitlab::ForcePushCheck.force_push?(project, oldrev, newrev)
Checks::ChangeAccess.new(change, user_access: user_access, project: project).exec
end
def protocol_allowed?
......@@ -173,48 +100,38 @@ module Gitlab
private
def protected_branch_action(oldrev, newrev, branch_name)
# we dont allow force push to protected branch
if forced_push?(oldrev, newrev)
:force_push_code_to_protected_branches
elsif Gitlab::Git.blank_ref?(newrev)
# and we dont allow remove of protected branch
:remove_protected_branches
elsif project.developers_can_push_to_protected_branch?(branch_name)
:push_code
else
:push_code_to_protected_branches
end
def matching_merge_request?(newrev, branch_name)
Checks::MatchingMergeRequest.new(newrev, branch_name, project).match?
end
def protected_tag?(tag_name)
project.repository.tag_exists?(tag_name)
end
def user_allowed?
Gitlab::UserAccess.allowed?(user)
end
def branch_name(ref)
ref = ref.to_s
if Gitlab::Git.branch_ref?(ref)
Gitlab::Git.ref_name(ref)
else
nil
end
def deploy_key
actor if actor.is_a?(DeployKey)
end
def tag_name(ref)
ref = ref.to_s
if Gitlab::Git.tag_ref?(ref)
Gitlab::Git.ref_name(ref)
def deploy_key_can_read_project?
if deploy_key
deploy_key.projects.include?(project)
else
nil
false
end
end
protected
def user
return @user if defined?(@user)
@user =
case actor
when User
actor
when DeployKey
nil
when Key
actor.user
end
end
def build_status_object(status, message = '')
GitAccessStatus.new(status, message)
end
......
module Gitlab
class GitAccessWiki < GitAccess
def change_access_check(change)
if user.can?(:create_wiki, project)
if user_access.can_do_action?(:create_wiki)
build_status_object(true)
else
build_status_object(false, "You are not allowed to write to this project's wiki.")
......
......@@ -2,7 +2,7 @@ module Gitlab
module ImportExport
extend self
VERSION = '0.1.1'
VERSION = '0.1.2'
FILENAME_LIMIT = 50
def export_path(relative_path:)
......
......@@ -53,7 +53,11 @@ included_attributes:
excluded_attributes:
snippets:
- :expired_at
merge_request_diff:
- :st_diffs
methods:
statuses:
- :type
\ No newline at end of file
- :type
merge_request_diff:
- :utf8_st_diffs
\ No newline at end of file
......@@ -33,6 +33,7 @@ module Gitlab
update_project_references
reset_ci_tokens if @relation_name == 'Ci::Trigger'
@relation_hash['data'].deep_symbolize_keys! if @relation_name == :events && @relation_hash['data']
set_st_diffs if @relation_name == :merge_request_diff
generate_imported_object
end
......@@ -129,6 +130,10 @@ module Gitlab
def parsed_relation_hash
@relation_hash.reject { |k, _v| !relation_class.attribute_method?(k) }
end
def set_st_diffs
@relation_hash['st_diffs'] = @relation_hash.delete('utf8_st_diffs')
end
end
end
end
module Gitlab
module UserAccess
def self.allowed?(user)
return false if user.blocked?
class UserAccess
attr_reader :user, :project
def initialize(user, project: nil)
@user = user
@project = project
end
def can_do_action?(action)
@permission_cache ||= {}
@permission_cache[action] ||= user.can?(action, project)
end
def cannot_do_action?(action)
!can_do_action?(action)
end
def allowed?
return false if user.blank? || user.blocked?
if user.requires_ldap_check? && user.try_obtain_ldap_lease
return false unless Gitlab::LDAP::Access.allowed?(user)
......@@ -9,5 +25,31 @@ module Gitlab
true
end
def can_push_to_branch?(ref)
return false unless user
if project.protected_branch?(ref) && !project.developers_can_push_to_protected_branch?(ref)
user.can?(:push_code_to_protected_branches, project)
else
user.can?(:push_code, project)
end
end
def can_merge_to_branch?(ref)
return false unless user
if project.protected_branch?(ref) && !project.developers_can_merge_to_protected_branch?(ref)
user.can?(:push_code_to_protected_branches, project)
else
user.can?(:push_code, project)
end
end
def can_read_project?
return false unless user
user.can?(:read_project, project)
end
end
end
......@@ -4,7 +4,7 @@ namespace :gemojione do
require 'digest/sha2'
require 'json'
dir = Gemojione.index.images_path
dir = Gemojione.images_path
digests = []
aliases = Hash.new { |hash, key| hash[key] = [] }
aliases_path = File.join(Rails.root, 'fixtures', 'emojis', 'aliases.json')
......@@ -50,9 +50,14 @@ namespace :gemojione do
SIZE = 20
RETINA = SIZE * 2
# Update these values to the width and height of the spritesheet when
# new emoji are added.
SPRITESHEET_WIDTH = 860
SPRITESHEET_HEIGHT = 840
Dir.mktmpdir do |tmpdir|
# Copy the Gemojione assets to the temporary folder for resizing
FileUtils.cp_r(Gemojione.index.images_path, tmpdir)
FileUtils.cp_r(Gemojione.images_path, tmpdir)
Dir.chdir(tmpdir) do
Dir["**/*.png"].each do |png|
......@@ -64,7 +69,7 @@ namespace :gemojione do
# Combine the resized assets into a packed sprite and re-generate the SCSS
SpriteFactory.cssurl = "image-url('$IMAGE')"
SpriteFactory.run!(File.join(tmpdir, 'images'), {
SpriteFactory.run!(File.join(tmpdir, 'png'), {
output_style: style_path,
output_image: "app/assets/images/emoji.png",
selector: '.emoji-',
......@@ -97,7 +102,7 @@ namespace :gemojione do
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx) {
background-image: image-url('emoji@2x.png');
background-size: 840px 820px;
background-size: #{SPRITESHEET_WIDTH}px #{SPRITESHEET_HEIGHT}px;
}
}
CSS
......@@ -107,7 +112,7 @@ namespace :gemojione do
# Now do it again but for Retina
Dir.mktmpdir do |tmpdir|
# Copy the Gemojione assets to the temporary folder for resizing
FileUtils.cp_r(Gemojione.index.images_path, tmpdir)
FileUtils.cp_r(Gemojione.images_path, tmpdir)
Dir.chdir(tmpdir) do
Dir["**/*.png"].each do |png|
......@@ -116,7 +121,7 @@ namespace :gemojione do
end
# Combine the resized assets into a packed sprite and re-generate the SCSS
SpriteFactory.run!(File.join(tmpdir, 'images'), {
SpriteFactory.run!(File.join(tmpdir), {
output_image: "app/assets/images/emoji@2x.png",
style: false,
nocomments: true,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment