Commit 843694f9 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'master' into ci-and-ce-sitting-in-a-tree-k-i-s-s-i-n-g

parents 6afd69f4 de3b7d9c
...@@ -21,7 +21,6 @@ config/aws.yml ...@@ -21,7 +21,6 @@ config/aws.yml
config/database.yml config/database.yml
config/gitlab.yml config/gitlab.yml
config/gitlab_ci.yml config/gitlab_ci.yml
config/initializers/omniauth.rb
config/initializers/rack_attack.rb config/initializers/rack_attack.rb
config/initializers/smtp_settings.rb config/initializers/smtp_settings.rb
config/resque.yml config/resque.yml
......
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 8.0.0 (unreleased) v 8.0.0 (unreleased)
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu) - Prevent too many redirects upon login when home page URL is set to external_url (Stan Hu)
- Improve dropdown positioning on the project home page (Hannes Rosenögger)
- Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibilty mode (Stan Hu)
- Remove user OAuth tokens from the database and request new tokens each session (Stan Hu) - Remove user OAuth tokens from the database and request new tokens each session (Stan Hu)
- Only show recent push event if the branch still exists or a recent merge request has not been created (Stan Hu) - Only show recent push event if the branch still exists or a recent merge request has not been created (Stan Hu)
- Remove satellites - Remove satellites
...@@ -13,6 +15,17 @@ v 8.0.0 (unreleased) ...@@ -13,6 +15,17 @@ v 8.0.0 (unreleased)
- Search for comments should be case insensetive - Search for comments should be case insensetive
- Create cross-reference for closing references on commits pushed to non-default branches (Maël Valais) - Create cross-reference for closing references on commits pushed to non-default branches (Maël Valais)
- Ability to search milestones - Ability to search milestones
- Gracefully handle SMTP user input errors (e.g. incorrect email addresses) to prevent Sidekiq retries (Stan Hu)
- Move dashboard activity to separate page
- Improve performance of git blame
- Limit content width to 1200px for most of pages to improve readability on big screens
v 7.14.1
- Improve abuse reports management from admin area
- Fix "Reload with full diff" URL button in compare branch view (Stan Hu)
- Only include base URL in OmniAuth full_host parameter (Stan Hu)
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu)
- Ability to enable SSL verification for Webhooks
v 7.14.0 v 7.14.0
- Fix bug where non-project members of the target project could set labels on new merge requests. - Fix bug where non-project members of the target project could set labels on new merge requests.
...@@ -298,6 +311,7 @@ v 7.11.0 ...@@ -298,6 +311,7 @@ v 7.11.0
- Protect OmniAuth request phase against CSRF. - Protect OmniAuth request phase against CSRF.
- Don't send notifications to mentioned users that don't have access to the project in question. - Don't send notifications to mentioned users that don't have access to the project in question.
- Add search issues/MR by number - Add search issues/MR by number
- Change plots to bar graphs in commit statistics screen
- Move snippets UI to fluid layout - Move snippets UI to fluid layout
- Improve UI for sidebar. Increase separation between navigation and content - Improve UI for sidebar. Increase separation between navigation and content
- Improve new project command options (Ben Bodenmiller) - Improve new project command options (Ben Bodenmiller)
......
...@@ -42,7 +42,7 @@ gem 'rqrcode-rails3', '~> 0.1.7' ...@@ -42,7 +42,7 @@ gem 'rqrcode-rails3', '~> 0.1.7'
gem 'attr_encrypted', '~> 1.3.4' gem 'attr_encrypted', '~> 1.3.4'
# Browser detection # Browser detection
gem "browser", '~> 0.8.0' gem "browser", '~> 1.0.0'
# Extracting information from a git repository # Extracting information from a git repository
# Provide access to Gitlab::Git library # Provide access to Gitlab::Git library
...@@ -285,7 +285,7 @@ gem "newrelic_rpm", '~> 3.9.4.245' ...@@ -285,7 +285,7 @@ gem "newrelic_rpm", '~> 3.9.4.245'
gem 'octokit', '~> 3.7.0' gem 'octokit', '~> 3.7.0'
gem "mail_room", "~> 0.4.0" gem "mail_room", "~> 0.4.1"
gem 'email_reply_parser', '~> 0.5.8' gem 'email_reply_parser', '~> 0.5.8'
......
...@@ -82,7 +82,7 @@ GEM ...@@ -82,7 +82,7 @@ GEM
ruby_parser (~> 3.7.0) ruby_parser (~> 3.7.0)
sass (~> 3.0) sass (~> 3.0)
terminal-table (~> 1.4) terminal-table (~> 1.4)
browser (0.8.0) browser (1.0.0)
builder (3.2.2) builder (3.2.2)
byebug (6.0.2) byebug (6.0.2)
cal-heatmap-rails (0.0.1) cal-heatmap-rails (0.0.1)
...@@ -388,7 +388,7 @@ GEM ...@@ -388,7 +388,7 @@ GEM
systemu (~> 2.6.2) systemu (~> 2.6.2)
mail (2.6.3) mail (2.6.3)
mime-types (>= 1.16, < 3) mime-types (>= 1.16, < 3)
mail_room (0.4.0) mail_room (0.4.1)
method_source (0.8.2) method_source (0.8.2)
mime-types (1.25.1) mime-types (1.25.1)
mimemagic (0.3.0) mimemagic (0.3.0)
...@@ -790,7 +790,7 @@ DEPENDENCIES ...@@ -790,7 +790,7 @@ DEPENDENCIES
binding_of_caller (~> 0.7.2) binding_of_caller (~> 0.7.2)
bootstrap-sass (~> 3.0) bootstrap-sass (~> 3.0)
brakeman brakeman
browser (~> 0.8.0) browser (~> 1.0.0)
byebug byebug
cal-heatmap-rails (~> 0.0.1) cal-heatmap-rails (~> 0.0.1)
capybara (~> 2.4.0) capybara (~> 2.4.0)
...@@ -846,7 +846,7 @@ DEPENDENCIES ...@@ -846,7 +846,7 @@ DEPENDENCIES
jquery-ui-rails (~> 4.2.1) jquery-ui-rails (~> 4.2.1)
kaminari (~> 0.15.1) kaminari (~> 0.15.1)
letter_opener (~> 1.1.2) letter_opener (~> 1.1.2)
mail_room (~> 0.4.0) mail_room (~> 0.4.1)
minitest (~> 5.7.0) minitest (~> 5.7.0)
mousetrap-rails (~> 1.4.6) mousetrap-rails (~> 1.4.6)
mysql2 (~> 0.3.16) mysql2 (~> 0.3.16)
......
...@@ -116,6 +116,12 @@ $ -> ...@@ -116,6 +116,12 @@ $ ->
$('.remove-row').bind 'ajax:success', -> $('.remove-row').bind 'ajax:success', ->
$(this).closest('li').fadeOut() $(this).closest('li').fadeOut()
$('.js-remove-tr').bind 'ajax:before', ->
$(this).hide()
$('.js-remove-tr').bind 'ajax:success', ->
$(this).closest('tr').fadeOut()
# Initialize select2 selects # Initialize select2 selects
$('select.select2').select2(width: 'resolve', dropdownAutoWidth: true) $('select.select2').select2(width: 'resolve', dropdownAutoWidth: true)
......
...@@ -51,6 +51,7 @@ class Dispatcher ...@@ -51,6 +51,7 @@ class Dispatcher
MergeRequests.init() MergeRequests.init()
when 'dashboard:show', 'root:show' when 'dashboard:show', 'root:show'
new Dashboard() new Dashboard()
when 'dashboard:activity'
new Activities() new Activities()
when 'dashboard:projects:starred' when 'dashboard:projects:starred'
new Activities() new Activities()
......
...@@ -8,7 +8,7 @@ class @ProjectsList ...@@ -8,7 +8,7 @@ class @ProjectsList
$(".projects-list-filter").keyup -> $(".projects-list-filter").keyup ->
terms = $(this).val() terms = $(this).val()
uiBox = $(this).closest('.panel') uiBox = $(this).closest('.projects-list-holder')
if terms == "" || terms == undefined if terms == "" || terms == undefined
uiBox.find(".projects-list li").show() uiBox.find(".projects-list li").show()
else else
......
...@@ -20,3 +20,8 @@ html { ...@@ -20,3 +20,8 @@ html {
.navless-container { .navless-container {
margin-top: 30px; margin-top: 30px;
} }
.container-limited {
max-width: $fixed-layout-width;
}
...@@ -13,7 +13,7 @@ $code_line_height: 1.5; ...@@ -13,7 +13,7 @@ $code_line_height: 1.5;
$border-color: #E5E5E5; $border-color: #E5E5E5;
$background-color: #f5f5f5; $background-color: #f5f5f5;
$header-height: 50px; $header-height: 50px;
$readable-width: 1100px; $fixed-layout-width: 1200px;
/* /*
......
...@@ -20,16 +20,16 @@ header { ...@@ -20,16 +20,16 @@ header {
} }
&.navbar-gitlab { &.navbar-gitlab {
padding: 0 20px;
z-index: 100; z-index: 100;
margin-bottom: 0; margin-bottom: 0;
min-height: $header-height; min-height: $header-height;
border: none; border: none;
width: 100%; border-bottom: 1px solid #EEE;
.container { .container-fluid {
background: #FFF; background: #FFF;
width: 100% !important; width: 100% !important;
padding: 0;
filter: none; filter: none;
.nav > li > a { .nav > li > a {
...@@ -64,55 +64,11 @@ header { ...@@ -64,55 +64,11 @@ header {
} }
} }
.header-logo {
border-bottom: 1px solid transparent;
float: left;
height: $header-height;
width: $sidebar_width;
overflow: hidden;
transition-duration: .3s;
a {
float: left;
height: $header-height;
width: 100%;
padding: ($header-height - 36 ) / 2 8px;
overflow: hidden;
img {
width: 36px;
height: 36px;
float: left;
}
.gitlab-text-container {
width: 230px;
h3 {
width: 158px;
float: left;
margin: 0;
margin-left: 14px;
font-size: 18px;
line-height: $header-height - 14;
font-weight: normal;
}
}
}
&:hover {
background-color: #EEE;
}
}
.header-content { .header-content {
border-bottom: 1px solid #EEE;
padding-right: 35px;
height: $header-height; height: $header-height;
.title { .title {
margin: 0; margin: 0;
padding: 0 15px 0 35px;
overflow: hidden; overflow: hidden;
font-size: 18px; font-size: 18px;
line-height: $header-height; line-height: $header-height;
...@@ -168,15 +124,7 @@ header { ...@@ -168,15 +124,7 @@ header {
} }
@mixin collapsed-header { @mixin collapsed-header {
.header-logo { margin-left: $sidebar_collapsed_width;
width: $sidebar_collapsed_width;
}
.header-content {
.title {
margin-left: 30px;
}
}
} }
@media (max-width: $screen-md-max) { @media (max-width: $screen-md-max) {
...@@ -191,16 +139,14 @@ header { ...@@ -191,16 +139,14 @@ header {
} }
.header-expanded { .header-expanded {
margin-left: $sidebar_width;
} }
} }
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
header .container { header .container-fluid {
font-size: 18px; font-size: 18px;
.title {
}
.navbar-nav { .navbar-nav {
margin: 0px; margin: 0px;
float: none !important; float: none !important;
......
...@@ -188,3 +188,46 @@ ...@@ -188,3 +188,46 @@
width: $sidebar_width - 2 * 10px; width: $sidebar_width - 2 * 10px;
} }
} }
.sidebar-wrapper {
.header-logo {
border-bottom: 1px solid transparent;
float: left;
height: $header-height;
width: $sidebar_width;
overflow: hidden;
transition-duration: .3s;
a {
float: left;
height: $header-height;
width: 100%;
padding: ($header-height - 36 ) / 2 8px;
overflow: hidden;
img {
width: 36px;
height: 36px;
float: left;
}
.gitlab-text-container {
width: 230px;
h3 {
width: 158px;
float: left;
margin: 0;
margin-left: 14px;
font-size: 18px;
line-height: $header-height - 14;
font-weight: normal;
}
}
}
&:hover {
background-color: #EEE;
}
}
}
...@@ -23,41 +23,6 @@ ...@@ -23,41 +23,6 @@
} }
} }
.project-row, .group-row {
padding: 0 !important;
font-size: 14px;
line-height: 24px;
a {
display: block;
padding: 8px 15px;
}
.project-name, .group-name {
font-weight: 500;
}
.arrow {
float: right;
margin: 0;
font-size: 20px;
}
.last-activity {
float: right;
font-size: 12px;
color: #AAA;
display: block;
.date {
color: #777;
}
}
}
.project-description {
overflow: hidden;
}
.project-access-icon { .project-access-icon {
margin-left: 10px; margin-left: 10px;
float: left; float: left;
...@@ -73,10 +38,9 @@ ...@@ -73,10 +38,9 @@
float: left; float: left;
.avatar { .avatar {
margin-top: -8px;
margin-left: -15px;
@include border-radius(0px); @include border-radius(0px);
} }
.identicon { .identicon {
line-height: 40px; line-height: 40px;
} }
......
...@@ -45,9 +45,3 @@ ...@@ -45,9 +45,3 @@
.btn { font-size: 13px; } .btn { font-size: 13px; }
} }
.issuable-details {
.description {
max-width: $readable-width;
}
}
...@@ -30,14 +30,21 @@ ...@@ -30,14 +30,21 @@
} }
} }
.project-home-dropdown {
margin: 11px 3px 0;
}
.project-home-desc { .project-home-desc {
h1 { h1 {
margin: 0; margin: 0;
margin-bottom: 10px; margin-bottom: 10px;
font-size: 26px; font-size: 26px;
font-weight: bold;
} }
p { p {
font-size: 18px;
color: #666;
display: inline; display: inline;
} }
} }
...@@ -316,3 +323,34 @@ table.table.protected-branches-list tr.no-border { ...@@ -316,3 +323,34 @@ table.table.protected-branches-list tr.no-border {
pre.light-well { pre.light-well {
border-color: #f1f1f1; border-color: #f1f1f1;
} }
.projects-search-form {
max-width: 600px;
margin: 0 auto;
margin-bottom: 20px;
input {
border-color: #BBB;
}
}
.project-row {
.project-full-name {
font-weight: bold;
font-size: 15px;
}
.project-description {
color: #888;
font-size: 13px;
p {
margin-bottom: 0;
color: #888;
}
}
}
.my-projects .project-row {
padding: 10px 0;
}
...@@ -117,7 +117,6 @@ ...@@ -117,7 +117,6 @@
.readme-holder { .readme-holder {
margin: 0 auto; margin: 0 auto;
max-width: $readable-width;
.readme-file-title { .readme-file-title {
font-size: 14px; font-size: 14px;
......
...@@ -7,27 +7,23 @@ ...@@ -7,27 +7,23 @@
* $color-dark - * $color-dark -
*/ */
@mixin gitlab-theme($color-light, $color, $color-darker, $color-dark) { @mixin gitlab-theme($color-light, $color, $color-darker, $color-dark) {
header { .page-with-sidebar {
&.navbar-gitlab { .header-logo {
.header-logo { background-color: $color-darker;
background-color: $color-darker; border-color: $color-darker;
border-color: $color-darker;
a { a {
color: $color-light; color: $color-light;
} }
&:hover { &:hover {
background-color: $color-dark; background-color: $color-dark;
a { a {
color: #FFF; color: #FFF;
}
} }
} }
} }
}
.page-with-sidebar {
.collapse-nav a { .collapse-nav a {
color: #FFF; color: #FFF;
background: $color; background: $color;
......
...@@ -4,8 +4,13 @@ class Admin::AbuseReportsController < Admin::ApplicationController ...@@ -4,8 +4,13 @@ class Admin::AbuseReportsController < Admin::ApplicationController
end end
def destroy def destroy
AbuseReport.find(params[:id]).destroy abuse_report = AbuseReport.find(params[:id])
redirect_to admin_abuse_reports_path, notice: 'Report was removed' if params[:remove_user]
abuse_report.user.destroy
end
abuse_report.destroy
render nothing: true
end end
end end
...@@ -39,6 +39,6 @@ class Admin::HooksController < Admin::ApplicationController ...@@ -39,6 +39,6 @@ class Admin::HooksController < Admin::ApplicationController
end end
def hook_params def hook_params
params.require(:hook).permit(:url) params.require(:hook).permit(:url, :enable_ssl_verification)
end end
end end
...@@ -59,7 +59,9 @@ class ApplicationController < ActionController::Base ...@@ -59,7 +59,9 @@ class ApplicationController < ActionController::Base
def authenticate_user!(*args) def authenticate_user!(*args)
# If user is not signed-in and tries to access root_path - redirect him to landing page # If user is not signed-in and tries to access root_path - redirect him to landing page
if current_application_settings.home_page_url.present? # Don't redirect to the default URL to prevent endless redirections
if current_application_settings.home_page_url.present? &&
current_application_settings.home_page_url.chomp('/') != Gitlab.config.gitlab['url'].chomp('/')
if current_user.nil? && root_path == request.path if current_user.nil? && root_path == request.path
redirect_to current_application_settings.home_page_url and return redirect_to current_application_settings.home_page_url and return
end end
......
class DashboardController < Dashboard::ApplicationController class DashboardController < Dashboard::ApplicationController
before_action :load_projects before_action :load_projects
before_action :event_filter, only: :show before_action :event_filter, only: :activity
respond_to :html respond_to :html
...@@ -10,13 +10,8 @@ class DashboardController < Dashboard::ApplicationController ...@@ -10,13 +10,8 @@ class DashboardController < Dashboard::ApplicationController
respond_to do |format| respond_to do |format|
format.html format.html
format.json do
load_events
pager_json("events/_events", @events.count)
end
format.atom do format.atom do
event_filter
load_events load_events
render layout: false render layout: false
end end
...@@ -40,6 +35,19 @@ class DashboardController < Dashboard::ApplicationController ...@@ -40,6 +35,19 @@ class DashboardController < Dashboard::ApplicationController
end end
end end
def activity
@last_push = current_user.recent_push
respond_to do |format|
format.html
format.json do
load_events
pager_json("events/_events", @events.count)
end
end
end
protected protected
def load_projects def load_projects
......
...@@ -53,6 +53,7 @@ class Projects::HooksController < Projects::ApplicationController ...@@ -53,6 +53,7 @@ class Projects::HooksController < Projects::ApplicationController
end end
def hook_params def hook_params
params.require(:hook).permit(:url, :push_events, :issues_events, :merge_requests_events, :tag_push_events, :note_events) params.require(:hook).permit(:url, :push_events, :issues_events,
:merge_requests_events, :tag_push_events, :note_events, :enable_ssl_verification)
end end
end end
...@@ -8,7 +8,7 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -8,7 +8,7 @@ class Projects::ServicesController < Projects::ApplicationController
:push_events, :issues_events, :merge_requests_events, :tag_push_events, :push_events, :issues_events, :merge_requests_events, :tag_push_events,
:note_events, :send_from_committer_email, :disable_diffs, :external_wiki_url, :note_events, :send_from_committer_email, :disable_diffs, :external_wiki_url,
:notify, :color, :notify, :color,
:server_host, :server_port, :default_irc_uri] :server_host, :server_port, :default_irc_uri, :enable_ssl_verification]
# Authorize # Authorize
before_action :authorize_admin_project! before_action :authorize_admin_project!
before_action :service, only: [:edit, :update, :test] before_action :service, only: [:edit, :update, :test]
......
...@@ -24,5 +24,14 @@ module Gitlab ...@@ -24,5 +24,14 @@ module Gitlab
@sidebar @sidebar
end end
end end
def fluid_layout(enabled = false)
if @fluid_layout.nil?
@fluid_layout = enabled
else
@fluid_layout
end
end
end end
end end
module PageLayoutHelper
def page_title(*titles)
@page_title ||= []
@page_title.push(*titles.compact) if titles.any?
@page_title.join(" | ")
end
def header_title(title = nil, title_url = nil)
if title
@header_title = title
@header_title_url = title_url
else
@header_title_url ? link_to(@header_title, @header_title_url) : @header_title
end
end
def sidebar(name = nil)
if name
@sidebar = name
else
@sidebar
end
end
def fluid_layout(enabled = false)
if @fluid_layout.nil?
@fluid_layout = enabled
else
@fluid_layout
end
end
end
...@@ -3,6 +3,8 @@ class EmailRejectionMailer < BaseMailer ...@@ -3,6 +3,8 @@ class EmailRejectionMailer < BaseMailer
@reason = reason @reason = reason
@original_message = Mail::Message.new(original_raw) @original_message = Mail::Message.new(original_raw)
return unless @original_message.from
headers = { headers = {
to: @original_message.from, to: @original_message.from,
subject: "[Rejected] #{@original_message.subject}" subject: "[Rejected] #{@original_message.subject}"
......
...@@ -25,6 +25,7 @@ class WebHook < ActiveRecord::Base ...@@ -25,6 +25,7 @@ class WebHook < ActiveRecord::Base
default_value_for :note_events, false default_value_for :note_events, false
default_value_for :merge_requests_events, false default_value_for :merge_requests_events, false
default_value_for :tag_push_events, false default_value_for :tag_push_events, false
default_value_for :enable_ssl_verification, false
# HTTParty timeout # HTTParty timeout
default_timeout Gitlab.config.gitlab.webhook_timeout default_timeout Gitlab.config.gitlab.webhook_timeout
...@@ -41,7 +42,7 @@ class WebHook < ActiveRecord::Base ...@@ -41,7 +42,7 @@ class WebHook < ActiveRecord::Base
"Content-Type" => "application/json", "Content-Type" => "application/json",
"X-Gitlab-Event" => hook_name.singularize.titleize "X-Gitlab-Event" => hook_name.singularize.titleize
}, },
verify: false) verify: enable_ssl_verification)
else else
post_url = url.gsub("#{parsed_url.userinfo}@", "") post_url = url.gsub("#{parsed_url.userinfo}@", "")
auth = { auth = {
...@@ -54,7 +55,7 @@ class WebHook < ActiveRecord::Base ...@@ -54,7 +55,7 @@ class WebHook < ActiveRecord::Base
"Content-Type" => "application/json", "Content-Type" => "application/json",
"X-Gitlab-Event" => hook_name.singularize.titleize "X-Gitlab-Event" => hook_name.singularize.titleize
}, },
verify: false, verify: enable_ssl_verification,
basic_auth: auth) basic_auth: auth)
end end
rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e
......
...@@ -23,7 +23,7 @@ require "addressable/uri" ...@@ -23,7 +23,7 @@ require "addressable/uri"
class BuildkiteService < CiService class BuildkiteService < CiService
ENDPOINT = "https://buildkite.com" ENDPOINT = "https://buildkite.com"
prop_accessor :project_url, :token prop_accessor :project_url, :token, :enable_ssl_verification
validates :project_url, presence: true, if: :activated? validates :project_url, presence: true, if: :activated?
validates :token, presence: true, if: :activated? validates :token, presence: true, if: :activated?
...@@ -37,6 +37,7 @@ class BuildkiteService < CiService ...@@ -37,6 +37,7 @@ class BuildkiteService < CiService
def compose_service_hook def compose_service_hook
hook = service_hook || build_service_hook hook = service_hook || build_service_hook
hook.url = webhook_url hook.url = webhook_url
hook.enable_ssl_verification = enable_ssl_verification
hook.save hook.save
end end
...@@ -96,7 +97,11 @@ class BuildkiteService < CiService ...@@ -96,7 +97,11 @@ class BuildkiteService < CiService
{ type: 'text', { type: 'text',
name: 'project_url', name: 'project_url',
placeholder: "#{ENDPOINT}/example/project" } placeholder: "#{ENDPOINT}/example/project" },
{ type: 'checkbox',
name: 'enable_ssl_verification',
title: "Enable SSL verification" }
] ]
end end
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
class GitlabCiService < CiService class GitlabCiService < CiService
API_PREFIX = "api/v1" API_PREFIX = "api/v1"
prop_accessor :project_url, :token prop_accessor :project_url, :token, :enable_ssl_verification
validates :project_url, validates :project_url,
presence: true, presence: true,
format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated? format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated?
...@@ -34,6 +34,7 @@ class GitlabCiService < CiService ...@@ -34,6 +34,7 @@ class GitlabCiService < CiService
def compose_service_hook def compose_service_hook
hook = service_hook || build_service_hook hook = service_hook || build_service_hook
hook.url = [project_url, "/build", "?token=#{token}"].join("") hook.url = [project_url, "/build", "?token=#{token}"].join("")
hook.enable_ssl_verification = enable_ssl_verification
hook.save hook.save
end end
...@@ -136,7 +137,8 @@ class GitlabCiService < CiService ...@@ -136,7 +137,8 @@ class GitlabCiService < CiService
def fields def fields
[ [
{ type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' }, { type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' },
{ type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' } { type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' },
{ type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
] ]
end end
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
%tr %tr
%td %td
- if reporter - if reporter
= link_to reporter.name, [:admin, reporter] = link_to reporter.name, reporter
- else - else
(removed) (removed)
%td %td
...@@ -12,12 +12,15 @@ ...@@ -12,12 +12,15 @@
= abuse_report.message = abuse_report.message
%td %td
- if user - if user
= link_to user.name, [:admin, user] = link_to user.name, user
- else - else
(removed) (removed)
%td %td
- if user - if user
= link_to 'Block', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs btn-warning" = link_to 'Remove user & report', admin_abuse_report_path(abuse_report, remove_user: true),
= link_to 'Remove user', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, method: :delete, class: "btn btn-xs btn-remove" data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, remote: true, method: :delete, class: "btn btn-xs btn-remove js-remove-tr"
%td %td
= link_to 'Remove report', [:admin, abuse_report], method: :delete, class: "btn btn-xs btn-close" - if user
= link_to 'Block user', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs"
= link_to 'Remove report', [:admin, abuse_report], remote: true, method: :delete, class: "btn btn-xs btn-close js-remove-tr"
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
%th Reported at %th Reported at
%th Message %th Message
%th User %th User
%th %th Primary action
%th %th
= render @abuse_reports = render @abuse_reports
= paginate @abuse_reports = paginate @abuse_reports
......
...@@ -18,6 +18,13 @@ ...@@ -18,6 +18,13 @@
= f.label :url, "URL:", class: 'control-label' = f.label :url, "URL:", class: 'control-label'
.col-sm-10 .col-sm-10
= f.text_field :url, class: "form-control" = f.text_field :url, class: "form-control"
.form-group
= f.label :enable_ssl_verification, "SSL verification", class: 'control-label checkbox'
.col-sm-10
.checkbox
= f.label :enable_ssl_verification do
= f.check_box :enable_ssl_verification
%strong Enable SSL verification
.form-actions .form-actions
= f.submit "Add System Hook", class: "btn btn-create" = f.submit "Add System Hook", class: "btn btn-create"
%hr %hr
...@@ -32,6 +39,7 @@ ...@@ -32,6 +39,7 @@
.list-item-name .list-item-name
= link_to admin_hook_path(hook) do = link_to admin_hook_path(hook) do
%strong= hook.url %strong= hook.url
%p SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"}
.pull-right .pull-right
= link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm" = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm"
......
.panel.panel-default .projects-list-holder
.panel-heading.clearfix .projects-search-form
.input-group .input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
- if current_user.can_create_project? - if current_user.can_create_project?
...@@ -7,4 +7,7 @@ ...@@ -7,4 +7,7 @@
= link_to new_project_path, class: 'btn btn-success' do = link_to new_project_path, class: 'btn btn-success' do
New project New project
= render 'shared/projects_list', projects: @projects, projects_limit: 20 %ul.projects-list.bordered-list.my-projects
- @projects.each do |project|
%li.project-row
= render partial: 'shared/project', locals: { project: project, avatar: true, stars: true }
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity")
%section.activities
= render 'activities'
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
= render 'shared/show_aside' = render 'shared/show_aside'
.dashboard.row .dashboard.row
%section.activities.col-md-8 %section.activities.col-md-7
= render 'dashboard/activities' = render 'dashboard/activities'
%aside.col-md-4 %aside.col-md-5
.panel.panel-default .panel.panel-default.projects-list-holder
.panel-heading.clearfix .panel-heading.clearfix
.input-group .input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
......
...@@ -4,14 +4,10 @@ ...@@ -4,14 +4,10 @@
= render 'dashboard/projects_head' = render 'dashboard/projects_head'
- if @projects.any? - if @last_push
= render 'shared/show_aside' = render "events/event_last_push", event: @last_push
.dashboard.row
%section.activities.col-md-8
= render 'activities'
%aside.col-md-4
= render 'sidebar'
- if @projects.any?
= render 'projects'
- else - else
= render "zero_authorized_projects" = render "zero_authorized_projects"
...@@ -9,6 +9,6 @@ ...@@ -9,6 +9,6 @@
#{time_ago_with_tooltip(event.created_at)} #{time_ago_with_tooltip(event.created_at)}
.pull-right .pull-right
= link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-sm" do = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-info btn-sm" do
Create Merge Request Create Merge Request
%hr %hr
%li
%h4.project-title
.project-access-icon
= visibility_level_icon(project.visibility_level)
= link_to project.name_with_namespace, [project.namespace.becomes(Namespace), project]
%span.pull-right
%i.fa.fa-star
= project.star_count
.project-info
- if project.description.present?
.project-description.str-truncated
= markdown(project.description, pipeline: :description)
.repo-info
- unless project.empty_repo?
= link_to pluralize(round_commit_count(project), 'commit'), namespace_project_commits_path(project.namespace, project, project.default_branch)
&middot;
= link_to pluralize(project.repository.branch_names.count, 'branch'), namespace_project_branches_path(project.namespace, project)
&middot;
= link_to pluralize(project.repository.tag_names.count, 'tag'), namespace_project_tags_path(project.namespace, project)
- else
%i.fa.fa-exclamation-triangle
Empty repository
%ul.projects-list.bordered-list.my-projects.public-projects
- projects.each do |project|
%li.project-row
= render partial: 'shared/project', locals: { project: project, avatar: true, stars: true }
- unless projects.present?
.nothing-here-block No such projects
...@@ -4,10 +4,5 @@ ...@@ -4,10 +4,5 @@
.clearfix .clearfix
= render 'filter' = render 'filter'
%br %br
.public-projects = render 'projects', projects: @projects
%ul.bordered-list.top-list = paginate @projects, theme: "gitlab"
= render @projects
- unless @projects.present?
.nothing-here-block No public projects
= paginate @projects, theme: "gitlab"
...@@ -7,8 +7,5 @@ ...@@ -7,8 +7,5 @@
See most starred projects See most starred projects
.pull-right .pull-right
= render 'explore/projects/dropdown' = render 'explore/projects/dropdown'
.public-projects = render 'projects', projects: @starred_projects
%ul.bordered-list
= render @starred_projects
= paginate @starred_projects, theme: 'gitlab' = paginate @starred_projects, theme: 'gitlab'
...@@ -13,6 +13,4 @@ ...@@ -13,6 +13,4 @@
See most discussed projects for last month See most discussed projects for last month
.pull-right .pull-right
= render 'explore/projects/dropdown' = render 'explore/projects/dropdown'
.public-projects = render 'projects', projects: @trending_projects
%ul.bordered-list
= render @trending_projects
.panel.panel-default .panel.panel-default.projects-list-holder
.panel-heading.clearfix .panel-heading.clearfix
.input-group .input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
= render 'shared/show_aside' = render 'shared/show_aside'
.row .row
%section.activities.col-md-8 %section.activities.col-md-7
.hidden-xs .hidden-xs
- if current_user - if current_user
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
...@@ -33,5 +33,5 @@ ...@@ -33,5 +33,5 @@
.content_list .content_list
= spinner = spinner
%aside.side.col-md-4 %aside.side.col-md-5
= render "projects", projects: @projects = render "projects", projects: @projects
.page-with-sidebar{ class: nav_sidebar_class } .page-with-sidebar{ class: nav_sidebar_class }
= render "layouts/broadcast" = render "layouts/broadcast"
.sidebar-wrapper.nicescroll .sidebar-wrapper.nicescroll
.header-logo
= link_to root_path, class: 'home', title: 'Dashboard', id: 'js-shortcuts-home', data: {toggle: 'tooltip', placement: 'bottom'} do
= brand_header_logo
.gitlab-text-container
%h3 GitLab
- if defined?(sidebar) && sidebar - if defined?(sidebar) && sidebar
= render "layouts/nav/#{sidebar}" = render "layouts/nav/#{sidebar}"
- elsif current_user - elsif current_user
...@@ -13,7 +18,7 @@ ...@@ -13,7 +18,7 @@
.username .username
= current_user.username = current_user.username
.content-wrapper .content-wrapper
.container-fluid %div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" }
.content .content
= render "layouts/flash" = render "layouts/flash"
.clearfix .clearfix
......
%header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class } %header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class }
.container %div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" }
.header-logo
= link_to root_path, class: 'home', title: 'Dashboard', id: 'js-shortcuts-home', data: {toggle: 'tooltip', placement: 'bottom'} do
= brand_header_logo
.gitlab-text-container
%h3 GitLab
.header-content .header-content
%button.navbar-toggle{type: 'button'} %button.navbar-toggle{type: 'button'}
%span.sr-only Toggle navigation %span.sr-only Toggle navigation
...@@ -17,15 +12,6 @@ ...@@ -17,15 +12,6 @@
%li.visible-sm.visible-xs %li.visible-sm.visible-xs
= link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do
= icon('search') = icon('search')
-#%li.hidden-xs
= link_to help_path, title: 'Help', data: {toggle: 'tooltip', placement: 'bottom'} do
= icon('question-circle fw')
-#%li
= link_to explore_root_path, title: 'Explore', data: {toggle: 'tooltip', placement: 'bottom'} do
= icon('globe fw')
-#%li
= link_to user_snippets_path(current_user), title: 'Your snippets', data: {toggle: 'tooltip', placement: 'bottom'} do
= icon('clipboard fw')
- if current_user.is_admin? - if current_user.is_admin?
%li %li
= link_to admin_root_path, title: 'Admin area', data: {toggle: 'tooltip', placement: 'bottom'} do = link_to admin_root_path, title: 'Admin area', data: {toggle: 'tooltip', placement: 'bottom'} do
...@@ -34,9 +20,6 @@ ...@@ -34,9 +20,6 @@
%li.hidden-xs %li.hidden-xs
= link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom'} do = link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom'} do
= icon('plus fw') = icon('plus fw')
-#%li
= link_to profile_path, title: 'Profile settings', data: {toggle: 'tooltip', placement: 'bottom'} do
= icon('cog fw')
%li %li
= link_to destroy_user_session_path, class: 'logout', method: :delete, title: 'Sign out', data: {toggle: 'tooltip', placement: 'bottom'} do = link_to destroy_user_session_path, class: 'logout', method: :delete, title: 'Sign out', data: {toggle: 'tooltip', placement: 'bottom'} do
= icon('sign-out') = icon('sign-out')
......
%header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class } %header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class }
.container %div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" }
.header-logo
= link_to explore_root_path, class: "home" do
= brand_header_logo
.gitlab-text-container
%h3 GitLab
.header-content .header-content
- unless current_controller?('sessions') - unless current_controller?('sessions')
.pull-right .pull-right
......
%ul.nav.nav-sidebar %ul.nav.nav-sidebar
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do = nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
= link_to (current_user ? root_path : explore_root_path), title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do = link_to (current_user ? root_path : explore_root_path), title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do
= icon('dashboard fw') = icon('home fw')
%span %span
Projects Projects
= nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path, title: 'Activity', data: {placement: 'right'} do
= icon('dashboard fw')
%span
Activity
= nav_link(controller: :groups) do = nav_link(controller: :groups) do
= link_to (current_user ? dashboard_groups_path : explore_groups_path), title: 'Groups', data: {placement: 'right'} do = link_to (current_user ? dashboard_groups_path : explore_groups_path), title: 'Groups', data: {placement: 'right'} do
= icon('group fw') = icon('group fw')
...@@ -29,7 +34,7 @@ ...@@ -29,7 +34,7 @@
%span.count= current_user.assigned_merge_requests.opened.count %span.count= current_user.assigned_merge_requests.opened.count
= nav_link(controller: :snippets) do = nav_link(controller: :snippets) do
= link_to (current_user ? user_snippets_path(current_user) : snippets_path), title: 'Your snippets', data: {placement: 'right'} do = link_to (current_user ? user_snippets_path(current_user) : snippets_path), title: 'Your snippets', data: {placement: 'right'} do
= icon('dashboard fw') = icon('clipboard fw')
%span %span
Snippets Snippets
- if current_user - if current_user
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.project-home-panel.clearfix{:class => ("empty-project" if empty_repo)} .project-home-panel.clearfix{:class => ("empty-project" if empty_repo)}
.project-identicon-holder .project-identicon-holder
= project_icon(@project, alt: '', class: 'project-avatar avatar s90') = project_icon(@project, alt: '', class: 'project-avatar avatar s90')
.project-home-desc.lead .project-home-desc
%h1= @project.name %h1= @project.name
- if @project.description.present? - if @project.description.present?
= markdown(@project.description, pipeline: :description) = markdown(@project.description, pipeline: :description)
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
.light .light
= commit_author_link(commit, avatar: false) = commit_author_link(commit, avatar: false)
authored authored
#{time_ago_with_tooltip(commit.committed_date)} #{time_ago_with_tooltip(commit.committed_date, skip_js: true)}
%td.lines.blame-numbers %td.lines.blame-numbers
%pre %pre
- line_count = blame_group[:lines].count - line_count = blame_group[:lines].count
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
%span.dropdown %span.dropdown
%a.dropdown-toggle.btn.btn-new{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn.btn-new{href: '#', "data-toggle" => "dropdown"}
= icon('plus') = icon('plus')
%ul.dropdown-menu %ul.dropdown-menu.dropdown-menu-right.project-home-dropdown
- if can?(current_user, :create_issue, @project) - if can?(current_user, :create_issue, @project)
%li %li
= link_to url_for_new_issue do = link_to url_for_new_issue do
......
- page_title "Deploy Keys" - page_title "Deploy Keys"
%h3.page-title %h3.page-title
Deploy keys allow read-only access to the repository Deploy keys allow read-only access to the repository
......
- if params[:view] == 'parallel'
- fluid_layout true
.prepend-top-20.append-bottom-20 .prepend-top-20.append-bottom-20
.pull-right .pull-right
.btn-group .btn-group
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Too many changes to show. Too many changes to show.
.pull-right .pull-right
- unless diff_hard_limit_enabled? - unless diff_hard_limit_enabled?
= link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: :html)), class: "btn btn-sm btn-warning" = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: nil)), class: "btn btn-sm btn-warning"
- if current_controller?(:commit) or current_controller?(:merge_requests) - if current_controller?(:commit) or current_controller?(:merge_requests)
- if current_controller?(:commit) - if current_controller?(:commit)
......
...@@ -50,39 +50,42 @@ ...@@ -50,39 +50,42 @@
datasets : [{ datasets : [{
fillColor : "rgba(220,220,220,0.5)", fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)", strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)", barStrokeWidth: 1,
pointStrokeColor : "#EEE", barValueSpacing: 1,
barDatasetSpacing: 1,
data : #{@commits_per_time.values.to_json} data : #{@commits_per_time.values.to_json}
}] }]
} }
ctx = $("#hour-chart").get(0).getContext("2d"); ctx = $("#hour-chart").get(0).getContext("2d");
new Chart(ctx).Line(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2}) new Chart(ctx).Bar(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2})
data = { data = {
labels : #{@commits_per_week_days.keys.to_json}, labels : #{@commits_per_week_days.keys.to_json},
datasets : [{ datasets : [{
fillColor : "rgba(220,220,220,0.5)", fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)", strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)", barStrokeWidth: 1,
pointStrokeColor : "#EEE", barValueSpacing: 1,
barDatasetSpacing: 1,
data : #{@commits_per_week_days.values.to_json} data : #{@commits_per_week_days.values.to_json}
}] }]
} }
ctx = $("#weekday-chart").get(0).getContext("2d"); ctx = $("#weekday-chart").get(0).getContext("2d");
new Chart(ctx).Line(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2}) new Chart(ctx).Bar(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2})
data = { data = {
labels : #{@commits_per_month.keys.to_json}, labels : #{@commits_per_month.keys.to_json},
datasets : [{ datasets : [{
fillColor : "rgba(220,220,220,0.5)", fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)", strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)", barStrokeWidth: 1,
pointStrokeColor : "#EEE", barValueSpacing: 1,
barDatasetSpacing: 1,
data : #{@commits_per_month.values.to_json} data : #{@commits_per_month.values.to_json}
}] }]
} }
ctx = $("#month-chart").get(0).getContext("2d"); ctx = $("#month-chart").get(0).getContext("2d");
new Chart(ctx).Line(data, {"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2}) new Chart(ctx).Bar(data, {"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2})
...@@ -55,6 +55,13 @@ ...@@ -55,6 +55,13 @@
%strong Merge Request events %strong Merge Request events
%p.light %p.light
This url will be triggered when a merge request is created This url will be triggered when a merge request is created
.form-group
= f.label :enable_ssl_verification, "SSL verification", class: 'control-label checkbox'
.col-sm-10
.checkbox
= f.label :enable_ssl_verification do
= f.check_box :enable_ssl_verification
%strong Enable SSL verification
.form-actions .form-actions
= f.submit "Add Web Hook", class: "btn btn-create" = f.submit "Add Web Hook", class: "btn btn-create"
...@@ -74,3 +81,4 @@ ...@@ -74,3 +81,4 @@
- %w(push_events tag_push_events issues_events note_events merge_requests_events).each do |trigger| - %w(push_events tag_push_events issues_events note_events merge_requests_events).each do |trigger|
- if hook.send(trigger) - if hook.send(trigger)
%span.label.label-gray= trigger.titleize %span.label.label-gray= trigger.titleize
SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"}
- page_title "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests" - page_title "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests"
- if params[:view] == 'parallel'
- fluid_layout true
.merge-request{'data-url' => merge_request_path(@merge_request)} .merge-request{'data-url' => merge_request_path(@merge_request)}
.merge-request-details.issuable-details .merge-request-details.issuable-details
= render "projects/merge_requests/show/mr_title" = render "projects/merge_requests/show/mr_title"
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
- if avatar - if avatar
.dash-project-avatar .dash-project-avatar
= project_icon(project, alt: '', class: 'avatar project-avatar s40') = project_icon(project, alt: '', class: 'avatar project-avatar s40')
%span.str-truncated %span.str-truncated.project-full-name
%span.namespace-name %span.namespace-name
- if project.namespace - if project.namespace
= project.namespace.human_name = project.namespace.human_name
...@@ -14,3 +14,7 @@ ...@@ -14,3 +14,7 @@
%span.pull-right.light %span.pull-right.light
%i.fa.fa-star %i.fa.fa-star
= project.star_count = project.star_count
- if project.description.present?
.project-description
.str-truncated
= markdown(project.description, pipeline: :description)
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
= render 'shared/show_aside' = render 'shared/show_aside'
.row .row
%section.col-md-8 %section.col-md-7
.header-with-avatar .header-with-avatar
= link_to avatar_icon(@user.email, 400), target: '_blank' do = link_to avatar_icon(@user.email, 400), target: '_blank' do
= image_tag avatar_icon(@user.email, 90), class: "avatar avatar-tile s90", alt: '' = image_tag avatar_icon(@user.email, 90), class: "avatar avatar-tile s90", alt: ''
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
.content_list .content_list
= spinner = spinner
%aside.col-md-4 %aside.col-md-5
= render 'profile', user: @user = render 'profile', user: @user
= render 'projects', projects: @projects, contributed_projects: @contributed_projects = render 'projects', projects: @projects, contributed_projects: @contributed_projects
......
...@@ -18,6 +18,8 @@ class EmailReceiverWorker ...@@ -18,6 +18,8 @@ class EmailReceiverWorker
def handle_failure(raw, e) def handle_failure(raw, e)
Rails.logger.warn("Email can not be processed: #{e}\n\n#{raw}") Rails.logger.warn("Email can not be processed: #{e}\n\n#{raw}")
return unless raw.present?
can_retry = false can_retry = false
reason = nil reason = nil
......
...@@ -4,7 +4,7 @@ class EmailsOnPushWorker ...@@ -4,7 +4,7 @@ class EmailsOnPushWorker
def perform(project_id, recipients, push_data, options = {}) def perform(project_id, recipients, push_data, options = {})
options.symbolize_keys! options.symbolize_keys!
options.reverse_merge!( options.reverse_merge!(
send_from_committer_email: false, send_from_committer_email: false,
disable_diffs: false disable_diffs: false
) )
send_from_committer_email = options[:send_from_committer_email] send_from_committer_email = options[:send_from_committer_email]
...@@ -16,9 +16,9 @@ class EmailsOnPushWorker ...@@ -16,9 +16,9 @@ class EmailsOnPushWorker
ref = push_data["ref"] ref = push_data["ref"]
author_id = push_data["user_id"] author_id = push_data["user_id"]
action = action =
if Gitlab::Git.blank_ref?(before_sha) if Gitlab::Git.blank_ref?(before_sha)
:create :create
elsif Gitlab::Git.blank_ref?(after_sha) elsif Gitlab::Git.blank_ref?(after_sha)
:delete :delete
else else
...@@ -42,17 +42,22 @@ class EmailsOnPushWorker ...@@ -42,17 +42,22 @@ class EmailsOnPushWorker
end end
recipients.split(" ").each do |recipient| recipients.split(" ").each do |recipient|
Notify.repository_push_email( begin
project_id, Notify.repository_push_email(
recipient, project_id,
author_id: author_id, recipient,
ref: ref, author_id: author_id,
action: action, ref: ref,
compare: compare, action: action,
reverse_compare: reverse_compare, compare: compare,
send_from_committer_email: send_from_committer_email, reverse_compare: reverse_compare,
disable_diffs: disable_diffs send_from_committer_email: send_from_committer_email,
).deliver disable_diffs: disable_diffs
).deliver
# These are input errors and won't be corrected even if Sidekiq retries
rescue Net::SMTPFatalError, Net::SMTPSyntaxError => e
logger.info("Failed to send e-mail for project '#{project.name_with_namespace}' to #{recipient}: #{e}")
end
end end
ensure ensure
compare = nil compare = nil
......
...@@ -8,7 +8,7 @@ class Settings < Settingslogic ...@@ -8,7 +8,7 @@ class Settings < Settingslogic
def gitlab_on_standard_port? def gitlab_on_standard_port?
gitlab.port.to_i == (gitlab.https ? 443 : 80) gitlab.port.to_i == (gitlab.https ? 443 : 80)
end end
# get host without www, thanks to http://stackoverflow.com/a/6674363/1233435 # get host without www, thanks to http://stackoverflow.com/a/6674363/1233435
def get_host_without_www(url) def get_host_without_www(url)
url = URI.encode(url) url = URI.encode(url)
...@@ -32,14 +32,12 @@ class Settings < Settingslogic ...@@ -32,14 +32,12 @@ class Settings < Settingslogic
end end
end end
def build_base_gitlab_url
base_gitlab_url.join('')
end
def build_gitlab_url def build_gitlab_url
custom_port = gitlab_on_standard_port? ? nil : ":#{gitlab.port}" (base_gitlab_url + [gitlab.relative_url_root]).join('')
[ gitlab.protocol,
"://",
gitlab.host,
custom_port,
gitlab.relative_url_root
].join('')
end end
# check that values in `current` (string or integer) is a contant in `modul`. # check that values in `current` (string or integer) is a contant in `modul`.
...@@ -64,6 +62,17 @@ class Settings < Settingslogic ...@@ -64,6 +62,17 @@ class Settings < Settingslogic
end end
value value
end end
private
def base_gitlab_url
custom_port = gitlab_on_standard_port? ? nil : ":#{gitlab.port}"
[ gitlab.protocol,
"://",
gitlab.host,
custom_port
]
end
end end
end end
...@@ -123,6 +132,7 @@ Settings.gitlab['email_enabled'] ||= true if Settings.gitlab['email_enabled'].ni ...@@ -123,6 +132,7 @@ Settings.gitlab['email_enabled'] ||= true if Settings.gitlab['email_enabled'].ni
Settings.gitlab['email_from'] ||= "gitlab@#{Settings.gitlab.host}" Settings.gitlab['email_from'] ||= "gitlab@#{Settings.gitlab.host}"
Settings.gitlab['email_display_name'] ||= "GitLab" Settings.gitlab['email_display_name'] ||= "GitLab"
Settings.gitlab['email_reply_to'] ||= "noreply@#{Settings.gitlab.host}" Settings.gitlab['email_reply_to'] ||= "noreply@#{Settings.gitlab.host}"
Settings.gitlab['base_url'] ||= Settings.send(:build_base_gitlab_url)
Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url) Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url)
Settings.gitlab['user'] ||= 'git' Settings.gitlab['user'] ||= 'git'
Settings.gitlab['user_home'] ||= begin Settings.gitlab['user_home'] ||= begin
......
if Gitlab::LDAP::Config.enabled?
module OmniAuth::Strategies
server = Gitlab.config.ldap.servers.values.first
klass = server['provider_class']
const_set(klass, Class.new(LDAP)) unless klass == 'LDAP'
end
OmniauthCallbacksController.class_eval do
server = Gitlab.config.ldap.servers.values.first
alias_method server['provider_name'], :ldap
end
end
OmniAuth.config.full_host = Settings.gitlab['base_url']
OmniAuth.config.allowed_request_methods = [:post]
#In case of auto sign-in, the GET method is used (users don't get to click on a button)
OmniAuth.config.allowed_request_methods << :get if Gitlab.config.omniauth.auto_sign_in_with_provider.present?
OmniAuth.config.before_request_phase do |env|
OmniAuth::RequestForgeryProtection.new(env).call
end
if Gitlab.config.omniauth.enabled
Gitlab.config.omniauth.providers.each do |provider|
if provider['name'] == 'kerberos'
require 'omniauth-kerberos'
end
end
end
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
# :name: "inbox" # :name: "inbox"
# # Always "sidekiq". # # Always "sidekiq".
# :delivery_method: sidekiq # :delivery_method: sidekiq
# # Always true.
# :delete_after_delivery: true
# :delivery_options: # :delivery_options:
# # The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml. # # The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
# :redis_url: redis://localhost:6379 # :redis_url: redis://localhost:6379
......
...@@ -360,6 +360,7 @@ Gitlab::Application.routes.draw do ...@@ -360,6 +360,7 @@ Gitlab::Application.routes.draw do
member do member do
get :issues get :issues
get :merge_requests get :merge_requests
get :activity
end end
scope module: :dashboard do scope module: :dashboard do
......
class AddEnableSslVerification < ActiveRecord::Migration
def change
add_column :web_hooks, :enable_ssl_verification, :boolean, default: false
end
end
...@@ -821,14 +821,14 @@ ActiveRecord::Schema.define(version: 20150826001931) do ...@@ -821,14 +821,14 @@ ActiveRecord::Schema.define(version: 20150826001931) do
t.integer "project_id" t.integer "project_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "type", default: "ProjectHook" t.string "type", default: "ProjectHook"
t.integer "service_id" t.integer "service_id"
t.boolean "push_events", default: true, null: false t.boolean "push_events", default: true, null: false
t.boolean "issues_events", default: false, null: false t.boolean "issues_events", default: false, null: false
t.boolean "merge_requests_events", default: false, null: false t.boolean "merge_requests_events", default: false, null: false
t.boolean "tag_push_events", default: false t.boolean "tag_push_events", default: false
t.integer "group_id" t.boolean "note_events", default: false, null: false
t.boolean "note_events", default: false, null: false t.boolean "enable_ssl_verification", default: false
end end
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
......
...@@ -59,6 +59,8 @@ In this example, we'll use the Gmail address `gitlab-replies@gmail.com`. If you' ...@@ -59,6 +59,8 @@ In this example, we'll use the Gmail address `gitlab-replies@gmail.com`. If you'
:name: "inbox" :name: "inbox"
# Always "sidekiq". # Always "sidekiq".
:delivery_method: sidekiq :delivery_method: sidekiq
# Always true.
:delete_after_delivery: true
:delivery_options: :delivery_options:
# The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml. # The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
:redis_url: redis://localhost:6379 :redis_url: redis://localhost:6379
...@@ -144,6 +146,8 @@ TODO ...@@ -144,6 +146,8 @@ TODO
:name: "inbox" :name: "inbox"
# Always "sidekiq". # Always "sidekiq".
:delivery_method: sidekiq :delivery_method: sidekiq
# Always true.
:delete_after_delivery: true
:delivery_options: :delivery_options:
# The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml. # The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
:redis_url: redis://localhost:6379 :redis_url: redis://localhost:6379
......
...@@ -8,5 +8,5 @@ ...@@ -8,5 +8,5 @@
### Note ### Note
* If you'd like to migrate from a self-hosted GitLab instance to GitLab.com, you can copy your repos by changing the remote and pushing to the new server; but issues and merge requests can't be imported. * If you'd like to migrate from a self-hosted GitLab instance to GitLab.com, you can copy your repos by changing the remote and pushing to the new server; but issues and merge requests can't be imported.
* Repositories are imported to GitLab via HTTP. * You can import any Git repository via HTTP from the New Project page.
If the repository is too large, it can timeout. We have a soft limit of 10GB. If the repository is too large, it can timeout.
@admin
Feature: Admin Hooks
Background:
Given I sign in as an admin
Scenario: On Admin Hooks
Given I visit admin hooks page
Then I submit the form with enabled SSL verification
And I see new hook with enabled SSL verification
\ No newline at end of file
...@@ -10,6 +10,10 @@ Feature: Dashboard ...@@ -10,6 +10,10 @@ Feature: Dashboard
Scenario: I should see projects list Scenario: I should see projects list
Then I should see "New Project" link Then I should see "New Project" link
Then I should see "Shop" project link Then I should see "Shop" project link
@javascript
Scenario: I should see activity list
And I visit dashboard activity page
Then I should see project "Shop" activity feed Then I should see project "Shop" activity feed
Scenario: I should see groups list Scenario: I should see groups list
...@@ -26,12 +30,12 @@ Feature: Dashboard ...@@ -26,12 +30,12 @@ Feature: Dashboard
@javascript @javascript
Scenario: I should see User joined Project event Scenario: I should see User joined Project event
Given user with name "John Doe" joined project "Shop" Given user with name "John Doe" joined project "Shop"
When I visit dashboard page When I visit dashboard activity page
Then I should see "John Doe joined project Shop" event Then I should see "John Doe joined project Shop" event
@javascript @javascript
Scenario: I should see User left Project event Scenario: I should see User left Project event
Given user with name "John Doe" joined project "Shop" Given user with name "John Doe" joined project "Shop"
And user with name "John Doe" left project "Shop" And user with name "John Doe" left project "Shop"
When I visit dashboard page When I visit dashboard activity page
Then I should see "John Doe left project Shop" event Then I should see "John Doe left project Shop" event
...@@ -6,7 +6,7 @@ Feature: Event Filters ...@@ -6,7 +6,7 @@ Feature: Event Filters
And this project has push event And this project has push event
And this project has new member event And this project has new member event
And this project has merge request event And this project has merge request event
And I visit dashboard page And I visit dashboard activity page
@javascript @javascript
Scenario: I should see all events Scenario: I should see all events
...@@ -16,7 +16,7 @@ Feature: Event Filters ...@@ -16,7 +16,7 @@ Feature: Event Filters
@javascript @javascript
Scenario: I should see only pushed events Scenario: I should see only pushed events
When I click "push" event filter When I click "push" event filter
Then I should see push event Then I should see push event
And I should not see new member event And I should not see new member event
And I should not see merge request event And I should not see merge request event
...@@ -38,11 +38,11 @@ Feature: Event Filters ...@@ -38,11 +38,11 @@ Feature: Event Filters
@javascript @javascript
Scenario: I should see only selected events while page reloaded Scenario: I should see only selected events while page reloaded
When I click "push" event filter When I click "push" event filter
And I visit dashboard page And I visit dashboard activity page
Then I should see push event Then I should see push event
And I should not see new member event And I should not see new member event
When I click "team" event filter When I click "team" event filter
And I visit dashboard page And I visit dashboard activity page
Then I should see push event Then I should see push event
And I should see new member event And I should see new member event
And I should not see merge request event And I should not see merge request event
......
...@@ -41,6 +41,7 @@ Feature: Project Commits ...@@ -41,6 +41,7 @@ Feature: Project Commits
Scenario: I browse big commit Scenario: I browse big commit
Given I visit big commit page Given I visit big commit page
Then I see big commit warning Then I see big commit warning
And I see "Reload with full diff" link
Scenario: I browse a commit with an image Scenario: I browse a commit with an image
Given I visit a commit with an image that changed Given I visit a commit with an image that changed
......
...@@ -13,6 +13,11 @@ Feature: Project Hooks ...@@ -13,6 +13,11 @@ Feature: Project Hooks
When I submit new hook When I submit new hook
Then I should see newly created hook Then I should see newly created hook
Scenario: I add new hook with SSL verification enabled
Given I visit project hooks page
When I submit new hook with SSL verification enabled
Then I should see newly created hook with SSL verification enabled
Scenario: I test hook Scenario: I test hook
Given project has hook Given project has hook
And I visit project hooks page And I visit project hooks page
......
class Spinach::Features::AdminHooks < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedAdmin
step "I submit the form with enabled SSL verification" do
fill_in 'hook_url', with: 'http://google.com'
check "Enable SSL verification"
click_on "Add System Hook"
end
step "I see new hook with enabled SSL verification" do
expect(page).to have_content "SSL Verification: enabled"
end
end
...@@ -79,6 +79,12 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps ...@@ -79,6 +79,12 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps
expect(page).to have_content "Too many changes" expect(page).to have_content "Too many changes"
end end
step 'I see "Reload with full diff" link' do
link = find_link('Reload with full diff')
expect(link[:href]).to end_with('?force_show_diff=true')
expect(link[:href]).not_to include('.html')
end
step 'I visit a commit with an image that changed' do step 'I visit a commit with an image that changed' do
visit namespace_project_commit_path(@project.namespace, @project, sample_image_commit.id) visit namespace_project_commit_path(@project.namespace, @project, sample_image_commit.id)
end end
......
...@@ -28,11 +28,24 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps ...@@ -28,11 +28,24 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps
expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1) expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1)
end end
step 'I submit new hook with SSL verification enabled' do
@url = FFaker::Internet.uri("http")
fill_in "hook_url", with: @url
check "hook_enable_ssl_verification"
expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1)
end
step 'I should see newly created hook' do step 'I should see newly created hook' do
expect(current_path).to eq namespace_project_hooks_path(current_project.namespace, current_project) expect(current_path).to eq namespace_project_hooks_path(current_project.namespace, current_project)
expect(page).to have_content(@url) expect(page).to have_content(@url)
end end
step 'I should see newly created hook with SSL verification enabled' do
expect(current_path).to eq namespace_project_hooks_path(current_project.namespace, current_project)
expect(page).to have_content(@url)
expect(page).to have_content("SSL Verification: enabled")
end
step 'I click test hook button' do step 'I click test hook button' do
stub_request(:post, @hook.url).to_return(status: 200) stub_request(:post, @hook.url).to_return(status: 200)
click_link 'Test Hook' click_link 'Test Hook'
......
...@@ -71,6 +71,10 @@ module SharedPaths ...@@ -71,6 +71,10 @@ module SharedPaths
visit dashboard_path visit dashboard_path
end end
step 'I visit dashboard activity page' do
visit activity_dashboard_path
end
step 'I visit dashboard projects page' do step 'I visit dashboard projects page' do
visit projects_dashboard_path visit projects_dashboard_path
end end
......
...@@ -288,7 +288,7 @@ print_status() { ...@@ -288,7 +288,7 @@ print_status() {
fi fi
if [ "$mail_room_enabled" = true ]; then if [ "$mail_room_enabled" = true ]; then
if [ "$mail_room_status" = "0" ]; then if [ "$mail_room_status" = "0" ]; then
echo "The GitLab MailRoom email processor with pid $spid is running." echo "The GitLab MailRoom email processor with pid $mpid is running."
else else
printf "The GitLab MailRoom email processor is \033[31mnot running\033[0m.\n" printf "The GitLab MailRoom email processor is \033[31mnot running\033[0m.\n"
fi fi
......
...@@ -121,7 +121,6 @@ module Gitlab::Markdown ...@@ -121,7 +121,6 @@ module Gitlab::Markdown
end end
it 'links with adjacent text' do it 'links with adjacent text' do
skip "TODO (rspeicher): Re-enable when usernames can't end in periods."
doc = filter("Mention me (#{reference}.)") doc = filter("Mention me (#{reference}.)")
expect(doc.to_html).to match(/\(<a.+>#{reference}<\/a>\.\)/) expect(doc.to_html).to match(/\(<a.+>#{reference}<\/a>\.\)/)
end end
......
require 'spec_helper'
describe EmailsOnPushWorker do
include RepoHelpers
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:data) { Gitlab::PushDataBuilder.build_sample(project, user) }
subject { EmailsOnPushWorker.new }
before do
allow(Project).to receive(:find).and_return(project)
end
describe "#perform" do
it "sends mail" do
subject.perform(project.id, user.email, data.stringify_keys)
email = ActionMailer::Base.deliveries.last
expect(email.subject).to include('Change some files')
expect(email.to).to eq([user.email])
end
it "gracefully handles an input SMTP error" do
ActionMailer::Base.deliveries.clear
allow(Notify).to receive(:repository_push_email).and_raise(Net::SMTPFatalError)
subject.perform(project.id, user.email, data.stringify_keys)
expect(ActionMailer::Base.deliveries.count).to eq(0)
end
end
end
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