Коммит fdc54452 создал по автору Rémy Coutable's avatar Rémy Coutable
Просмотр файлов

Merge remote-tracking branch 'ce/8-5-stable' into 8-5-stable-ee

владельцы ed504c97 64f1bab6
...@@ -63,6 +63,13 @@ v 8.5.0 (unreleased) ...@@ -63,6 +63,13 @@ v 8.5.0 (unreleased)
- Replaces "Create merge request" link with one to the "Merge Request" when one exists - Replaces "Create merge request" link with one to the "Merge Request" when one exists
- Fix CI builds badge, add a new link to builds badge, deprecate the old one - Fix CI builds badge, add a new link to builds badge, deprecate the old one
- Fix broken link to project in build notification emails - Fix broken link to project in build notification emails
- Ability to see and sort on vote count from Issues and MR lists
- Fix builds scheduler when first build in stage was allowed to fail
- User project limit is reached notice is hidden if the projects limit is zero
- Add API support for managing runners and project's runners
- Allow SAML users to login with no previous account without having to allow
all Omniauth providers to do so.
- Allow existing users to auto link their SAML credentials by logging in via SAML
v 8.4.4 v 8.4.4
- Update omniauth-saml gem to 1.4.2 - Update omniauth-saml gem to 1.4.2
......
...@@ -214,7 +214,7 @@ gem 'jquery-turbolinks', '~> 2.1.0' ...@@ -214,7 +214,7 @@ gem 'jquery-turbolinks', '~> 2.1.0'
gem 'addressable', '~> 2.3.8' gem 'addressable', '~> 2.3.8'
gem 'bootstrap-sass', '~> 3.3.0' gem 'bootstrap-sass', '~> 3.3.0'
gem 'font-awesome-rails', '~> 4.2' gem 'font-awesome-rails', '~> 4.2'
gem 'gitlab_emoji', '~> 0.2.0' gem 'gitlab_emoji', '~> 0.3.0'
gem 'gon', '~> 6.0.1' gem 'gon', '~> 6.0.1'
gem 'jquery-atwho-rails', '~> 1.3.2' gem 'jquery-atwho-rails', '~> 1.3.2'
gem 'jquery-rails', '~> 4.0.0' gem 'jquery-rails', '~> 4.0.0'
......
...@@ -349,7 +349,7 @@ GEM ...@@ -349,7 +349,7 @@ GEM
ruby-progressbar (~> 1.4) ruby-progressbar (~> 1.4)
gemnasium-gitlab-service (0.2.6) gemnasium-gitlab-service (0.2.6)
rugged (~> 0.21) rugged (~> 0.21)
gemojione (2.1.1) gemojione (2.2.1)
json json
get_process_mem (0.2.0) get_process_mem (0.2.0)
gherkin-ruby (0.3.2) gherkin-ruby (0.3.2)
...@@ -377,8 +377,8 @@ GEM ...@@ -377,8 +377,8 @@ GEM
mime-types (~> 1.15) mime-types (~> 1.15)
posix-spawn (~> 0.3) posix-spawn (~> 0.3)
gitlab-license (0.0.4) gitlab-license (0.0.4)
gitlab_emoji (0.2.0) gitlab_emoji (0.3.1)
gemojione (~> 2.1) gemojione (~> 2.2, >= 2.2.1)
gitlab_git (8.1.0) gitlab_git (8.1.0)
activesupport (~> 4.0) activesupport (~> 4.0)
charlock_holmes (~> 0.7.3) charlock_holmes (~> 0.7.3)
...@@ -962,7 +962,7 @@ DEPENDENCIES ...@@ -962,7 +962,7 @@ DEPENDENCIES
gitlab-elasticsearch-git (~> 0.0.10) gitlab-elasticsearch-git (~> 0.0.10)
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-license (~> 0.0.4) gitlab-license (~> 0.0.4)
gitlab_emoji (~> 0.2.0) gitlab_emoji (~> 0.3.0)
gitlab_git (~> 8.1) gitlab_git (~> 8.1)
gitlab_meta (= 7.0) gitlab_meta (= 7.0)
gitlab_omniauth-ldap (~> 1.2.1) gitlab_omniauth-ldap (~> 1.2.1)
......
8.5.0-rc2-ee 8.5.0-rc2-ee
\ No newline at end of file
...@@ -15,3 +15,5 @@ class @IssuableContext ...@@ -15,3 +15,5 @@ class @IssuableContext
block.find('.selectbox').show() block.find('.selectbox').show()
block.find('.value').hide() block.find('.value').hide()
block.find('.js-select2').select2("open") block.find('.js-select2').select2("open")
$(".right-sidebar").niceScroll()
...@@ -117,20 +117,4 @@ body { ...@@ -117,20 +117,4 @@ body {
&.ui_violet { &.ui_violet {
@include gitlab-theme(#9988CC, $theme-violet, #443366, #332255); @include gitlab-theme(#9988CC, $theme-violet, #443366, #332255);
} }
}
::-webkit-scrollbar{
width: 3px;
}
::-webkit-scrollbar-thumb{
background-color:$theme-charcoal; border-radius: 0;
}
::-webkit-scrollbar-thumb:hover{
background-color:$theme-charcoal;
}
::-webkit-scrollbar-track{
background-color:#FFF;
} }
\ No newline at end of file
Это отличие свёрнуто
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
display: inline-block; display: inline-block;
} }
.issue-no-comments { .issue-no-comments, .issue-no-votes {
opacity: 0.5; opacity: 0.5;
} }
} }
......
...@@ -163,7 +163,7 @@ ...@@ -163,7 +163,7 @@
display: inline-block; display: inline-block;
} }
.merge-request-no-comments { .merge-request-no-comments, .merge-request-no-votes {
opacity: 0.5; opacity: 0.5;
} }
} }
...@@ -236,4 +236,4 @@ ...@@ -236,4 +236,4 @@
} }
} }
} }
} }
\ No newline at end of file
...@@ -73,24 +73,19 @@ ...@@ -73,24 +73,19 @@
font-weight: normal; font-weight: normal;
} }
.visibility-icon {
display: inline-block;
margin-left: 5px;
font-size: 18px;
color: $gray;
}
p { p {
padding: 0 $gl-padding; padding: 0 $gl-padding;
color: #5c5d5e; color: #5c5d5e;
} }
} }
.visibility-level-label {
@extend .btn;
@extend .btn-gray;
color: $gray;
cursor: default;
i {
color: inherit;
}
}
.project-repo-buttons { .project-repo-buttons {
margin-top: 20px; margin-top: 20px;
margin-bottom: 0px; margin-bottom: 0px;
......
...@@ -42,6 +42,26 @@ def ldap ...@@ -42,6 +42,26 @@ def ldap
end end
end end
def saml
if current_user
log_audit_event(current_user, with: :saml)
# Update SAML identity if data has changed.
identity = current_user.identities.find_by(extern_uid: oauth['uid'], provider: :saml)
if identity.nil?
current_user.identities.create(extern_uid: oauth['uid'], provider: :saml)
redirect_to profile_account_path, notice: 'Authentication method updated'
else
redirect_to after_sign_in_path_for(current_user)
end
else
saml_user = Gitlab::Saml::User.new(oauth)
saml_user.save
@user = saml_user.gl_user
continue_login_process
end
end
def omniauth_error def omniauth_error
@provider = params[:provider] @provider = params[:provider]
@error = params[:error] @error = params[:error]
...@@ -65,25 +85,11 @@ def handle_omniauth ...@@ -65,25 +85,11 @@ def handle_omniauth
log_audit_event(current_user, with: oauth['provider']) log_audit_event(current_user, with: oauth['provider'])
redirect_to profile_account_path, notice: 'Authentication method updated' redirect_to profile_account_path, notice: 'Authentication method updated'
else else
@user = Gitlab::OAuth::User.new(oauth) oauth_user = Gitlab::OAuth::User.new(oauth)
@user.save oauth_user.save
@user = oauth_user.gl_user
# Only allow properly saved users to login. continue_login_process
if @user.persisted? && @user.valid?
log_audit_event(@user.gl_user, with: oauth['provider'])
sign_in_and_redirect(@user.gl_user)
else
error_message =
if @user.gl_user.errors.any?
@user.gl_user.errors.map do |attribute, message|
"#{attribute} #{message}"
end.join(", ")
else
''
end
redirect_to omniauth_error_path(oauth['provider'], error: error_message) and return
end
end end
rescue Gitlab::OAuth::SignupDisabledError rescue Gitlab::OAuth::SignupDisabledError
label = Gitlab::OAuth::Provider.label_for(oauth['provider']) label = Gitlab::OAuth::Provider.label_for(oauth['provider'])
...@@ -104,6 +110,18 @@ def handle_service_ticket provider, ticket ...@@ -104,6 +110,18 @@ def handle_service_ticket provider, ticket
session[:service_tickets][provider] = ticket session[:service_tickets][provider] = ticket
end end
def continue_login_process
# Only allow properly saved users to login.
if @user.persisted? && @user.valid?
log_audit_event(@user, with: oauth['provider'])
sign_in_and_redirect(@user)
else
error_message = @user.errors.full_messages.to_sentence
redirect_to omniauth_error_path(oauth['provider'], error: error_message) and return
end
end
def oauth def oauth
@oauth ||= request.env['omniauth.auth'] @oauth ||= request.env['omniauth.auth']
end end
......
...@@ -32,7 +32,7 @@ def create ...@@ -32,7 +32,7 @@ def create
if continue_params if continue_params
redirect_to continue_params[:to], notice: continue_params[:notice] redirect_to continue_params[:to], notice: continue_params[:notice]
else else
redirect_to namespace_project_path(@forked_project.namespace, @forked_project), notice: "The project was successfully forked." redirect_to namespace_project_path(@forked_project.namespace, @forked_project), notice: "The project '#{@forked_project.name}' was successfully forked."
end end
end end
else else
......
...@@ -248,7 +248,7 @@ def autocomplete_emojis ...@@ -248,7 +248,7 @@ def autocomplete_emojis
Emoji.emojis.map do |name, emoji| Emoji.emojis.map do |name, emoji|
{ {
name: name, name: name,
path: view_context.image_url("emoji/#{emoji["unicode"]}.png") path: view_context.image_url("#{emoji["unicode"]}.png")
} }
end end
end end
......
...@@ -118,12 +118,6 @@ def grouped_options_refs ...@@ -118,12 +118,6 @@ def grouped_options_refs
grouped_options_for_select(options, @ref || @project.default_branch) grouped_options_for_select(options, @ref || @project.default_branch)
end end
def emoji_autocomplete_source
# should be an array of strings
# so to_s can be called, because it is sufficient and to_json is too slow
Emoji.names.to_s
end
# Define whenever show last push event # Define whenever show last push event
# with suggestion to create MR # with suggestion to create MR
def show_last_push_widget?(event) def show_last_push_widget?(event)
......
...@@ -11,6 +11,8 @@ def sort_options_hash ...@@ -11,6 +11,8 @@ def sort_options_hash
sort_value_largest_repo => sort_title_largest_repo, sort_value_largest_repo => sort_title_largest_repo,
sort_value_recently_signin => sort_title_recently_signin, sort_value_recently_signin => sort_title_recently_signin,
sort_value_oldest_signin => sort_title_oldest_signin, sort_value_oldest_signin => sort_title_oldest_signin,
sort_value_downvotes => sort_title_downvotes,
sort_value_upvotes => sort_title_upvotes
} }
end end
...@@ -54,6 +56,14 @@ def sort_title_oldest_signin ...@@ -54,6 +56,14 @@ def sort_title_oldest_signin
'Oldest sign in' 'Oldest sign in'
end end
def sort_title_downvotes
'Least popular'
end
def sort_title_upvotes
'Most popular'
end
def sort_value_oldest_updated def sort_value_oldest_updated
'updated_asc' 'updated_asc'
end end
...@@ -93,4 +103,12 @@ def sort_value_recently_signin ...@@ -93,4 +103,12 @@ def sort_value_recently_signin
def sort_value_oldest_signin def sort_value_oldest_signin
'oldest_sign_in' 'oldest_sign_in'
end end
def sort_value_downvotes
'downvotes_desc'
end
def sort_value_upvotes
'upvotes_desc'
end
end end
...@@ -22,6 +22,7 @@ class Runner < ActiveRecord::Base ...@@ -22,6 +22,7 @@ class Runner < ActiveRecord::Base
extend Ci::Model extend Ci::Model
LAST_CONTACT_TIME = 5.minutes.ago LAST_CONTACT_TIME = 5.minutes.ago
AVAILABLE_SCOPES = ['specific', 'shared', 'active', 'paused', 'online']
has_many :builds, class_name: 'Ci::Build' has_many :builds, class_name: 'Ci::Build'
has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject' has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject'
...@@ -38,6 +39,11 @@ class Runner < ActiveRecord::Base ...@@ -38,6 +39,11 @@ class Runner < ActiveRecord::Base
scope :online, ->() { where('contacted_at > ?', LAST_CONTACT_TIME) } scope :online, ->() { where('contacted_at > ?', LAST_CONTACT_TIME) }
scope :ordered, ->() { order(id: :desc) } scope :ordered, ->() { order(id: :desc) }
scope :owned_or_shared, ->(project_id) do
joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id')
.where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id)
end
acts_as_taggable acts_as_taggable
def self.search(query) def self.search(query)
......
...@@ -69,10 +69,35 @@ def sort(method) ...@@ -69,10 +69,35 @@ def sort(method)
case method.to_s case method.to_s
when 'milestone_due_asc' then order_milestone_due_asc when 'milestone_due_asc' then order_milestone_due_asc
when 'milestone_due_desc' then order_milestone_due_desc when 'milestone_due_desc' then order_milestone_due_desc
when 'downvotes_desc' then order_downvotes_desc
when 'upvotes_desc' then order_upvotes_desc
else else
order_by(method) order_by(method)
end end
end end
def order_downvotes_desc
order_votes_desc('thumbsdown')
end
def order_upvotes_desc
order_votes_desc('thumbsup')
end
def order_votes_desc(award_emoji_name)
issuable_table = self.arel_table
note_table = Note.arel_table
join_clause = issuable_table.join(note_table, Arel::Nodes::OuterJoin).on(
note_table[:noteable_id].eq(issuable_table[:id]).and(
note_table[:noteable_type].eq(self.name).and(
note_table[:is_award].eq(true).and(note_table[:note].eq(award_emoji_name))
)
)
).join_sources
joins(join_clause).group(issuable_table[:id]).reorder("COUNT(notes.id) DESC")
end
end end
def today? def today?
......
...@@ -140,7 +140,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -140,7 +140,7 @@ class MergeRequest < ActiveRecord::Base
scope :by_milestone, ->(milestone) { where(milestone_id: milestone) } scope :by_milestone, ->(milestone) { where(milestone_id: milestone) }
scope :in_projects, ->(project_ids) { where("source_project_id in (:project_ids) OR target_project_id in (:project_ids)", project_ids: project_ids) } scope :in_projects, ->(project_ids) { where("source_project_id in (:project_ids) OR target_project_id in (:project_ids)", project_ids: project_ids) }
scope :of_projects, ->(ids) { where(target_project_id: ids) } scope :of_projects, ->(ids) { where(target_project_id: ids) }
scope :opened, -> { with_state(:opened) } scope :opened, -> { with_states(:opened, :reopened) }
scope :merged, -> { with_state(:merged) } scope :merged, -> { with_state(:merged) }
scope :closed, -> { with_state(:closed) } scope :closed, -> { with_state(:closed) }
scope :closed_and_merged, -> { with_states(:closed, :merged) } scope :closed_and_merged, -> { with_states(:closed, :merged) }
......
...@@ -138,7 +138,7 @@ def member?(user_id) ...@@ -138,7 +138,7 @@ def member?(user_id)
end end
def human_max_access(user_id) def human_max_access(user_id)
Gitlab::Access.options.key max_member_access(user_id) Gitlab::Access.options_with_owner.key(max_member_access(user_id))
end end
# This method assumes project and group members are eager loaded for optimal # This method assumes project and group members are eager loaded for optimal
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать