Commit b8db9c8c authored by Douwe Maan's avatar Douwe Maan

Merge branch 'feature/disable-password-authentication' into 'master'

Allow password authentication to be disabled entirely

Closes #37320

See merge request gitlab-org/gitlab-ce!15223
parents a6cafbcb 257fd571
...@@ -196,7 +196,7 @@ class ApplicationController < ActionController::Base ...@@ -196,7 +196,7 @@ class ApplicationController < ActionController::Base
end end
def check_password_expiration def check_password_expiration
return if session[:impersonator_id] || current_user&.ldap_user? return if session[:impersonator_id] || !current_user&.allow_password_authentication?
password_expires_at = current_user&.password_expires_at password_expires_at = current_user&.password_expires_at
......
...@@ -51,7 +51,7 @@ class InvitesController < ApplicationController ...@@ -51,7 +51,7 @@ class InvitesController < ApplicationController
return if current_user return if current_user
notice = "To accept this invitation, sign in" notice = "To accept this invitation, sign in"
notice << " or create an account" if current_application_settings.signup_enabled? notice << " or create an account" if current_application_settings.allow_signup?
notice << "." notice << "."
store_location_for :user, request.fullpath store_location_for :user, request.fullpath
......
...@@ -140,7 +140,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController ...@@ -140,7 +140,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
label = Gitlab::OAuth::Provider.label_for(oauth['provider']) label = Gitlab::OAuth::Provider.label_for(oauth['provider'])
message = "Signing in using your #{label} account without a pre-existing GitLab account is not allowed." message = "Signing in using your #{label} account without a pre-existing GitLab account is not allowed."
if current_application_settings.signup_enabled? if current_application_settings.allow_signup?
message << " Create a GitLab account first, and then connect it to your #{label} account." message << " Create a GitLab account first, and then connect it to your #{label} account."
end end
......
class PasswordsController < Devise::PasswordsController class PasswordsController < Devise::PasswordsController
include Gitlab::CurrentSettings
before_action :resource_from_email, only: [:create] before_action :resource_from_email, only: [:create]
before_action :prevent_ldap_reset, only: [:create] before_action :check_password_authentication_available, only: [:create]
before_action :throttle_reset, only: [:create] before_action :throttle_reset, only: [:create]
def edit def edit
...@@ -25,7 +27,7 @@ class PasswordsController < Devise::PasswordsController ...@@ -25,7 +27,7 @@ class PasswordsController < Devise::PasswordsController
def update def update
super do |resource| super do |resource|
if resource.valid? && resource.require_password_creation? if resource.valid? && resource.password_automatically_set?
resource.update_attribute(:password_automatically_set, false) resource.update_attribute(:password_automatically_set, false)
end end
end end
...@@ -38,11 +40,15 @@ class PasswordsController < Devise::PasswordsController ...@@ -38,11 +40,15 @@ class PasswordsController < Devise::PasswordsController
self.resource = resource_class.find_by_email(email) self.resource = resource_class.find_by_email(email)
end end
def prevent_ldap_reset def check_password_authentication_available
return unless resource&.ldap_user? if resource
return if resource.allow_password_authentication?
else
return if current_application_settings.password_authentication_enabled?
end
redirect_to after_sending_reset_password_instructions_path_for(resource_name), redirect_to after_sending_reset_password_instructions_path_for(resource_name),
alert: "Cannot reset password for LDAP user." alert: "Password authentication is unavailable."
end end
def throttle_reset def throttle_reset
......
...@@ -77,7 +77,7 @@ class Profiles::PasswordsController < Profiles::ApplicationController ...@@ -77,7 +77,7 @@ class Profiles::PasswordsController < Profiles::ApplicationController
end end
def authorize_change_password! def authorize_change_password!
render_404 if @user.ldap_user? render_404 unless @user.allow_password_authentication?
end end
def user_params def user_params
......
...@@ -63,7 +63,7 @@ class SessionsController < Devise::SessionsController ...@@ -63,7 +63,7 @@ class SessionsController < Devise::SessionsController
user = User.admins.last user = User.admins.last
return unless user && user.require_password_creation? return unless user && user.require_password_creation_for_web?
Users::UpdateService.new(current_user, user: user).execute do |user| Users::UpdateService.new(current_user, user: user).execute do |user|
@token = user.generate_reset_token @token = user.generate_reset_token
......
...@@ -3,9 +3,9 @@ module ApplicationSettingsHelper ...@@ -3,9 +3,9 @@ module ApplicationSettingsHelper
include Gitlab::CurrentSettings include Gitlab::CurrentSettings
delegate :gravatar_enabled?, delegate :allow_signup?,
:signup_enabled?, :gravatar_enabled?,
:password_authentication_enabled?, :password_authentication_enabled_for_web?,
:akismet_enabled?, :akismet_enabled?,
:koding_enabled?, :koding_enabled?,
to: :current_application_settings to: :current_application_settings
...@@ -203,7 +203,7 @@ module ApplicationSettingsHelper ...@@ -203,7 +203,7 @@ module ApplicationSettingsHelper
:metrics_port, :metrics_port,
:metrics_sample_interval, :metrics_sample_interval,
:metrics_timeout, :metrics_timeout,
:password_authentication_enabled, :password_authentication_enabled_for_web,
:performance_bar_allowed_group_id, :performance_bar_allowed_group_id,
:performance_bar_enabled, :performance_bar_enabled,
:plantuml_enabled, :plantuml_enabled,
......
...@@ -58,12 +58,12 @@ module ButtonHelper ...@@ -58,12 +58,12 @@ module ButtonHelper
def http_clone_button(project, placement = 'right', append_link: true) def http_clone_button(project, placement = 'right', append_link: true)
klass = 'http-selector' klass = 'http-selector'
klass << ' has-tooltip' if current_user.try(:require_password_creation?) || current_user.try(:require_personal_access_token_creation_for_git_auth?) klass << ' has-tooltip' if current_user.try(:require_extra_setup_for_git_auth?)
protocol = gitlab_config.protocol.upcase protocol = gitlab_config.protocol.upcase
tooltip_title = tooltip_title =
if current_user.try(:require_password_creation?) if current_user.try(:require_password_creation_for_git?)
_("Set a password on your account to pull or push via %{protocol}.") % { protocol: protocol } _("Set a password on your account to pull or push via %{protocol}.") % { protocol: protocol }
else else
_("Create a personal access token on your account to pull or push via %{protocol}.") % { protocol: protocol } _("Create a personal access token on your account to pull or push via %{protocol}.") % { protocol: protocol }
......
...@@ -234,11 +234,11 @@ module ProjectsHelper ...@@ -234,11 +234,11 @@ module ProjectsHelper
def show_no_password_message? def show_no_password_message?
cookies[:hide_no_password_message].blank? && !current_user.hide_no_password && cookies[:hide_no_password_message].blank? && !current_user.hide_no_password &&
( current_user.require_password_creation? || current_user.require_personal_access_token_creation_for_git_auth? ) current_user.require_extra_setup_for_git_auth?
end end
def link_to_set_password def link_to_set_password
if current_user.require_password_creation? if current_user.require_password_creation_for_git?
link_to s_('SetPasswordToCloneLink|set a password'), edit_profile_password_path link_to s_('SetPasswordToCloneLink|set a password'), edit_profile_password_path
else else
link_to s_('CreateTokenToCloneLink|create a personal access token'), profile_personal_access_tokens_path link_to s_('CreateTokenToCloneLink|create a personal access token'), profile_personal_access_tokens_path
......
...@@ -276,7 +276,8 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -276,7 +276,8 @@ class ApplicationSetting < ActiveRecord::Base
koding_url: nil, koding_url: nil,
max_artifacts_size: Settings.artifacts['max_size'], max_artifacts_size: Settings.artifacts['max_size'],
max_attachment_size: Settings.gitlab['max_attachment_size'], max_attachment_size: Settings.gitlab['max_attachment_size'],
password_authentication_enabled: Settings.gitlab['password_authentication_enabled'], password_authentication_enabled_for_web: Settings.gitlab['signin_enabled'],
password_authentication_enabled_for_git: true,
performance_bar_allowed_group_id: nil, performance_bar_allowed_group_id: nil,
rsa_key_restriction: 0, rsa_key_restriction: 0,
plantuml_enabled: false, plantuml_enabled: false,
...@@ -474,6 +475,14 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -474,6 +475,14 @@ class ApplicationSetting < ActiveRecord::Base
has_attribute?(attr_name) ? public_send(attr_name) : FORBIDDEN_KEY_VALUE # rubocop:disable GitlabSecurity/PublicSend has_attribute?(attr_name) ? public_send(attr_name) : FORBIDDEN_KEY_VALUE # rubocop:disable GitlabSecurity/PublicSend
end end
def allow_signup?
signup_enabled? && password_authentication_enabled_for_web?
end
def password_authentication_enabled?
password_authentication_enabled_for_web? || password_authentication_enabled_for_git?
end
private private
def ensure_uuid! def ensure_uuid!
......
...@@ -633,18 +633,34 @@ class User < ActiveRecord::Base ...@@ -633,18 +633,34 @@ class User < ActiveRecord::Base
count.zero? && Gitlab::ProtocolAccess.allowed?('ssh') count.zero? && Gitlab::ProtocolAccess.allowed?('ssh')
end end
def require_password_creation? def require_password_creation_for_web?
password_automatically_set? && allow_password_authentication? allow_password_authentication_for_web? && password_automatically_set?
end
def require_password_creation_for_git?
allow_password_authentication_for_git? && password_automatically_set?
end end
def require_personal_access_token_creation_for_git_auth? def require_personal_access_token_creation_for_git_auth?
return false if current_application_settings.password_authentication_enabled? || ldap_user? return false if allow_password_authentication_for_git? || ldap_user?
PersonalAccessTokensFinder.new(user: self, impersonation: false, state: 'active').execute.none? PersonalAccessTokensFinder.new(user: self, impersonation: false, state: 'active').execute.none?
end end
def require_extra_setup_for_git_auth?
require_password_creation_for_git? || require_personal_access_token_creation_for_git_auth?
end
def allow_password_authentication? def allow_password_authentication?
!ldap_user? && current_application_settings.password_authentication_enabled? allow_password_authentication_for_web? || allow_password_authentication_for_git?
end
def allow_password_authentication_for_web?
current_application_settings.password_authentication_enabled_for_web? && !ldap_user?
end
def allow_password_authentication_for_git?
current_application_settings.password_authentication_enabled_for_git? && !ldap_user?
end end
def can_change_username? def can_change_username?
......
...@@ -34,7 +34,7 @@ module Users ...@@ -34,7 +34,7 @@ module Users
private private
def can_create_user? def can_create_user?
(current_user.nil? && current_application_settings.signup_enabled?) || current_user&.admin? (current_user.nil? && current_application_settings.allow_signup?) || current_user&.admin?
end end
# Allowed params for creating a user (admins only) # Allowed params for creating a user (admins only)
......
...@@ -160,9 +160,22 @@ ...@@ -160,9 +160,22 @@
.form-group .form-group
.col-sm-offset-2.col-sm-10 .col-sm-offset-2.col-sm-10
.checkbox .checkbox
= f.label :password_authentication_enabled do = f.label :password_authentication_enabled_for_web do
= f.check_box :password_authentication_enabled = f.check_box :password_authentication_enabled_for_web
Sign-in enabled Password authentication enabled for web interface
.help-block
When disabled, an external authentication provider must be used.
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
= f.label :password_authentication_enabled_for_git do
= f.check_box :password_authentication_enabled_for_git
Password authentication enabled for Git over HTTP(S)
.help-block
When disabled, a Personal Access Token
- if Gitlab::LDAP::Config.enabled?
or LDAP password
must be used to authenticate.
- if omniauth_enabled? && button_based_providers.any? - if omniauth_enabled? && button_based_providers.any?
.form-group .form-group
= f.label :enabled_oauth_sign_in_sources, 'Enabled OAuth sign-in sources', class: 'control-label col-sm-2' = f.label :enabled_oauth_sign_in_sources, 'Enabled OAuth sign-in sources', class: 'control-label col-sm-2'
......
...@@ -45,10 +45,10 @@ ...@@ -45,10 +45,10 @@
.well-segment.admin-well.admin-well-features .well-segment.admin-well.admin-well-features
%h4 Features %h4 Features
- sign_up = "Sign up" - sign_up = "Sign up"
%p{ "aria-label" => "#{sign_up}: status " + (signup_enabled? ? "on" : "off") } %p{ "aria-label" => "#{sign_up}: status " + (allow_signup? ? "on" : "off") }
= sign_up = sign_up
%span.light.pull-right %span.light.pull-right
= boolean_to_icon signup_enabled? = boolean_to_icon allow_signup?
- ldap = "LDAP" - ldap = "LDAP"
%p{ "aria-label" => "#{ldap}: status " + (Gitlab.config.ldap.enabled ? "on" : "off") } %p{ "aria-label" => "#{ldap}: status " + (Gitlab.config.ldap.enabled ? "on" : "off") }
= ldap = ldap
......
...@@ -6,15 +6,15 @@ ...@@ -6,15 +6,15 @@
- else - else
= render 'devise/shared/tabs_normal' = render 'devise/shared/tabs_normal'
.tab-content .tab-content
- if password_authentication_enabled? || ldap_enabled? || crowd_enabled? - if password_authentication_enabled_for_web? || ldap_enabled? || crowd_enabled?
= render 'devise/shared/signin_box' = render 'devise/shared/signin_box'
-# Signup only makes sense if you can also sign-in -# Signup only makes sense if you can also sign-in
- if password_authentication_enabled? && signup_enabled? - if allow_signup?
= render 'devise/shared/signup_box' = render 'devise/shared/signup_box'
-# Show a message if none of the mechanisms above are enabled -# Show a message if none of the mechanisms above are enabled
- if !password_authentication_enabled? && !ldap_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?) - if !password_authentication_enabled_for_web? && !ldap_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
%div %div
No authentication methods configured. No authentication methods configured.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<%= link_to "Sign in", new_session_path(resource_name), class: "btn" %><br /> <%= link_to "Sign in", new_session_path(resource_name), class: "btn" %><br />
<% end -%> <% end -%>
<%- if devise_mapping.registerable? && controller_name != 'registrations' && gitlab_config.signup_enabled %> <%- if devise_mapping.registerable? && controller_name != 'registrations' && allow_signup? %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br /> <%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%> <% end -%>
......
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
.login-box.tab-pane{ id: "#{server['provider_name']}", role: 'tabpanel', class: active_when(i.zero? && !crowd_enabled?) } .login-box.tab-pane{ id: "#{server['provider_name']}", role: 'tabpanel', class: active_when(i.zero? && !crowd_enabled?) }
.login-body .login-body
= render 'devise/sessions/new_ldap', server: server = render 'devise/sessions/new_ldap', server: server
- if password_authentication_enabled? - if password_authentication_enabled_for_web?
.login-box.tab-pane{ id: 'ldap-standard', role: 'tabpanel' } .login-box.tab-pane{ id: 'ldap-standard', role: 'tabpanel' }
.login-body .login-body
= render 'devise/sessions/new_base' = render 'devise/sessions/new_base'
- elsif password_authentication_enabled? - elsif password_authentication_enabled_for_web?
.login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' } .login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' }
.login-body .login-body
= render 'devise/sessions/new_base' = render 'devise/sessions/new_base'
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
- @ldap_servers.each_with_index do |server, i| - @ldap_servers.each_with_index do |server, i|
%li{ class: active_when(i.zero? && !crowd_enabled?) } %li{ class: active_when(i.zero? && !crowd_enabled?) }
= link_to server['label'], "##{server['provider_name']}", 'data-toggle' => 'tab' = link_to server['label'], "##{server['provider_name']}", 'data-toggle' => 'tab'
- if password_authentication_enabled? - if password_authentication_enabled_for_web?
%li %li
= link_to 'Standard', '#ldap-standard', 'data-toggle' => 'tab' = link_to 'Standard', '#ldap-standard', 'data-toggle' => 'tab'
- if password_authentication_enabled? && signup_enabled? - if allow_signup?
%li %li
= link_to 'Register', '#register-pane', 'data-toggle' => 'tab' = link_to 'Register', '#register-pane', 'data-toggle' => 'tab'
%ul.nav-links.new-session-tabs.nav-tabs{ role: 'tablist' } %ul.nav-links.new-session-tabs.nav-tabs{ role: 'tablist' }
%li.active{ role: 'presentation' } %li.active{ role: 'presentation' }
%a{ href: '#login-pane', data: { toggle: 'tab' }, role: 'tab' } Sign in %a{ href: '#login-pane', data: { toggle: 'tab' }, role: 'tab' } Sign in
- if password_authentication_enabled? && signup_enabled? - if allow_signup?
%li{ role: 'presentation' } %li{ role: 'presentation' }
%a{ href: '#register-pane', data: { toggle: 'tab' }, role: 'tab' } Register %a{ href: '#register-pane', data: { toggle: 'tab' }, role: 'tab' } Register
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
= link_to profile_emails_path do = link_to profile_emails_path do
%strong.fly-out-top-item-name %strong.fly-out-top-item-name
#{ _('Emails') } #{ _('Emails') }
- unless current_user.ldap_user? - if current_user.allow_password_authentication?
= nav_link(controller: :passwords) do = nav_link(controller: :passwords) do
= link_to edit_profile_password_path do = link_to edit_profile_password_path do
.nav-icon-container .nav-icon-container
......
%p %p
Hi #{@user['name']}! Hi #{@user['name']}!
%p %p
- if Gitlab.config.gitlab.signup_enabled - if current_application_settings.allow_signup?
Your account has been created successfully. Your account has been created successfully.
- else - else
The Administrator created an account for you. Now you are a member of the company GitLab application. The Administrator created an account for you. Now you are a member of the company GitLab application.
......
---
title: Allow password authentication to be disabled entirely
merge_request: 15223
author: Markus Koller
type: changed
...@@ -256,7 +256,7 @@ rescue ArgumentError # no user configured ...@@ -256,7 +256,7 @@ rescue ArgumentError # no user configured
end end
Settings.gitlab['time_zone'] ||= nil Settings.gitlab['time_zone'] ||= nil
Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil? Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil?
Settings.gitlab['password_authentication_enabled'] ||= true if Settings.gitlab['password_authentication_enabled'].nil? Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].nil?
Settings.gitlab['restricted_visibility_levels'] = Settings.__send__(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], []) Settings.gitlab['restricted_visibility_levels'] = Settings.__send__(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], [])
Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil? Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil?
Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)|[Ii]mplement(?:s|ed|ing)?)(:?) +(?:(?:issues? +)?%{issue_ref}(?:(?:, *| +and +)?)|([A-Z][A-Z0-9_]+-\d+))+)' if Settings.gitlab['issue_closing_pattern'].nil? Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)|[Ii]mplement(?:s|ed|ing)?)(:?) +(?:(?:issues? +)?%{issue_ref}(?:(?:, *| +and +)?)|([A-Z][A-Z0-9_]+-\d+))+)' if Settings.gitlab['issue_closing_pattern'].nil?
......
class RenameApplicationSettingsPasswordAuthenticationEnabledToPasswordAuthenticationEnabledForWeb < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
rename_column_concurrently :application_settings, :password_authentication_enabled, :password_authentication_enabled_for_web
end
def down
cleanup_concurrent_column_rename :application_settings, :password_authentication_enabled_for_web, :password_authentication_enabled
end
end
class AddPasswordAuthenticationEnabledForGitToApplicationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column :application_settings, :password_authentication_enabled_for_git, :boolean, default: true, null: false
end
end
class CleanupApplicationSettingsPasswordAuthenticationEnabledRename < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
cleanup_concurrent_column_rename :application_settings, :password_authentication_enabled, :password_authentication_enabled_for_web
end
def down
rename_column_concurrently :application_settings, :password_authentication_enabled_for_web, :password_authentication_enabled
end
end
...@@ -129,7 +129,6 @@ ActiveRecord::Schema.define(version: 20171121144800) do ...@@ -129,7 +129,6 @@ ActiveRecord::Schema.define(version: 20171121144800) do
t.boolean "prometheus_metrics_enabled", default: false, null: false t.boolean "prometheus_metrics_enabled", default: false, null: false
t.boolean "help_page_hide_commercial_content", default: false t.boolean "help_page_hide_commercial_content", default: false
t.string "help_page_support_url" t.string "help_page_support_url"
t.boolean "password_authentication_enabled"
t.integer "performance_bar_allowed_group_id" t.integer "performance_bar_allowed_group_id"
t.boolean "hashed_storage_enabled", default: false, null: false t.boolean "hashed_storage_enabled", default: false, null: false
t.boolean "project_export_enabled", default: true, null: false t.boolean "project_export_enabled", default: true, null: false
...@@ -149,6 +148,8 @@ ActiveRecord::Schema.define(version: 20171121144800) do ...@@ -149,6 +148,8 @@ ActiveRecord::Schema.define(version: 20171121144800) do
t.boolean "throttle_authenticated_web_enabled", default: false, null: false t.boolean "throttle_authenticated_web_enabled", default: false, null: false
t.integer "throttle_authenticated_web_requests_per_period", default: 7200, null: false t.integer "throttle_authenticated_web_requests_per_period", default: 7200, null: false
t.integer "throttle_authenticated_web_period_in_seconds", default: 3600, null: false t.integer "throttle_authenticated_web_period_in_seconds", default: 3600, null: false
t.boolean "password_authentication_enabled_for_web"
t.boolean "password_authentication_enabled_for_git", default: true
end end
create_table "audit_events", force: :cascade do |t| create_table "audit_events", force: :cascade do |t|
......
...@@ -30,6 +30,12 @@ immediately block all access. ...@@ -30,6 +30,12 @@ immediately block all access.
>**Note**: GitLab EE supports a configurable sync time, with a default >**Note**: GitLab EE supports a configurable sync time, with a default
of one hour. of one hour.
## Git password authentication
LDAP-enabled users can always authenticate with Git using their GitLab username
or email and LDAP password, even if password authentication for Git is disabled
in the application settings.
## Configuration ## Configuration
To enable LDAP integration you need to add your LDAP server settings in To enable LDAP integration you need to add your LDAP server settings in
......
...@@ -25,7 +25,7 @@ Example response: ...@@ -25,7 +25,7 @@ Example response:
"id" : 1, "id" : 1,
"default_branch_protection" : 2, "default_branch_protection" : 2,
"restricted_visibility_levels" : [], "restricted_visibility_levels" : [],
"password_authentication_enabled" : true, "password_authentication_enabled_for_web" : true,
"after_sign_out_path" : null, "after_sign_out_path" : null,
"max_attachment_size" : 10, "max_attachment_size" : 10,
"user_oauth_applications" : true, "user_oauth_applications" : true,
...@@ -117,7 +117,8 @@ PUT /application/settings ...@@ -117,7 +117,8 @@ PUT /application/settings
| `metrics_port` | integer | no | The UDP port to use for connecting to InfluxDB | | `metrics_port` | integer | no | The UDP port to use for connecting to InfluxDB |
| `metrics_sample_interval` | integer | yes (if `metrics_enabled` is `true`) | The sampling interval in seconds. | | `metrics_sample_interval` | integer | yes (if `metrics_enabled` is `true`) | The sampling interval in seconds. |
| `metrics_timeout` | integer | yes (if `metrics_enabled` is `true`) | The amount of seconds after which InfluxDB will time out. | | `metrics_timeout` | integer | yes (if `metrics_enabled` is `true`) | The amount of seconds after which InfluxDB will time out. |
| `password_authentication_enabled` | boolean | no | Enable authentication via a GitLab account password. Default is `true`. | | `password_authentication_enabled_for_web` | boolean | no | Enable authentication for the web interface via a GitLab account password. Default is `true`. |
| `password_authentication_enabled_for_git` | boolean | no | Enable authentication for Git over HTTP(S) via a GitLab account password. Default is `true`. |
| `performance_bar_allowed_group_id` | string | no | The group that is allowed to enable the performance bar | | `performance_bar_allowed_group_id` | string | no | The group that is allowed to enable the performance bar |
| `performance_bar_enabled` | boolean | no | Allow enabling the performance bar | | `performance_bar_enabled` | boolean | no | Allow enabling the performance bar |
| `plantuml_enabled` | boolean | no | Enable PlantUML integration. Default is `false`. | | `plantuml_enabled` | boolean | no | Enable PlantUML integration. Default is `false`. |
...@@ -165,7 +166,7 @@ Example response: ...@@ -165,7 +166,7 @@ Example response:
"id": 1, "id": 1,
"default_projects_limit": 100000, "default_projects_limit": 100000,
"signup_enabled": true, "signup_enabled": true,
"password_authentication_enabled": true, "password_authentication_enabled_for_web": true,
"gravatar_enabled": true, "gravatar_enabled": true,
"sign_in_text": "", "sign_in_text": "",
"created_at": "2015-06-12T15:51:55.432Z", "created_at": "2015-06-12T15:51:55.432Z",
......
...@@ -763,7 +763,10 @@ module API ...@@ -763,7 +763,10 @@ module API
expose(:default_project_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_project_visibility) } expose(:default_project_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_project_visibility) }
expose(:default_snippet_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_snippet_visibility) } expose(:default_snippet_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_snippet_visibility) }
expose(:default_group_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_group_visibility) } expose(:default_group_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_group_visibility) }
expose :password_authentication_enabled, as: :signin_enabled
# support legacy names, can be removed in v5
expose :password_authentication_enabled_for_web, as: :password_authentication_enabled
expose :password_authentication_enabled_for_web, as: :signin_enabled
end end
class Release < Grape::Entity class Release < Grape::Entity
......
...@@ -44,9 +44,11 @@ module API ...@@ -44,9 +44,11 @@ module API
requires :domain_blacklist, type: String, desc: 'Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com' requires :domain_blacklist, type: String, desc: 'Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com'
end end
optional :after_sign_up_text, type: String, desc: 'Text shown after sign up' optional :after_sign_up_text, type: String, desc: 'Text shown after sign up'
optional :password_authentication_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled' optional :password_authentication_enabled_for_web, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface'
optional :signin_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled' optional :password_authentication_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface' # support legacy names, can be removed in v5
mutually_exclusive :password_authentication_enabled, :signin_enabled optional :signin_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface' # support legacy names, can be removed in v5
mutually_exclusive :password_authentication_enabled_for_web, :password_authentication_enabled, :signin_enabled
optional :password_authentication_enabled_for_git, type: Boolean, desc: 'Flag indicating if password authentication is enabled for Git over HTTP(S)'
optional :require_two_factor_authentication, type: Boolean, desc: 'Require all users to setup Two-factor authentication' optional :require_two_factor_authentication, type: Boolean, desc: 'Require all users to setup Two-factor authentication'
given require_two_factor_authentication: ->(val) { val } do given require_two_factor_authentication: ->(val) { val } do
requires :two_factor_grace_period, type: Integer, desc: 'Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication' requires :two_factor_grace_period, type: Integer, desc: 'Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication'
...@@ -135,8 +137,11 @@ module API ...@@ -135,8 +137,11 @@ module API
put "application/settings" do put "application/settings" do
attrs = declared_params(include_missing: false) attrs = declared_params(include_missing: false)
# support legacy names, can be removed in v5
if attrs.has_key?(:signin_enabled) if attrs.has_key?(:signin_enabled)
attrs[:password_authentication_enabled] = attrs.delete(:signin_enabled) attrs[:password_authentication_enabled_for_web] = attrs.delete(:signin_enabled)
elsif attrs.has_key?(:password_authentication_enabled)
attrs[:password_authentication_enabled_for_web] = attrs.delete(:password_authentication_enabled)
end end
if current_settings.update_attributes(attrs) if current_settings.update_attributes(attrs)
......
...@@ -172,8 +172,8 @@ module API ...@@ -172,8 +172,8 @@ module API
expose :id expose :id
expose :default_projects_limit expose :default_projects_limit
expose :signup_enabled expose :signup_enabled
expose :password_authentication_enabled expose :password_authentication_enabled_for_web, as: :password_authentication_enabled
expose :password_authentication_enabled, as: :signin_enabled expose :password_authentication_enabled_for_web, as: :signin_enabled
expose :gravatar_enabled expose :gravatar_enabled
expose :sign_in_text expose :sign_in_text
expose :after_sign_up_text expose :after_sign_up_text
......
...@@ -44,8 +44,8 @@ module API ...@@ -44,8 +44,8 @@ module API
requires :domain_blacklist, type: String, desc: 'Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com' requires :domain_blacklist, type: String, desc: 'Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com'
end end
optional :after_sign_up_text, type: String, desc: 'Text shown after sign up' optional :after_sign_up_text, type: String, desc: 'Text shown after sign up'
optional :password_authentication_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled' optional :password_authentication_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface'
optional :signin_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled' optional :signin_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface'
mutually_exclusive :password_authentication_enabled, :signin_enabled mutually_exclusive :password_authentication_enabled, :signin_enabled
optional :require_two_factor_authentication, type: Boolean, desc: 'Require all users to setup Two-factor authentication' optional :require_two_factor_authentication, type: Boolean, desc: 'Require all users to setup Two-factor authentication'
given require_two_factor_authentication: ->(val) { val } do given require_two_factor_authentication: ->(val) { val } do
...@@ -131,7 +131,9 @@ module API ...@@ -131,7 +131,9 @@ module API
attrs = declared_params(include_missing: false) attrs = declared_params(include_missing: false)
if attrs.has_key?(:signin_enabled) if attrs.has_key?(:signin_enabled)
attrs[:password_authentication_enabled] = attrs.delete(:signin_enabled) attrs[:password_authentication_enabled_for_web] = attrs.delete(:signin_enabled)
elsif attrs.has_key?(:password_authentication_enabled)
attrs[:password_authentication_enabled_for_web] = attrs.delete(:password_authentication_enabled)
end end
if current_settings.update_attributes(attrs) if current_settings.update_attributes(attrs)
......
...@@ -34,7 +34,7 @@ module Gitlab ...@@ -34,7 +34,7 @@ module Gitlab
rate_limit!(ip, success: result.success?, login: login) rate_limit!(ip, success: result.success?, login: login)
Gitlab::Auth::UniqueIpsLimiter.limit_user!(result.actor) Gitlab::Auth::UniqueIpsLimiter.limit_user!(result.actor)
return result if result.success? || current_application_settings.password_authentication_enabled? || Gitlab::LDAP::Config.enabled? return result if result.success? || authenticate_using_internal_or_ldap_password?
# If sign-in is disabled and LDAP is not configured, recommend a # If sign-in is disabled and LDAP is not configured, recommend a
# personal access token on failed auth attempts # personal access token on failed auth attempts
...@@ -45,6 +45,10 @@ module Gitlab ...@@ -45,6 +45,10 @@ module Gitlab
# Avoid resource intensive login checks if password is not provided # Avoid resource intensive login checks if password is not provided
return unless password.present? return unless password.present?
# Nothing to do here if internal auth is disabled and LDAP is
# not configured
return unless authenticate_using_internal_or_ldap_password?
Gitlab::Auth::UniqueIpsLimiter.limit_user! do Gitlab::Auth::UniqueIpsLimiter.limit_user! do
user = User.by_login(login) user = User.by_login(login)
...@@ -52,10 +56,8 @@ module Gitlab ...@@ -52,10 +56,8 @@ module Gitlab
# LDAP users are only authenticated via LDAP # LDAP users are only authenticated via LDAP
if user.nil? || user.ldap_user? if user.nil? || user.ldap_user?
# Second chance - try LDAP authentication # Second chance - try LDAP authentication
return unless Gitlab::LDAP::Config.enabled?
Gitlab::LDAP::Authentication.login(login, password) Gitlab::LDAP::Authentication.login(login, password)
else elsif current_application_settings.password_authentication_enabled_for_git?
user if user.active? && user.valid_password?(password) user if user.active? && user.valid_password?(password)
end end
end end
...@@ -84,6 +86,10 @@ module Gitlab ...@@ -84,6 +86,10 @@ module Gitlab
private private
def authenticate_using_internal_or_ldap_password?
current_application_settings.password_authentication_enabled_for_git? || Gitlab::LDAP::Config.enabled?
end
def service_request_check(login, password, project) def service_request_check(login, password, project)
matched_login = /(?<service>^[a-zA-Z]*-ci)-token$/.match(login) matched_login = /(?<service>^[a-zA-Z]*-ci)-token$/.match(login)
......
...@@ -79,7 +79,7 @@ module Gitlab ...@@ -79,7 +79,7 @@ module Gitlab
def features_usage_data_ce def features_usage_data_ce
{ {
signup: current_application_settings.signup_enabled?, signup: current_application_settings.allow_signup?,
ldap: Gitlab.config.ldap.enabled, ldap: Gitlab.config.ldap.enabled,
gravatar: current_application_settings.gravatar_enabled?, gravatar: current_application_settings.gravatar_enabled?,
omniauth: Gitlab.config.omniauth.enabled, omniauth: Gitlab.config.omniauth.enabled,
......
...@@ -41,14 +41,13 @@ describe ApplicationController do ...@@ -41,14 +41,13 @@ describe ApplicationController do
controller.send(:check_password_expiration) controller.send(:check_password_expiration)
end end
it 'redirects if the user is over their password expiry and sign-in is disabled' do it 'does not redirect if the user is over their password expiry but password authentication is disabled for the web interface' do
stub_application_setting(password_authentication_enabled: false) stub_application_setting(password_authentication_enabled_for_web: false)
stub_application_setting(password_authentication_enabled_for_git: false)
user.password_expires_at = Time.new(2002) user.password_expires_at = Time.new(2002)
expect(user.ldap_user?).to be_falsey
allow(controller).to receive(:current_user).and_return(user) allow(controller).to receive(:current_user).and_return(user)
expect(controller).to receive(:redirect_to) expect(controller).not_to receive(:redirect_to)
expect(controller).to receive(:new_profile_password_path)
controller.send(:check_password_expiration) controller.send(:check_password_expiration)
end end
......
require 'spec_helper' require 'spec_helper'
describe PasswordsController do describe PasswordsController do
describe '#prevent_ldap_reset' do describe '#check_password_authentication_available' do
before do before do
@request.env["devise.mapping"] = Devise.mappings[:user] @request.env["devise.mapping"] = Devise.mappings[:user]
end end
context 'when password authentication is disabled' do context 'when password authentication is disabled for the web interface and Git' do
it 'allows password reset' do it 'prevents a password reset' do
stub_application_setting(password_authentication_enabled: false) stub_application_setting(password_authentication_enabled_for_web: false)
stub_application_setting(password_authentication_enabled_for_git: false)
post :create post :create
expect(response).to have_gitlab_http_status(302) expect(response).to have_gitlab_http_status(302)
expect(flash[:alert]).to eq 'Password authentication is unavailable.'
end end
end end
...@@ -22,7 +24,7 @@ describe PasswordsController do ...@@ -22,7 +24,7 @@ describe PasswordsController do
it 'prevents a password reset' do it 'prevents a password reset' do
post :create, user: { email: user.email } post :create, user: { email: user.email }
expect(flash[:alert]).to eq('Cannot reset password for LDAP user.') expect(flash[:alert]).to eq 'Password authentication is unavailable.'
end end
end end
end end
......
...@@ -118,7 +118,8 @@ describe RegistrationsController do ...@@ -118,7 +118,8 @@ describe RegistrationsController do
context 'user does not require password confirmation' do context 'user does not require password confirmation' do
before do before do
stub_application_setting(password_authentication_enabled: false) stub_application_setting(password_authentication_enabled_for_web: false)
stub_application_setting(password_authentication_enabled_for_git: false)
end end
it 'fails if username confirmation is not provided' do it 'fails if username confirmation is not provided' do
......
...@@ -53,12 +53,13 @@ describe 'Profile > Password' do ...@@ -53,12 +53,13 @@ describe 'Profile > Password' do
context 'Regular user' do context 'Regular user' do
let(:user) { create(:user) } let(:user) { create(:user) }
it 'renders 200 when sign-in is disabled' do it 'renders 404 when password authentication is disabled for the web interface and Git' do
stub_application_setting(password_authentication_enabled: false) stub_application_setting(password_authentication_enabled_for_web: false)
stub_application_setting(password_authentication_enabled_for_git: false)
visit edit_profile_password_path visit edit_profile_password_path
expect(page).to have_gitlab_http_status(200) expect(page).to have_gitlab_http_status(404)
end end
end end
......
...@@ -30,7 +30,7 @@ feature 'No Password Alert' do ...@@ -30,7 +30,7 @@ feature 'No Password Alert' do
let(:user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'saml') } let(:user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'saml') }
before do before do
stub_application_setting(password_authentication_enabled?: false) stub_application_setting(password_authentication_enabled_for_git?: false)
stub_omniauth_saml_config(enabled: true, auto_link_saml_user: true, allow_single_sign_on: ['saml'], providers: [mock_saml_config]) stub_omniauth_saml_config(enabled: true, auto_link_saml_user: true, allow_single_sign_on: ['saml'], providers: [mock_saml_config])
end end
......
...@@ -35,7 +35,7 @@ describe ButtonHelper do ...@@ -35,7 +35,7 @@ describe ButtonHelper do
context 'with internal auth disabled' do context 'with internal auth disabled' do
before do before do
stub_application_setting(password_authentication_enabled?: false) stub_application_setting(password_authentication_enabled_for_git?: false)
end end
context 'when user has no personal access tokens' do context 'when user has no personal access tokens' do
......
...@@ -150,17 +150,26 @@ describe ProjectsHelper do ...@@ -150,17 +150,26 @@ describe ProjectsHelper do
end end
end end
context 'user requires a password' do context 'user has hidden the message' do
let(:user) { create(:user, password_automatically_set: true) } it 'returns false' do
allow(helper).to receive(:cookies).and_return(hide_no_password_message: true)
expect(helper.show_no_password_message?).to be_falsey
end
end
context 'user requires a password for Git' do
it 'returns true' do it 'returns true' do
allow(user).to receive(:require_password_creation_for_git?).and_return(true)
expect(helper.show_no_password_message?).to be_truthy expect(helper.show_no_password_message?).to be_truthy
end end
end end
context 'user requires a personal access token' do context 'user requires a personal access token for Git' do
it 'returns true' do it 'returns true' do
stub_application_setting(password_authentication_enabled?: false) allow(user).to receive(:require_password_creation_for_git?).and_return(false)
allow(user).to receive(:require_personal_access_token_creation_for_git_auth?).and_return(true)
expect(helper.show_no_password_message?).to be_truthy expect(helper.show_no_password_message?).to be_truthy
end end
...@@ -168,23 +177,23 @@ describe ProjectsHelper do ...@@ -168,23 +177,23 @@ describe ProjectsHelper do
end end
describe '#link_to_set_password' do describe '#link_to_set_password' do
let(:user) { create(:user, password_automatically_set: true) }
before do before do
allow(helper).to receive(:current_user).and_return(user) allow(helper).to receive(:current_user).and_return(user)
end end
context 'user requires a password' do context 'password authentication is enabled for Git' do
let(:user) { create(:user, password_automatically_set: true) }
it 'returns link to set a password' do it 'returns link to set a password' do
stub_application_setting(password_authentication_enabled_for_git?: true)
expect(helper.link_to_set_password).to match %r{<a href="#{edit_profile_password_path}">set a password</a>} expect(helper.link_to_set_password).to match %r{<a href="#{edit_profile_password_path}">set a password</a>}
end end
end end
context 'user requires a personal access token' do context 'password authentication is disabled for Git' do
let(:user) { create(:user) }
it 'returns link to create a personal access token' do it 'returns link to create a personal access token' do
stub_application_setting(password_authentication_enabled?: false) stub_application_setting(password_authentication_enabled_for_git?: false)
expect(helper.link_to_set_password).to match %r{<a href="#{profile_personal_access_tokens_path}">create a personal access token</a>} expect(helper.link_to_set_password).to match %r{<a href="#{profile_personal_access_tokens_path}">create a personal access token</a>}
end end
......
...@@ -251,7 +251,7 @@ describe Gitlab::Auth do ...@@ -251,7 +251,7 @@ describe Gitlab::Auth do
end end
it 'throws an error suggesting user create a PAT when internal auth is disabled' do it 'throws an error suggesting user create a PAT when internal auth is disabled' do
allow_any_instance_of(ApplicationSetting).to receive(:password_authentication_enabled?) { false } allow_any_instance_of(ApplicationSetting).to receive(:password_authentication_enabled_for_git?) { false }
expect { gl_auth.find_for_git_client('foo', 'bar', project: nil, ip: 'ip') }.to raise_error(Gitlab::Auth::MissingPersonalAccessTokenError) expect { gl_auth.find_for_git_client('foo', 'bar', project: nil, ip: 'ip') }.to raise_error(Gitlab::Auth::MissingPersonalAccessTokenError)
end end
...@@ -324,6 +324,26 @@ describe Gitlab::Auth do ...@@ -324,6 +324,26 @@ describe Gitlab::Auth do
gl_auth.find_with_user_password('ldap_user', 'password') gl_auth.find_with_user_password('ldap_user', 'password')
end end
end end
context "with password authentication disabled for Git" do
before do
stub_application_setting(password_authentication_enabled_for_git: false)
end
it "does not find user by valid login/password" do
expect(gl_auth.find_with_user_password(username, password)).to be_nil
end
context "with ldap enabled" do
before do
allow(Gitlab::LDAP::Config).to receive(:enabled?).and_return(true)
end
it "does not find non-ldap user by valid login/password" do
expect(gl_auth.find_with_user_password(username, password)).to be_nil
end
end
end
end end
private private
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::FakeApplicationSettings do describe Gitlab::FakeApplicationSettings do
let(:defaults) { { password_authentication_enabled: false, foobar: 'asdf', signup_enabled: true, 'test?' => 123 } } let(:defaults) { { password_authentication_enabled_for_web: false, foobar: 'asdf', signup_enabled: true, 'test?' => 123 } }
subject { described_class.new(defaults) } subject { described_class.new(defaults) }
it 'wraps OpenStruct variables properly' do it 'wraps OpenStruct variables properly' do
expect(subject.password_authentication_enabled).to be_falsey expect(subject.password_authentication_enabled_for_web).to be_falsey
expect(subject.signup_enabled).to be_truthy expect(subject.signup_enabled).to be_truthy
expect(subject.foobar).to eq('asdf') expect(subject.foobar).to eq('asdf')
end end
it 'defines predicate methods' do it 'defines predicate methods' do
expect(subject.password_authentication_enabled?).to be_falsey expect(subject.password_authentication_enabled_for_web?).to be_falsey
expect(subject.signup_enabled?).to be_truthy expect(subject.signup_enabled?).to be_truthy
end end
it 'predicate method changes when value is updated' do it 'predicate method changes when value is updated' do
subject.password_authentication_enabled = true subject.password_authentication_enabled_for_web = true
expect(subject.password_authentication_enabled?).to be_truthy expect(subject.password_authentication_enabled_for_web?).to be_truthy
end end
it 'does not define a predicate method' do it 'does not define a predicate method' do
......
...@@ -103,7 +103,7 @@ describe Gitlab::UsageData do ...@@ -103,7 +103,7 @@ describe Gitlab::UsageData do
subject { described_class.features_usage_data_ce } subject { described_class.features_usage_data_ce }
it 'gathers feature usage data' do it 'gathers feature usage data' do
expect(subject[:signup]).to eq(current_application_settings.signup_enabled?) expect(subject[:signup]).to eq(current_application_settings.allow_signup?)
expect(subject[:ldap]).to eq(Gitlab.config.ldap.enabled) expect(subject[:ldap]).to eq(Gitlab.config.ldap.enabled)
expect(subject[:gravatar]).to eq(current_application_settings.gravatar_enabled?) expect(subject[:gravatar]).to eq(current_application_settings.gravatar_enabled?)
expect(subject[:omniauth]).to eq(Gitlab.config.omniauth.enabled) expect(subject[:omniauth]).to eq(Gitlab.config.omniauth.enabled)
......
...@@ -564,4 +564,22 @@ describe ApplicationSetting do ...@@ -564,4 +564,22 @@ describe ApplicationSetting do
expect(setting.key_restriction_for(:foo)).to eq(described_class::FORBIDDEN_KEY_VALUE) expect(setting.key_restriction_for(:foo)).to eq(described_class::FORBIDDEN_KEY_VALUE)
end end
end end
describe '#allow_signup?' do
it 'returns true' do
expect(setting.allow_signup?).to be_truthy
end
it 'returns false if signup is disabled' do
allow(setting).to receive(:signup_enabled?).and_return(false)
expect(setting.allow_signup?).to be_falsey
end
it 'returns false if password authentication is disabled for the web interface' do
allow(setting).to receive(:password_authentication_enabled_for_web?).and_return(false)
expect(setting.allow_signup?).to be_falsey
end
end
end end
...@@ -2143,25 +2143,47 @@ describe User do ...@@ -2143,25 +2143,47 @@ describe User do
end end
end end
describe '#allow_password_authentication?' do describe '#allow_password_authentication_for_web?' do
context 'regular user' do context 'regular user' do
let(:user) { build(:user) } let(:user) { build(:user) }
it 'returns true when sign-in is enabled' do it 'returns true when password authentication is enabled for the web interface' do
expect(user.allow_password_authentication?).to be_truthy expect(user.allow_password_authentication_for_web?).to be_truthy
end end
it 'returns false when sign-in is disabled' do it 'returns false when password authentication is disabled for the web interface' do
stub_application_setting(password_authentication_enabled: false) stub_application_setting(password_authentication_enabled_for_web: false)
expect(user.allow_password_authentication?).to be_falsey expect(user.allow_password_authentication_for_web?).to be_falsey
end end
end end
it 'returns false for ldap user' do it 'returns false for ldap user' do
user = create(:omniauth_user, provider: 'ldapmain') user = create(:omniauth_user, provider: 'ldapmain')
expect(user.allow_password_authentication?).to be_falsey expect(user.allow_password_authentication_for_web?).to be_falsey
end
end
describe '#allow_password_authentication_for_git?' do
context 'regular user' do
let(:user) { build(:user) }
it 'returns true when password authentication is enabled for Git' do
expect(user.allow_password_authentication_for_git?).to be_truthy
end
it 'returns false when password authentication is disabled Git' do
stub_application_setting(password_authentication_enabled_for_git: false)
expect(user.allow_password_authentication_for_git?).to be_falsey
end
end
it 'returns false for ldap user' do
user = create(:omniauth_user, provider: 'ldapmain')
expect(user.allow_password_authentication_for_git?).to be_falsey
end end
end end
...@@ -2381,7 +2403,8 @@ describe User do ...@@ -2381,7 +2403,8 @@ describe User do
let(:expected) { !(password_automatically_set || ldap_user || password_authentication_disabled) } let(:expected) { !(password_automatically_set || ldap_user || password_authentication_disabled) }
before do before do
stub_application_setting(password_authentication_enabled: !password_authentication_disabled) stub_application_setting(password_authentication_enabled_for_web: !password_authentication_disabled)
stub_application_setting(password_authentication_enabled_for_git: !password_authentication_disabled)
end end
it 'returns false unless all inputs are true' do it 'returns false unless all inputs are true' do
......
...@@ -10,7 +10,7 @@ describe API::Settings, 'Settings' do ...@@ -10,7 +10,7 @@ describe API::Settings, 'Settings' do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Hash expect(json_response).to be_an Hash
expect(json_response['default_projects_limit']).to eq(42) expect(json_response['default_projects_limit']).to eq(42)
expect(json_response['password_authentication_enabled']).to be_truthy expect(json_response['password_authentication_enabled_for_web']).to be_truthy
expect(json_response['repository_storages']).to eq(['default']) expect(json_response['repository_storages']).to eq(['default'])
expect(json_response['koding_enabled']).to be_falsey expect(json_response['koding_enabled']).to be_falsey
expect(json_response['koding_url']).to be_nil expect(json_response['koding_url']).to be_nil
...@@ -37,7 +37,7 @@ describe API::Settings, 'Settings' do ...@@ -37,7 +37,7 @@ describe API::Settings, 'Settings' do
it "updates application settings" do it "updates application settings" do
put api("/application/settings", admin), put api("/application/settings", admin),
default_projects_limit: 3, default_projects_limit: 3,
password_authentication_enabled: false, password_authentication_enabled_for_web: false,
repository_storages: ['custom'], repository_storages: ['custom'],
koding_enabled: true, koding_enabled: true,
koding_url: 'http://koding.example.com', koding_url: 'http://koding.example.com',
...@@ -58,7 +58,7 @@ describe API::Settings, 'Settings' do ...@@ -58,7 +58,7 @@ describe API::Settings, 'Settings' do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(json_response['default_projects_limit']).to eq(3) expect(json_response['default_projects_limit']).to eq(3)
expect(json_response['password_authentication_enabled']).to be_falsey expect(json_response['password_authentication_enabled_for_web']).to be_falsey
expect(json_response['repository_storages']).to eq(['custom']) expect(json_response['repository_storages']).to eq(['custom'])
expect(json_response['koding_enabled']).to be_truthy expect(json_response['koding_enabled']).to be_truthy
expect(json_response['koding_url']).to eq('http://koding.example.com') expect(json_response['koding_url']).to eq('http://koding.example.com')
......
...@@ -28,11 +28,11 @@ describe API::V3::Settings, 'Settings' do ...@@ -28,11 +28,11 @@ describe API::V3::Settings, 'Settings' do
it "updates application settings" do it "updates application settings" do
put v3_api("/application/settings", admin), put v3_api("/application/settings", admin),
default_projects_limit: 3, password_authentication_enabled: false, repository_storage: 'custom', koding_enabled: true, koding_url: 'http://koding.example.com', default_projects_limit: 3, password_authentication_enabled_for_web: false, repository_storage: 'custom', koding_enabled: true, koding_url: 'http://koding.example.com',
plantuml_enabled: true, plantuml_url: 'http://plantuml.example.com' plantuml_enabled: true, plantuml_url: 'http://plantuml.example.com'
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(json_response['default_projects_limit']).to eq(3) expect(json_response['default_projects_limit']).to eq(3)
expect(json_response['password_authentication_enabled']).to be_falsey expect(json_response['password_authentication_enabled_for_web']).to be_falsey
expect(json_response['repository_storage']).to eq('custom') expect(json_response['repository_storage']).to eq('custom')
expect(json_response['repository_storages']).to eq(['custom']) expect(json_response['repository_storages']).to eq(['custom'])
expect(json_response['koding_enabled']).to be_truthy expect(json_response['koding_enabled']).to be_truthy
......
...@@ -463,7 +463,7 @@ describe 'Git HTTP requests' do ...@@ -463,7 +463,7 @@ describe 'Git HTTP requests' do
context 'when internal auth is disabled' do context 'when internal auth is disabled' do
before do before do
allow_any_instance_of(ApplicationSetting).to receive(:password_authentication_enabled?) { false } allow_any_instance_of(ApplicationSetting).to receive(:password_authentication_enabled_for_git?) { false }
end end
it 'rejects pulls with personal access token error message' do it 'rejects pulls with personal access token error message' do
......
...@@ -105,7 +105,7 @@ describe JwtController do ...@@ -105,7 +105,7 @@ describe JwtController do
context 'when internal auth is disabled' do context 'when internal auth is disabled' do
it 'rejects the authorization attempt with personal access token message' do it 'rejects the authorization attempt with personal access token message' do
allow_any_instance_of(ApplicationSetting).to receive(:password_authentication_enabled?) { false } allow_any_instance_of(ApplicationSetting).to receive(:password_authentication_enabled_for_git?) { false }
get '/jwt/auth', parameters, headers get '/jwt/auth', parameters, headers
expect(response).to have_gitlab_http_status(401) expect(response).to have_gitlab_http_status(401)
......
...@@ -8,7 +8,11 @@ RSpec::Matchers.define :have_gitlab_http_status do |expected| ...@@ -8,7 +8,11 @@ RSpec::Matchers.define :have_gitlab_http_status do |expected|
end end
failure_message do |actual| failure_message do |actual|
# actual can be either an ActionDispatch::TestResponse (which uses #response_code)
# or a Capybara::Session (which uses #status_code)
response_code = actual.try(:response_code) || actual.try(:status_code)
"expected the response to have status code #{expected.inspect}" \ "expected the response to have status code #{expected.inspect}" \
" but it was #{actual.response_code}. The response was: #{actual.body}" " but it was #{response_code}. The response was: #{actual.body}"
end 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