Commit 1af8b1e4 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq into ce-to-ee

Conflicts:
	app/views/help/index.html.haml
	lib/gitlab/git_access.rb
	public/500.html
	public/502.html
parents 21b10d61 be969bb4
Please view this file on the master branch, on stable branches it's out of date.
v 7.11.0 (unreleased)
- Fix broken view when viewing history of a file that includes a path that used to be another file (Stan Hu)
- Don't show duplicate deploy keys
- Fix commit time being displayed in the wrong timezone in some cases (Hannes Rosenögger)
- Make the first branch pushed to an empty repository the default HEAD (Stan Hu)
......@@ -42,6 +43,9 @@ v 7.11.0 (unreleased)
- Task lists are now usable in comments, and will show up in Markdown previews.
- Fix bug where avatar filenames were not actually deleted from the database during removal (Stan Hu)
- Fix bug where Slack service channel was not saved in admin template settings. (Stan Hu)
- Protect OmniAuth request phase against CSRF.
-
-
- Move snippets UI to fluid layout
- Improve UI for sidebar. Increase separation between navigation and content
- Improve new project command options (Ben Bodenmiller)
......@@ -56,6 +60,12 @@ v 7.11.0 (unreleased)
- Add "Create Merge Request" buttons to commits and branches pages and push event.
- Show user roles by comments.
- Fix automatic blocking of auto-created users from Active Directory.
- Call merge request web hook for each new commits (Arthur Gautier)
- Use SIGKILL by default in Sidekiq::MemoryKiller
- Fix mentioning of private groups.
- Add style for <kbd> element in markdown
- Spin spinner icon next to "Checking for CI status..." on MR page.
- Fix reference links in dashboard activity and ATOM feeds.
v 7.10.2
- Fix CI links on MR page
......
......@@ -23,7 +23,7 @@ gem "pg", group: :postgres
# Auth
gem "devise", '3.2.4'
gem "devise-async", '0.9.0'
gem 'omniauth', "~> 1.1.3"
gem 'omniauth', "~> 1.2.2"
gem 'omniauth-google-oauth2'
gem 'omniauth-twitter'
gem 'omniauth-github'
......@@ -44,7 +44,7 @@ gem "browser"
# Extracting information from a git repository
# Provide access to Gitlab::Git library
gem "gitlab_git", '~> 7.1.11'
gem "gitlab_git", '~> 7.1.12'
# Ruby/Rack Git Smart-HTTP Server Handler
gem 'gitlab-grack', '~> 2.0.2', require: 'grack'
......
......@@ -226,7 +226,7 @@ GEM
mime-types (~> 1.19)
gitlab_emoji (0.1.0)
gemojione (~> 2.0)
gitlab_git (7.1.11)
gitlab_git (7.1.12)
activesupport (~> 4.0)
charlock_holmes (~> 0.6)
gitlab-linguist (~> 3.0)
......@@ -363,9 +363,9 @@ GEM
rack (~> 1.2)
octokit (3.7.0)
sawyer (~> 0.6.0, >= 0.5.3)
omniauth (1.1.4)
hashie (>= 1.2, < 3)
rack
omniauth (1.2.2)
hashie (>= 1.2, < 4)
rack (~> 1.0)
omniauth-bitbucket (0.0.2)
multi_json (~> 1.7)
omniauth (~> 1.1)
......@@ -725,7 +725,7 @@ DEPENDENCIES
gitlab-license (~> 0.0.2)
gitlab-linguist (~> 3.0.1)
gitlab_emoji (~> 0.1)
gitlab_git (~> 7.1.11)
gitlab_git (~> 7.1.12)
gitlab_meta (= 7.0)
gitlab_omniauth-ldap (= 1.2.1)
gollum-lib (~> 4.0.2)
......@@ -754,7 +754,7 @@ DEPENDENCIES
newrelic_rpm
nprogress-rails
octokit (= 3.7.0)
omniauth (~> 1.1.3)
omniauth (~> 1.2.2)
omniauth-bitbucket
omniauth-github
omniauth-gitlab
......
......@@ -73,6 +73,22 @@
padding: 0;
}
kbd {
display: inline-block;
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #555;
vertical-align: middle;
background-color: #FCFCFC;
border-width: 1px;
border-style: solid;
border-color: #CCC #CCC #BBB;
border-image: none;
border-radius: 3px;
box-shadow: 0px -1px 0px #BBB inset;
}
h1 {
margin-top: 45px;
font-size: 2.5em;
......
......@@ -33,7 +33,16 @@ ul.notes {
&:before {
content: "\00b7";
}
font-size: 13px;
a {
@extend .cgray;
&:hover {
text-decoration: underline;
}
}
}
.author {
color: #333;
......@@ -47,7 +56,7 @@ ul.notes {
.note-role {
float: right;
margin-top: 2px;
margin-top: 1px;
border: 1px solid #bbb;
background-color: transparent;
color: #999;
......@@ -142,31 +151,23 @@ ul.notes {
.discussion,
.note {
&.note:hover {
.note-actions { display: block; }
.note-actions + .note-role { display: none; }
}
.discussion-header:hover {
.discussion-actions { display: block; }
}
.discussion-actions,
.note-actions {
display: none;
float: right;
i.fa {
font-size: 16px;
line-height: 16px;
vertical-align: middle;
}
margin-left: 10px;
a {
margin-left: 5px;
@extend .cgray;
color: #999;
i.fa {
font-size: 16px;
line-height: 16px;
}
&:hover {
@extend .cgray;
&.danger { @extend .cred; }
}
}
......
......@@ -218,6 +218,10 @@ ul.nav.nav-projects-tabs {
color: #555;
}
.actions {
margin-top: 10px;
}
.nav-pills a {
padding: 10px;
}
......
......@@ -43,6 +43,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:default_project_visibility,
:default_snippet_visibility,
:restricted_signup_domains_raw,
:version_check_enabled,
restricted_visibility_levels: [],
)
end
......
......@@ -73,8 +73,15 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
redirect_to omniauth_error_path(oauth['provider'], error: error_message) and return
end
end
rescue Gitlab::OAuth::ForbiddenAction => e
flash[:notice] = e.message
rescue Gitlab::OAuth::SignupDisabledError => e
message = "Signing in using your #{oauth['provider']} account without a pre-existing GitLab account is not allowed."
if current_application_settings.signup_enabled?
message << " Create a GitLab account first, and then connect it to your #{oauth['provider']} account."
end
flash[:notice] = message
redirect_to new_user_session_path
end
......
class SessionsController < Devise::SessionsController
prepend_before_action :authenticate_with_two_factor, only: [:create]
include AuthenticatesWithTwoFactor
# This action comes from DeviseController, but because we call `sign_in`
# manually inside `authenticate_with_two_factor`, not skipping this action
# would cause a "You are already signed in." error message to be shown upon
# successful login.
skip_before_action :require_no_authentication, only: [:create]
prepend_before_action :authenticate_with_two_factor, only: [:create]
def new
redirect_path =
......@@ -74,9 +70,7 @@ class SessionsController < Devise::SessionsController
end
else
if user && user.valid_password?(user_params[:password])
# Save the user's ID to session so we can ask for a one-time password
session[:otp_user_id] = user.id
render :two_factor and return
prompt_for_two_factor(user)
end
end
end
......
......@@ -330,12 +330,20 @@ module ApplicationHelper
count =
if project.nil?
""
nil
elsif current_controller?(:issues)
" (#{project.issues.send(entity).count})"
project.issues.send(entity).count
elsif current_controller?(:merge_requests)
" (#{project.merge_requests.send(entity).count})"
project.merge_requests.send(entity).count
end
"#{entity_title}#{count}"
html = content_tag :span, entity_title
if count.present?
html += " "
html += content_tag :span, number_with_delimiter(count), class: 'badge'
end
html.html_safe
end
end
......@@ -168,8 +168,8 @@ module EventsHelper
end
end
def event_note(text)
text = first_line_in_markdown(text, 150)
def event_note(text, options = {})
text = first_line_in_markdown(text, 150, options)
sanitize(text, tags: %w(a img b pre code p span))
end
......@@ -189,7 +189,7 @@ module EventsHelper
xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}"
xml.link href: event_link
xml.title truncate(event_title, length: 80)
xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%S%Z")
xml.media :thumbnail, width: "40", height: "40", url: avatar_icon(event.author_email)
xml.author do |author|
xml.name event.author_name
......
......@@ -19,7 +19,7 @@ module GitlabMarkdownHelper
escape_once(body)
end
gfm_body = gfm(escaped_body, @project, html_options)
gfm_body = gfm(escaped_body, {}, html_options)
gfm_body.gsub!(%r{<a.*?>.*?</a>}m) do |match|
"</a>#{match}#{link_to("", url, html_options)[0..-5]}" # "</a>".length +1
......@@ -32,11 +32,13 @@ module GitlabMarkdownHelper
unless @markdown && options == @options
@options = options
# see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch
rend = Redcarpet::Render::GitlabHTML.new(self, user_color_scheme_class, {
options.merge!(
# Handled further down the line by Gitlab::Markdown::SanitizationFilter
escape_html: false
}.merge(options))
)
# see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch
rend = Redcarpet::Render::GitlabHTML.new(self, user_color_scheme_class, options)
# see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
@markdown = Redcarpet::Markdown.new(rend,
......@@ -58,8 +60,8 @@ module GitlabMarkdownHelper
# as Markdown. HTML tags in the parsed output are not counted toward the
# +max_chars+ limit. If the length limit falls within a tag's contents, then
# the tag contents are truncated without removing the closing tag.
def first_line_in_markdown(text, max_chars = nil)
md = markdown(text).strip
def first_line_in_markdown(text, max_chars = nil, options = {})
md = markdown(text, options).strip
truncate_visible(md, max_chars || md.length) if md.present?
end
......@@ -72,146 +74,6 @@ module GitlabMarkdownHelper
end
end
# TODO (rspeicher): This should be its own filter
def create_relative_links(text)
paths = extract_paths(text)
paths.uniq.each do |file_path|
# If project does not have repository
# its nothing to rebuild
#
# TODO: pass project variable to markdown helper instead of using
# instance variable. Right now it generates invalid path for pages out
# of project scope. Example: search results where can be rendered markdown
# from different projects
if @repository && @repository.exists? && !@repository.empty?
new_path = rebuild_path(file_path)
# Finds quoted path so we don't replace other mentions of the string
# eg. "doc/api" will be replaced and "/home/doc/api/text" won't
text.gsub!("\"#{file_path}\"", "\"/#{new_path}\"")
end
end
text
end
def extract_paths(text)
links = substitute_links(text)
image_links = substitute_image_links(text)
links + image_links
end
def substitute_links(text)
links = text.scan(/<a href=\"([^"]*)\">/)
relative_links = links.flatten.reject{ |link| link_to_ignore? link }
relative_links
end
def substitute_image_links(text)
links = text.scan(/<img src=\"([^"]*)\"/)
relative_links = links.flatten.reject{ |link| link_to_ignore? link }
relative_links
end
def link_to_ignore?(link)
if link =~ /\A\#\w+/
# ignore anchors like <a href="#my-header">
true
else
ignored_protocols.map{ |protocol| link.include?(protocol) }.any?
end
end
def ignored_protocols
["http://","https://", "ftp://", "mailto:", "smb://"]
end
def rebuild_path(file_path)
file_path = file_path.dup
file_path.gsub!(/(#.*)/, "")
id = $1 || ""
file_path = relative_file_path(file_path)
file_path = sanitize_slashes(file_path)
[
Gitlab.config.gitlab.relative_url_root,
@project.path_with_namespace,
path_with_ref(file_path),
file_path
].compact.join("/").gsub(/\A\/*|\/*\z/, '') + id
end
def sanitize_slashes(path)
path[0] = "" if path.start_with?("/")
path.chop if path.end_with?("/")
path
end
def relative_file_path(path)
requested_path = @path
nested_path = build_nested_path(path, requested_path)
return nested_path if file_exists?(nested_path)
path
end
# Covering a special case, when the link is referencing file in the same directory eg:
# If we are at doc/api/README.md and the README.md contains relative links like [Users](users.md)
# this takes the request path(doc/api/README.md), and replaces the README.md with users.md so the path looks like doc/api/users.md
# If we are at doc/api and the README.md shown in below the tree view
# this takes the request path(doc/api) and adds users.md so the path looks like doc/api/users.md
def build_nested_path(path, request_path)
return request_path if path == ""
return path unless request_path
if local_path(request_path) == "tree"
base = request_path.split("/").push(path)
base.join("/")
else
base = request_path.split("/")
base.pop
base.push(path).join("/")
end
end
# Checks if the path exists in the repo
# eg. checks if doc/README.md exists, if not then link to blob
def path_with_ref(path)
if file_exists?(path)
"#{local_path(path)}/#{correct_ref}"
else
"blob/#{correct_ref}"
end
end
def file_exists?(path)
return false if path.nil?
@repository.blob_at(current_sha, path).present? || @repository.tree(current_sha, path).entries.any?
end
# Check if the path is pointing to a directory(tree) or a file(blob)
# eg. doc/api is directory and doc/README.md is file
def local_path(path)
return "tree" if @repository.tree(current_sha, path).entries.any?
return "raw" if @repository.blob_at(current_sha, path).image?
"blob"
end
def current_sha
if @commit
@commit.id
elsif @repository && !@repository.empty?
if @ref
@repository.commit(@ref).try(:sha)
else
@repository.head_commit.sha
end
end
end
# We will assume that if no ref exists we can point to master
def correct_ref
@ref ? @ref : "master"
end
private
# Return +text+, truncated to +max_chars+ characters, excluding any HTML
......
module VersionCheckHelper
def version_status_badge
if Rails.env.production?
image_tag VersionCheck.new.url
end
end
end
......@@ -42,10 +42,10 @@ module Mentionable
SystemNoteService.cross_reference_exists?(target, local_reference)
end
def mentioned_users(current_user = nil, p = project)
def mentioned_users(current_user = nil)
return [] if mentionable_text.blank?
ext = Gitlab::ReferenceExtractor.new(p, current_user)
ext = Gitlab::ReferenceExtractor.new(self.project, current_user)
ext.analyze(mentionable_text)
ext.users.uniq
end
......
......@@ -40,7 +40,7 @@ module Participable
meth = method(attr)
value =
if meth.arity == 1
if meth.arity == 1 || meth.arity == -1
meth.call(current_user)
else
meth.call
......
......@@ -10,6 +10,7 @@ module MergeRequests
close_merge_requests
reload_merge_requests
execute_mr_web_hooks
comment_mr_with_commits
true
......@@ -88,6 +89,20 @@ module MergeRequests
end
end
# Call merge request webhook with update branches
def execute_mr_web_hooks
merge_requests = @project.origin_merge_requests.opened
.where(source_branch: @branch_name)
.to_a
merge_requests += @fork_merge_requests.where(source_branch: @branch_name)
.to_a
merge_requests = filter_merge_requests(merge_requests)
merge_requests.each do |merge_request|
execute_hooks(merge_request, 'update')
end
end
def filter_merge_requests(merge_requests)
merge_requests.uniq.select(&:source_project)
end
......
......@@ -32,6 +32,12 @@
= f.check_box :twitter_sharing_enabled, :'aria-describedby' => 'twitter_help_block'
%strong Twitter enabled
%span.help-block#twitter_help_block Show users a button to share their newly created public or internal projects on twitter
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
= f.label :version_check_enabled do
= f.check_box :version_check_enabled
Version check enabled
%fieldset
%legend Misc
.form-group
......
......@@ -56,7 +56,12 @@
%span.light.pull-right
= boolean_to_icon Gitlab.config.omniauth.enabled
.col-md-4
%h4 Components
%h4
Components
- if current_application_settings.version_check_enabled
.pull-right
= version_status_badge
%hr
%p
GitLab
......
......@@ -5,6 +5,6 @@
- providers.each do |provider|
%span.light
- if default_providers.include?(provider)
= link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), class: 'oauth-image-link'
= link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), method: :post, class: 'oauth-image-link'
- else
= link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn", "data-no-turbolink" => "true"
= link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), method: :post, class: "btn", "data-no-turbolink" => "true"
......@@ -2,4 +2,4 @@
.commit-row-title
= link_to truncate_sha(commit[:id]), namespace_project_commit_path(project.namespace, project, commit[:id]), class: "commit_short_id", alt: ''
&nbsp;
= gfm event_commit_title(commit[:message]), project
= gfm event_commit_title(commit[:message]), project: project
%div{xmlns: "http://www.w3.org/1999/xhtml"}
- if issue.description.present?
= markdown(issue.description, xhtml: true)
= markdown(issue.description, xhtml: true, reference_only_path: false, project: issue.project)
%div{xmlns: "http://www.w3.org/1999/xhtml"}
- if merge_request.description.present?
= markdown(merge_request.description, xhtml: true)
= markdown(merge_request.description, xhtml: true, reference_only_path: false, project: merge_request.project)
%div{xmlns: "http://www.w3.org/1999/xhtml"}
= markdown(note.note, xhtml: true)
= markdown(note.note, xhtml: true, reference_only_path: false, project: note.project)
......@@ -6,7 +6,7 @@
%i
at
= commit[:timestamp].to_time.to_s(:short)
%blockquote= markdown(escape_once(commit[:message]), xhtml: true)
%blockquote= markdown(escape_once(commit[:message]), xhtml: true, reference_only_path: false, project: note.project)
- if event.commits_count > 15
%p
%i
......
......@@ -14,7 +14,7 @@
.event-note
.md
%i.fa.fa-comment-o.event-note-icon
= event_note(event.target.note)
= event_note(event.target.note, project: event.project)
- note = event.target
- if note.attachment.url
- if note.attachment.image?
......
......@@ -4,6 +4,8 @@
%span.light Enterprise Edition
%span= Gitlab::VERSION
%small= Gitlab::REVISION
- if current_application_settings.version_check_enabled
= version_status_badge
%br
Read more about GitLab at #{link_to promo_host, promo_url, target: '_blank'}.
- if help_text.present?
......
......@@ -61,7 +61,7 @@
- enabled_social_providers.each do |provider|
.btn-group
= link_to oauth_image_tag(provider), omniauth_authorize_path(User, provider),
class: "btn btn-lg #{'active' if oauth_active?(provider)}"
method: :post, class: "btn btn-lg #{'active' if oauth_active?(provider)}"
- if oauth_active?(provider)
= link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do
= icon('close')
......
......@@ -10,17 +10,14 @@
- if @repository.changelog
%li.hidden-xs
= link_to changelog_url(@project) do
= icon("list-alt fw")
Changelog
- if @repository.license
%li
= link_to license_url(@project) do
= icon("check-circle-o fw")
License
- if @repository.contribution_guide
%li
= link_to contribution_guide_url(@project) do
= icon("info-circle fw")
Contribution guide
.actions
......@@ -73,15 +70,12 @@
%ul.nav.nav-pills
%li
= link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref) do
= icon("history fw")
= pluralize(number_with_delimiter(@repository.commit_count), 'commit')
%li
= link_to namespace_project_branches_path(@project.namespace, @project) do
= icon("code-fork fw")
= pluralize(number_with_delimiter(@repository.branch_names.count), 'branch')
%li
= link_to namespace_project_tags_path(@project.namespace, @project) do
= icon("tags fw")
= pluralize(number_with_delimiter(@repository.tag_names.count), 'tag')
.actions
......
......@@ -3,7 +3,7 @@
= link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref) do
= icon("history")
Commits
%span.badge= number_with_precision(@repository.commit_count, precision: 0, delimiter: ',')
%span.badge= number_with_delimiter(@repository.commit_count)
= nav_link(controller: :compare) do
= link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: @ref || @repository.root_ref) do
= icon("exchange")
......
- if @commits.any?
.ci_widget.ci-success{style: "display:none"}
%i.fa.fa-check
= icon("check")
%span CI build passed
for #{@merge_request.last_commit_short_sha}.
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget.ci-failed{style: "display:none"}
%i.fa.fa-times
= icon("times")
%span CI build failed
for #{@merge_request.last_commit_short_sha}.
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
- [:running, :pending].each do |status|
.ci_widget{class: "ci-#{status}", style: "display:none"}
%i.fa.fa-clock-o
= icon("clock-o")
%span CI build #{status}
for #{@merge_request.last_commit_short_sha}.
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget
%i.fa.fa-spinner
= icon("spinner spin")
Checking for CI status for #{@merge_request.last_commit_short_sha}
.ci_widget.ci-canceled{style: "display:none"}
%i.fa.fa-times
= icon("times")
%span CI build canceled
for #{@merge_request.last_commit_short_sha}.
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget.ci-error{style: "display:none"}
%i.fa.fa-times
= icon("times")
%span Cannot connect to the CI server. Please check your settings and try again.
......@@ -8,19 +8,13 @@
= image_tag avatar_icon(note.author_email), class: 'avatar s40', alt: ''
.timeline-content
.note-header
.note-actions
= link_to "##{dom_id(note)}", name: dom_id(note), title: "Link here" do
= icon('link fw')
Link here
- if note_editable?(note)
- if note_editable?(note)
.note-actions
= link_to '#', title: 'Edit comment', class: 'js-note-edit' do
= icon('pencil-square-o fw')
Edit
= icon('pencil-square-o')
= link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'danger js-note-delete' do
= icon('trash-o fw', class: 'cred')
Remove
= link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'js-note-delete danger' do
= icon('trash-o')
- unless note.system
- member = note.project.team.find_member(note.author.id)
......@@ -33,10 +27,13 @@
= image_tag avatar_icon(note.author_email), class: 'avatar s16', alt: ''
= link_to_member(note.project, note.author, avatar: false)
%span.author-username
= '@' + note.author.username
%span.note-last-update
= note_timestamp(note)
= link_to "##{dom_id(note)}", name: dom_id(note), title: "Link here" do
= note_timestamp(note)
- if note.superceded?(@notes)
- if note.upvote?
......
......@@ -14,7 +14,9 @@
- last_note = discussion_notes.last
last updated by
= link_to_member(@project, last_note.author, avatar: false)
%span.discussion-last-update
#{time_ago_with_tooltip(last_note.updated_at, 'bottom', 'discussion_updated_ago')}
.discussion-body.js-toggle-content
= render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note
......@@ -13,3 +13,8 @@ if Gitlab::LDAP::Config.enabled?
end
end
end
OmniAuth.config.allowed_request_methods = [:post]
OmniAuth.config.before_request_phase do |env|
OmniAuth::RequestForgeryProtection.new(env).call
end
......@@ -31,7 +31,7 @@ en:
messages:
# Common error messages
invalid_request: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
invalid_redirect_uri: 'The redirect uri included is not valid.'
invalid_redirect_uri: 'The redirect URI included is not valid.'
unauthorized_client: 'The client is not authorized to perform this request using this method.'
access_denied: 'The resource owner or authorization server denied the request.'
invalid_scope: 'The requested scope is invalid, unknown, or malformed.'
......@@ -63,11 +63,11 @@ en:
flash:
applications:
create:
notice: 'Application created.'
notice: 'The application was created successfully.'
destroy:
notice: 'Application deleted.'
notice: 'The application was deleted successfully.'
update:
notice: 'Application updated.'
notice: 'The application was updated successfully.'
authorized_applications:
destroy:
notice: 'Application revoked.'
notice: 'The application was revoked access.'
class AddVersionCheckToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :version_check_enabled, :boolean, default: true
end
end
......@@ -40,6 +40,7 @@ ActiveRecord::Schema.define(version: 20150509180749) do
t.boolean "twitter_sharing_enabled", default: true
t.text "help_text"
t.text "restricted_visibility_levels"
t.boolean "version_check_enabled", default: true
t.integer "max_attachment_size", default: 10, null: false
t.integer "default_project_visibility"
t.integer "default_snippet_visibility"
......
......@@ -32,6 +32,7 @@ Parameters:
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
- `search` (optional) - Return list of authorized projects according to a search criteria
- `ci_enabled_first` - Return projects ordered by ci_enabled flag. Projects with enabled GitLab CI go first
```json
[
......@@ -134,6 +135,7 @@ Parameters:
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
- `search` (optional) - Return list of authorized projects according to a search criteria
- `ci_enabled_first` - Return projects ordered by ci_enabled flag. Projects with enabled GitLab CI go first
### List ALL projects
......@@ -149,6 +151,7 @@ Parameters:
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
- `search` (optional) - Return list of authorized projects according to a search criteria
- `ci_enabled_first` - Return projects ordered by ci_enabled flag. Projects with enabled GitLab CI go first
### Get single project
......
# GitLab Upgrader
*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/upgrader.md) for the most up to date instructions.*
*DEPRECATED* We recommend to [switch to the Omnibus package and repository server](https://about.gitlab.com/update/) instead of using this script.
Although deprecated, if someone wants to make this script into a gem or otherwise improve it merge requests are welcome.
*Make sure you view this [upgrade guide from the 'master' branch](../../../master/doc/update/upgrader.md) for the most up to date instructions.*
GitLab Upgrader - a ruby script that allows you easily upgrade GitLab to latest minor version.
......@@ -24,13 +29,15 @@ If you have local changes to your GitLab repository the script will stash them a
## 2. Run GitLab upgrade tool
Note: GitLab 7.9 adds `nodejs` as a dependency. GitLab 7.6 adds `libkrb5-dev` as a dependency (installed by default on Ubuntu and OSX). GitLab 7.2 adds `pkg-config` and `cmake` as dependency. Please check the dependencies in the [installation guide.](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies)
Please replace X.X.X with the [latest GitLab release](https://packages.gitlab.com/gitlab/gitlab-ce).
GitLab 7.9 adds `nodejs` as a dependency. GitLab 7.6 adds `libkrb5-dev` as a dependency (installed by default on Ubuntu and OSX). GitLab 7.2 adds `pkg-config` and `cmake` as dependency. Please check the dependencies in the [installation guide.](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies)
cd /home/git/gitlab
sudo -u git -H ruby -Ilib -e 'require "gitlab/upgrader"' -e 'class Gitlab::Upgrader' -e 'def latest_version_raw' -e '"v7.10.1"' -e 'end' -e 'end' -e 'Gitlab::Upgrader.new.execute'
sudo -u git -H ruby -Ilib -e 'require "gitlab/upgrader"' -e 'class Gitlab::Upgrader' -e 'def latest_version_raw' -e '"vX.X.X"' -e 'end' -e 'end' -e 'Gitlab::Upgrader.new.execute'
# to perform a non-interactive install (no user input required) you can add -y
# sudo -u git -H ruby -Ilib -e 'require "gitlab/upgrader"' -e 'class Gitlab::Upgrader' -e 'def latest_version_raw' -e '"v7.10.1"' -e 'end' -e 'end' -e 'Gitlab::Upgrader.new.execute' -- -y
# sudo -u git -H ruby -Ilib -e 'require "gitlab/upgrader"' -e 'class Gitlab::Upgrader' -e 'def latest_version_raw' -e '"vX.X.X"' -e 'end' -e 'end' -e 'Gitlab::Upgrader.new.execute' -- -y
## 3. Start application
......@@ -59,13 +66,15 @@ sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION`
You've read through the entire guide and probably already did all the steps one by one.
Here is a one line command with step 1 to 5 for the next time you upgrade:
Below is a one line command with step 1 to 5 for the next time you upgrade.
Please replace X.X.X with the [latest GitLab release](https://packages.gitlab.com/gitlab/gitlab-ce).
```bash
cd /home/git/gitlab; \
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production; \
sudo service gitlab stop; \
sudo -u git -H ruby -Ilib -e 'require "gitlab/upgrader"' -e 'class Gitlab::Upgrader' -e 'def latest_version_raw' -e '"v7.10.1"' -e 'end' -e 'end' -e 'Gitlab::Upgrader.new.execute' -- -y; \
sudo -u git -H ruby -Ilib -e 'require "gitlab/upgrader"' -e 'class Gitlab::Upgrader' -e 'def latest_version_raw' -e '"vX.X.X"' -e 'end' -e 'end' -e 'Gitlab::Upgrader.new.execute' -- -y; \
cd /home/git/gitlab-shell; \
sudo -u git -H git fetch; \
sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION`; \
......
......@@ -145,7 +145,7 @@ X-Gitlab-Event: Issue Hook
## Merge request events
Triggered when a new merge request is created or an existing merge request was updated/merged/closed.
Triggered when a new merge request is created, an existing merge request was updated/merged/closed or a commit is added in the source branch.
**Request header**:
......
......@@ -5,15 +5,14 @@ RUN apt-get update -q \
&& DEBIAN_FRONTEND=noninteractive apt-get install -qy --no-install-recommends \
ca-certificates \
openssh-server \
wget
wget \
apt-transport-https
# Download & Install GitLab
# If the Omnibus package version below is outdated please contribute a merge request to update it.
# If you run GitLab Enterprise Edition point it to a location where you have downloaded it.
RUN TMP_FILE=$(mktemp); \
wget -q -O $TMP_FILE https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab-ce_7.10.1~omnibus.2-1_amd64.deb \
&& dpkg -i $TMP_FILE \
&& rm -f $TMP_FILE
RUN echo "deb https://packages.gitlab.com/gitlab/gitlab-ce/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/gitlab_gitlab-ce.list
RUN wget -q -O - https://packages.gitlab.com/gpg.key | apt-key add -
RUN apt-get update && apt-get install -yq --no-install-recommends gitlab-ce
# Manage SSHD through runit
RUN mkdir -p /opt/gitlab/sv/sshd/supervise \
......
......@@ -2,20 +2,18 @@ FROM ubuntu:14.04
MAINTAINER Sytse Sijbrandij
# Install required packages
RUN apt-get update
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get install -yq --no-install-recommends \
RUN apt-get update -q \
&& DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
ca-certificates \
openssh-server \
wget
wget \
apt-transport-https
# Download & Install GitLab
# If the Omnibus package version below is outdated please contribute a merge request to update it.
# If you run GitLab Enterprise Edition point it to a location where you have downloaded it.
RUN TMP_FILE=$(mktemp); \
wget -q -O $TMP_FILE https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab-ce_7.10.1~omnibus.2-1_amd64.deb \
&& dpkg -i $TMP_FILE \
&& rm -f $TMP_FILE
RUN echo "deb https://packages.gitlab.com/gitlab/gitlab-ce/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/gitlab_gitlab-ce.list
RUN wget -q -O - https://packages.gitlab.com/gpg.key | apt-key add -
RUN apt-get update && apt-get install -yq --no-install-recommends gitlab-ce
# Manage SSHD through runit
RUN mkdir -p /opt/gitlab/sv/sshd/supervise \
......
......@@ -24,10 +24,6 @@ module API
User.find_by(id: params[:user_id])
end
unless actor
return Gitlab::GitAccessStatus.new(false, 'No such user or key')
end
project_path = params[:project]
# Check for *.wiki repositories.
......@@ -39,22 +35,14 @@ module API
project = Project.find_with_namespace(project_path)
if project
access =
if wiki
Gitlab::GitAccessWiki.new(actor, project)
else
Gitlab::GitAccess.new(actor, project)
end
status = access.check(params[:action], params[:changes])
end
access =
if wiki
Gitlab::GitAccessWiki.new(actor, project)
else
Gitlab::GitAccess.new(actor, project)
end
if project && access.can_read_project?
status
else
Gitlab::GitAccessStatus.new(false, 'No such project')
end
access.check(params[:action], params[:changes])
end
#
......
......@@ -22,7 +22,12 @@ module API
projects = projects.search(params[:search])
end
projects.reorder(project_order_by => project_sort)
if params[:ci_enabled_first].present?
projects.includes(:gitlab_ci_service).
reorder("services.active DESC, projects.#{project_order_by} #{project_sort}")
else
projects.reorder(project_order_by => project_sort)
end
end
def project_order_by
......
......@@ -51,9 +51,9 @@ module Gitlab
def protection_options
{
"Not protected, developers and masters can (force) push and delete the branch" => PROTECTION_NONE,
"Partially protected, developers can also push but prevent all force pushes and deletion" => PROTECTION_DEV_CAN_PUSH,
"Fully protected, only masters can push and prevent all force pushes and deletion" => PROTECTION_FULL,
"Not protected: Both developers and masters can push new commits, force push, or delete the branch." => PROTECTION_NONE,
"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,
}
end
......
......@@ -32,8 +32,7 @@ module Gitlab
def can_push_to_branch?(ref)
return false unless user
if project.protected_branch?(ref) &&
!(project.developers_can_push_to_protected_branch?(ref) && project.team.developer?(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)
......@@ -51,6 +50,18 @@ module Gitlab
end
def check(cmd, changes = nil)
unless actor
return build_status_object(false, "No user or key was provided.")
end
if user && !user_allowed?
return build_status_object(false, "Your account has been blocked.")
end
unless project && can_read_project?
return build_status_object(false, 'The project you were looking for could not be found.')
end
case cmd
when *DOWNLOAD_COMMANDS
download_access_check
......@@ -61,7 +72,7 @@ module Gitlab
git_annex_access_check(actor.user, project, changes)
end
else
build_status_object(false, "Wrong command")
build_status_object(false, "The command you're trying to execute is not allowed.")
end
end
......@@ -69,7 +80,7 @@ module Gitlab
if user
user_download_access_check
elsif deploy_key
deploy_key_download_access_check
build_status_object(true)
else
raise 'Wrong actor'
end
......@@ -79,41 +90,29 @@ module Gitlab
if user
user_push_access_check(changes)
elsif deploy_key
build_status_object(false, "Deploy key not allowed to push")
build_status_object(false, "Deploy keys are not allowed to push code.")
else
raise 'Wrong actor'
end
end
def user_download_access_check
if user && user_allowed? && user.can?(:download_code, project)
build_status_object(true)
else
build_status_object(false, "You don't have access")
unless user.can?(:download_code, project)
return build_status_object(false, "You are not allowed to download code from this project.")
end
end
def deploy_key_download_access_check
if can_read_project?
build_status_object(true)
else
build_status_object(false, "Deploy key not allowed to access this project")
end
build_status_object(true)
end
def user_push_access_check(changes)
unless user && user_allowed?
return build_status_object(false, "You don't have access")
end
if changes.blank?
return build_status_object(true)
end
unless project.repository.exists?
return build_status_object(false, "Repository does not exist")
return build_status_object(false, "A repository for this project does not exist yet.")
end
if ::License.block_changes?
message = ::LicenseHelper.license_message(signed_in: true, is_admin: (user && user.is_admin?))
return build_status_object(false, message)
......@@ -146,11 +145,21 @@ module Gitlab
:push_code
end
# Stop execution if user has no access to this project
unless user.can?(action, project)
return build_status_object(false, "You don't have permission")
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
# Return build_status_object(true) if all git hook checks passed successfully
......
......@@ -4,7 +4,7 @@ module Gitlab
if user.can?(:write_wiki, project)
build_status_object(true)
else
build_status_object(false, "You don't have access")
build_status_object(false, "You are not allowed to write to this project's wiki.")
end
end
end
......
......@@ -15,6 +15,7 @@ module Gitlab
autoload :IssueReferenceFilter, 'gitlab/markdown/issue_reference_filter'
autoload :LabelReferenceFilter, 'gitlab/markdown/label_reference_filter'
autoload :MergeRequestReferenceFilter, 'gitlab/markdown/merge_request_reference_filter'
autoload :RelativeLinkFilter, 'gitlab/markdown/relative_link_filter'
autoload :SanitizationFilter, 'gitlab/markdown/sanitization_filter'
autoload :SnippetReferenceFilter, 'gitlab/markdown/snippet_reference_filter'
autoload :TableOfContentsFilter, 'gitlab/markdown/table_of_contents_filter'
......@@ -23,10 +24,10 @@ module Gitlab
# Public: Parse the provided text with GitLab-Flavored Markdown
#
# text - the source text
# project - the project
# options - options
# html_options - extra options for the reference links as given to link_to
def gfm(text, project = @project, html_options = {})
gfm_with_options(text, {}, project, html_options)
def gfm(text, options = {}, html_options = {})
gfm_with_options(text, options, html_options)
end
# Public: Parse the provided text with GitLab-Flavored Markdown
......@@ -37,7 +38,7 @@ module Gitlab
# :reference_only_path - Use relative path for reference links
# project - the project
# html_options - extra options for the reference links as given to link_to
def gfm_with_options(text, options = {}, project = @project, html_options = {})
def gfm_with_options(text, options = {}, html_options = {})
return text if text.nil?
# Duplicate the string so we don't alter the original, then call to_str
......@@ -47,7 +48,9 @@ module Gitlab
options.reverse_merge!(
xhtml: false,
reference_only_path: true
reference_only_path: true,
project: @project,
current_user: current_user
)
pipeline = HTML::Pipeline.new(filters)
......@@ -61,10 +64,15 @@ module Gitlab
no_header_anchors: options[:no_header_anchors],
# ReferenceFilter
current_user: current_user,
current_user: options[:current_user],
only_path: options[:reference_only_path],
project: project,
reference_class: html_options[:class]
project: options[:project],
reference_class: html_options[:class],
# RelativeLinkFilter
ref: @ref,
requested_path: @path,
project_wiki: @project_wiki
}
result = pipeline.call(text, context)
......@@ -91,6 +99,7 @@ module Gitlab
[
Gitlab::Markdown::SanitizationFilter,
Gitlab::Markdown::RelativeLinkFilter,
Gitlab::Markdown::EmojiFilter,
Gitlab::Markdown::TableOfContentsFilter,
Gitlab::Markdown::AutolinkFilter,
......
require 'html/pipeline/filter'
require 'uri'
module Gitlab
module Markdown
# HTML filter that "fixes" relative links to files in a repository.
#
# Context options:
# :commit
# :project
# :project_wiki
# :ref
# :requested_path
class RelativeLinkFilter < HTML::Pipeline::Filter
def call
return doc unless linkable_files?
doc.search('a').each do |el|
process_link_attr el.attribute('href')
end
doc.search('img').each do |el|
process_link_attr el.attribute('src')
end
doc
end
protected
def linkable_files?
context[:project_wiki].nil? && repository.try(:exists?) && !repository.empty?
end
def process_link_attr(html_attr)
return if html_attr.blank?
uri = URI(html_attr.value)
if uri.relative? && uri.path.present?
html_attr.value = rebuild_relative_uri(uri).to_s
end
rescue URI::Error
# noop
end
def rebuild_relative_uri(uri)
file_path = relative_file_path(uri.path)
uri.path = [
relative_url_root,
context[:project].path_with_namespace,
path_type(file_path),
ref || 'master', # assume that if no ref exists we can point to master
file_path
].compact.join('/').squeeze('/').chomp('/')
uri
end
def relative_file_path(path)
nested_path = build_nested_path(path, context[:requested_path])
file_exists?(nested_path) ? nested_path : path
end
# Covering a special case, when the link is referencing file in the same
# directory.
# If we are at doc/api/README.md and the README.md contains relative
# links like [Users](users.md), this takes the request
# path(doc/api/README.md) and replaces the README.md with users.md so the
# path looks like doc/api/users.md.
# If we are at doc/api and the README.md shown in below the tree view
# this takes the request path(doc/api) and adds users.md so the path
# looks like doc/api/users.md
def build_nested_path(path, request_path)
return request_path if path.empty?
return path unless request_path
parts = request_path.split('/')
parts.pop if path_type(request_path) != 'tree'
parts.push(path).join('/')
end
def file_exists?(path)
return false if path.nil?
repository.blob_at(current_sha, path).present? ||
repository.tree(current_sha, path).entries.any?
end
# Get the type of the given path
#
# path - String path to check
#
# Examples:
#
# path_type('doc/README.md') # => 'blob'
# path_type('doc/logo.png') # => 'raw'
# path_type('doc/api') # => 'tree'
#
# Returns a String
def path_type(path)
if repository.tree(current_sha, path).entries.any?
'tree'
elsif repository.blob_at(current_sha, path).try(:image?)
'raw'
else
'blob'
end
end
def current_sha
context[:commit].try(:id) ||
ref ? repository.commit(ref).try(:sha) : repository.head_commit.sha
end
def relative_url_root
Gitlab.config.gitlab.relative_url_root.presence || '/'
end
def ref
context[:ref]
end
def repository
context[:project].try(:repository)
end
end
end
end
......@@ -5,7 +5,7 @@
#
module Gitlab
module OAuth
class ForbiddenAction < StandardError; end
class SignupDisabledError < StandardError; end
class User
attr_accessor :auth_hash, :gl_user
......@@ -99,7 +99,7 @@ module Gitlab
end
def unauthorized_to_create
raise ForbiddenAction.new("Unauthorized to create user, signup disabled for #{auth_hash.provider}")
raise SignupDisabledError
end
end
end
......
......@@ -7,7 +7,7 @@ module Gitlab
GRACE_TIME = (ENV['SIDEKIQ_MEMORY_KILLER_GRACE_TIME'] || 15 * 60).to_s.to_i
# Wait 30 seconds for running jobs to finish during graceful shutdown
SHUTDOWN_WAIT = (ENV['SIDEKIQ_MEMORY_KILLER_SHUTDOWN_WAIT'] || 30).to_s.to_i
SHUTDOWN_SIGNAL = (ENV['SIDEKIQ_MEMORY_KILLER_SHUTDOWN_SIGNAL'] || 'SIGTERM').to_s
SHUTDOWN_SIGNAL = (ENV['SIDEKIQ_MEMORY_KILLER_SHUTDOWN_SIGNAL'] || 'SIGKILL').to_s
# Create a mutex used to ensure there will be only one thread waiting to
# shut Sidekiq down
......
# Protects OmniAuth request phase against CSRF.
module OmniAuth
# Based on ActionController::RequestForgeryProtection.
class RequestForgeryProtection
def initialize(env)
@env = env
end
def request
@request ||= ActionDispatch::Request.new(@env)
end
def session
request.session
end
def reset_session
request.reset_session
end
def params
request.params
end
def call
verify_authenticity_token
end
def verify_authenticity_token
if !verified_request?
Rails.logger.warn "Can't verify CSRF token authenticity" if Rails.logger
handle_unverified_request
end
end
private
def protect_against_forgery?
ApplicationController.allow_forgery_protection
end
def request_forgery_protection_token
ApplicationController.request_forgery_protection_token
end
def forgery_protection_strategy
ApplicationController.forgery_protection_strategy
end
def verified_request?
!protect_against_forgery? || request.get? || request.head? ||
form_authenticity_token == params[request_forgery_protection_token] ||
form_authenticity_token == request.headers['X-CSRF-Token']
end
def handle_unverified_request
forgery_protection_strategy.new(self).handle_unverified_request
end
# Sets the token value for the current session.
def form_authenticity_token
session[:_csrf_token] ||= SecureRandom.base64(32)
end
end
end
......@@ -7,9 +7,12 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
def initialize(template, color_scheme, options = {})
@template = template
@color_scheme = color_scheme
@project = @template.instance_variable_get("@project")
@options = options.dup
@options.reverse_merge!(
project: @template.instance_variable_get("@project")
)
super(options)
end
......@@ -36,10 +39,6 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
end
def postprocess(full_document)
unless @template.instance_variable_get("@project_wiki") || @project.nil?
full_document = h.create_relative_links(full_document)
end
h.gfm_with_options(full_document, @options)
end
end
require "base64"
# This class is used to build image URL to
# check if it is a new version for update
class VersionCheck
def data
{ version: Gitlab::VERSION }
end
def url
encoded_data = Base64.urlsafe_encode64(data.to_json)
"#{host}?gitlab_info=#{encoded_data}"
end
def host
'https://version.gitlab.com/check.png'
end
end
<!DOCTYPE html>
<html>
<head>
<title>The page you were looking for doesn't exist (404)</title>
<title>The page you're looking for could not be found (404)</title>
<link href="/static.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>404</h1>
<h3>The page you were looking for doesn't exist.</h3>
<h3>The page you're looking for could not be found.</h3>
<hr/>
<p>You may have mistyped the address or the page may have moved.</p>
<p>Make sure the address is correct and that the page hasn't moved.</p>
<p>Please contact your GitLab administrator if you think this is a mistake.</p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>The change you wanted was rejected (422)</title>
<title>The change you requested was rejected (422)</title>
<link href="/static.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- This file lives in public/422.html -->
<h1>422</h1>
<div>
<h2>The change you wanted was rejected.</h2>
<p>Maybe you tried to change something you didn't have access to.</p>
</div>
<h3>The change you requested was rejected.</h3>
<hr />
<p>Make sure you have access to the thing you tried to change.</p>
<p>Please contact your GitLab administrator if you think this is a mistake.</p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>We're sorry, but something went wrong (500)</title>
<title>Something went wrong (500)</title>
<link href="/static.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>500</h1>
<h3>We're sorry, but something went wrong.</h3>
<h3>Whoops, something went wrong on our end.</h3>
<hr/>
<p>Try refreshing the page, or going back and attempting the action again.</p>
<p><a href="/help" >Please contact your GitLab administrator</a> if this problem persists.</p>
</body>
</html>
......@@ -6,8 +6,9 @@
</head>
<body>
<h1>502</h1>
<h3>GitLab is not responding.</h3>
<h3>Whoops, GitLab is taking too much time to respond.</h3>
<hr/>
<p>Try refreshing the page, or going back and attempting the action again.</p>
<p><a href="/help" >Please contact your GitLab administrator</a> if this problem persists.</p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Deploy in progress. Please try again in a few minutes</title>
<title>Deploy in progress</title>
<link href="/static.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<h1><center><img src="/gitlab_logo.png"/></center>Deploy in progress</h1>
<h3>Please try again in a few minutes or contact your administrator.</h3>
<h1>
<img src="/gitlab_logo.png" /><br />
Deploy in progress
</h1>
<h3>Please try again in a few minutes.</h3>
<hr/>
<p>Please contact your GitLab administrator if this problem persists.</p>
</body>
</html>
......@@ -2,18 +2,24 @@ body {
color: #666;
text-align: center;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin:0;
margin: 0;
width: 800px;
margin: auto;
font-size: 14px;
}
h1 {
font-size: 56px;
line-height: 100px;
font-weight: normal;
color: #456;
}
h2 { font-size: 24px; color: #666; line-height: 1.5em; }
h2 {
font-size: 24px;
color: #666;
line-height: 1.5em;
}
h3 {
color: #456;
......
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnp2mUaLBoHFX127ysonX
OihiGpI4098eFfH1iAxpKHIof0vs0jFF05IUScNXJZ1U3w8G1U/unY/wGGa3NzAb
ZfDd22eOF6X2Gfiey6U4w9dFf0/UT5x1bphlpX357yh4O9oWWuNaWD062DTbOOsJ
U6UW2U/sZAu/QScys0Nw+gJ58t93hb4jFq+nO5IAQc6g4S8ek5YvIXOshFEpF2in
ZLbSYowx92+9GzfjvdQ7fk0Q2ssg0zfScVa6FY8n019osz0SC3wcSd/qicdfecpu
7oycpd9YDqk4lufE1qVMOsgE8OO4KXMrByz2f+T0p/bH9zdBa5HYylf1T7i60hIL
kQIDAQAB
-----END PUBLIC KEY-----
......@@ -21,7 +21,7 @@ describe GitlabMarkdownHelper do
describe "#gfm" do
it "should forward HTML options to links" do
expect(gfm("Fixed in #{commit.id}", @project, class: 'foo')).
expect(gfm("Fixed in #{commit.id}", { project: @project }, class: 'foo')).
to have_selector('a.gfm.foo')
end
......@@ -96,79 +96,6 @@ describe GitlabMarkdownHelper do
end
end
describe "#markdown" do
# TODO (rspeicher): These belong in a relative link filter spec
context 'relative links' do
context 'with a valid repository' do
before do
@repository = project.repository
@ref = 'markdown'
end
it "should handle relative urls for a file in master" do
actual = "[GitLab API doc](doc/api/README.md)\n"
expected = "<p><a href=\"/#{project.path_with_namespace}/blob/#{@ref}/doc/api/README.md\">GitLab API doc</a></p>\n"
expect(markdown(actual)).to match(expected)
end
it "should handle relative urls for a file in master with an anchor" do
actual = "[GitLab API doc](doc/api/README.md#section)\n"
expected = "<p><a href=\"/#{project.path_with_namespace}/blob/#{@ref}/doc/api/README.md#section\">GitLab API doc</a></p>\n"
expect(markdown(actual)).to match(expected)
end
it "should not handle relative urls for the current file with an anchor" do
actual = "[GitLab API doc](#section)\n"
expected = "<p><a href=\"#section\">GitLab API doc</a></p>\n"
expect(markdown(actual)).to match(expected)
end
it "should handle relative urls for a directory in master" do
actual = "[GitLab API doc](doc/api)\n"
expected = "<p><a href=\"/#{project.path_with_namespace}/tree/#{@ref}/doc/api\">GitLab API doc</a></p>\n"
expect(markdown(actual)).to match(expected)
end
it "should handle absolute urls" do
actual = "[GitLab](https://www.gitlab.com)\n"
expected = "<p><a href=\"https://www.gitlab.com\">GitLab</a></p>\n"
expect(markdown(actual)).to match(expected)
end
it "should handle relative urls in reference links for a file in master" do
actual = "[GitLab API doc][GitLab readme]\n [GitLab readme]: doc/api/README.md\n"
expected = "<p><a href=\"/#{project.path_with_namespace}/blob/#{@ref}/doc/api/README.md\">GitLab API doc</a></p>\n"
expect(markdown(actual)).to match(expected)
end
it "should handle relative urls in reference links for a directory in master" do
actual = "[GitLab API doc directory][GitLab readmes]\n [GitLab readmes]: doc/api/\n"
expected = "<p><a href=\"/#{project.path_with_namespace}/tree/#{@ref}/doc/api\">GitLab API doc directory</a></p>\n"
expect(markdown(actual)).to match(expected)
end
it "should not handle malformed relative urls in reference links for a file in master" do
actual = "[GitLab readme]: doc/api/README.md\n"
expected = ""
expect(markdown(actual)).to match(expected)
end
end
context 'with an empty repository' do
before do
@project = create(:empty_project)
@repository = @project.repository
end
it "should not touch relative urls" do
actual = "[GitLab API doc][GitLab readme]\n [GitLab readme]: doc/api/README.md\n"
expected = "<p><a href=\"doc/api/README.md\">GitLab API doc</a></p>\n"
expect(markdown(actual)).to match(expected)
end
end
end
end
describe '#render_wiki_content' do
before do
@wiki = double('WikiPage')
......
......@@ -115,18 +115,10 @@ describe Gitlab::GitAccess do
let(:actor) { key }
context 'pull code' do
context 'allowed' do
before { key.projects << project }
subject { access.download_access_check }
it { expect(subject.allowed?).to be_truthy }
end
context 'denied' do
subject { access.download_access_check }
before { key.projects << project }
subject { access.download_access_check }
it { expect(subject.allowed?).to be_falsey }
end
it { expect(subject.allowed?).to be_truthy }
end
end
end
......
require 'spec_helper'
module Gitlab::Markdown
describe RelativeLinkFilter do
def filter(doc)
described_class.call(doc, {
commit: project.commit,
project: project,
project_wiki: project_wiki,
ref: ref,
requested_path: requested_path
})
end
def image(path)
%(<img src="#{path}" />)
end
def link(path)
%(<a href="#{path}">#{path}</a>)
end
let(:project) { create(:project) }
let(:project_path) { project.path_with_namespace }
let(:ref) { 'markdown' }
let(:project_wiki) { nil }
let(:requested_path) { '/' }
shared_examples :preserve_unchanged do
it 'does not modify any relative URL in anchor' do
doc = filter(link('README.md'))
expect(doc.at_css('a')['href']).to eq 'README.md'
end
it 'does not modify any relative URL in image' do
doc = filter(image('files/images/logo-black.png'))
expect(doc.at_css('img')['src']).to eq 'files/images/logo-black.png'
end
end
shared_examples :relative_to_requested do
it 'rebuilds URL relative to the requested path' do
doc = filter(link('users.md'))
expect(doc.at_css('a')['href']).
to eq "/#{project_path}/blob/#{ref}/doc/api/users.md"
end
end
context 'with a project_wiki' do
let(:project_wiki) { double('ProjectWiki') }
include_examples :preserve_unchanged
end
context 'without a repository' do
let(:project) { create(:empty_project) }
include_examples :preserve_unchanged
end
context 'with an empty repository' do
let(:project) { create(:project_empty_repo) }
include_examples :preserve_unchanged
end
it 'does not raise an exception on invalid URIs' do
act = link("://foo")
expect { filter(act) }.not_to raise_error
end
context 'with a valid repository' do
it 'rebuilds relative URL for a file in the repo' do
doc = filter(link('doc/api/README.md'))
expect(doc.at_css('a')['href']).
to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
end
it 'rebuilds relative URL for a file in the repo with an anchor' do
doc = filter(link('README.md#section'))
expect(doc.at_css('a')['href']).
to eq "/#{project_path}/blob/#{ref}/README.md#section"
end
it 'rebuilds relative URL for a directory in the repo' do
doc = filter(link('doc/api/'))
expect(doc.at_css('a')['href']).
to eq "/#{project_path}/tree/#{ref}/doc/api"
end
it 'rebuilds relative URL for an image in the repo' do
doc = filter(link('files/images/logo-black.png'))
expect(doc.at_css('a')['href']).
to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png"
end
it 'does not modify relative URL with an anchor only' do
doc = filter(link('#section-1'))
expect(doc.at_css('a')['href']).to eq '#section-1'
end
it 'does not modify absolute URL' do
doc = filter(link('http://example.com'))
expect(doc.at_css('a')['href']).to eq 'http://example.com'
end
context 'when requested path is a file in the repo' do
let(:requested_path) { 'doc/api/README.md' }
include_examples :relative_to_requested
end
context 'when requested path is a directory in the repo' do
let(:requested_path) { 'doc/api' }
include_examples :relative_to_requested
end
end
end
end
......@@ -86,6 +86,15 @@ describe API::API, api: true do
expect(json_response).to be_an Array
expect(json_response.first['id']).to eq(project3.id)
end
it 'returns projects in the correct order when ci_enabled_first parameter is passed' do
[project, project2, project3].each{ |project| project.build_missing_services }
project2.gitlab_ci_service.update(active: true, token: "token", project_url: "url")
get api('/projects', user), { ci_enabled_first: 'true'}
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.first['id']).to eq(project2.id)
end
end
end
end
......
......@@ -30,11 +30,18 @@ describe MergeRequests::RefreshService do
end
context 'push to origin repo source branch' do
let(:refresh_service) { service.new(@project, @user) }
before do
service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master')
allow(refresh_service).to receive(:execute_hooks)
refresh_service.execute(@oldrev, @newrev, 'refs/heads/master')
reload_mrs
end
it 'should execute hooks with update action' do
expect(refresh_service).to have_received(:execute_hooks).
with(@merge_request, 'update')
end
it { expect(@merge_request.notes).not_to be_empty }
it { expect(@merge_request).to be_open }
it { expect(@fork_merge_request).to be_open }
......@@ -54,11 +61,18 @@ describe MergeRequests::RefreshService do
end
context 'push to fork repo source branch' do
let(:refresh_service) { service.new(@fork_project, @user) }
before do
service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/master')
allow(refresh_service).to receive(:execute_hooks)
refresh_service.execute(@oldrev, @newrev, 'refs/heads/master')
reload_mrs
end
it 'should execute hooks with update action' do
expect(refresh_service).to have_received(:execute_hooks).
with(@fork_merge_request, 'update')
end
it { expect(@merge_request.notes).to be_empty }
it { expect(@merge_request).to be_open }
it { expect(@fork_merge_request.notes.last.note).to include('Added 4 commits') }
......
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