From 599a6d78737237e806dcfe0105b8b81dc696b71f Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 2 Mar 2016 17:48:49 -0500 Subject: Allow the initial admin to set a password Closes #1980 --- app/controllers/passwords_controller.rb | 8 +++++ app/controllers/sessions_controller.rb | 18 +++++++++++ db/fixtures/production/001_admin.rb | 55 ++++++++++++++++++--------------- spec/features/login_spec.rb | 26 ++++++++++++++++ 4 files changed, 82 insertions(+), 25 deletions(-) diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index f74daff3bd0..a8575e037e4 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -23,6 +23,14 @@ class PasswordsController < Devise::PasswordsController end end + def update + super do |resource| + if resource.valid? && resource.require_password? + resource.update_attribute(:password_automatically_set, false) + end + end + end + protected def resource_from_email diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 44eb58e418b..65677a3dd3c 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -4,8 +4,10 @@ class SessionsController < Devise::SessionsController skip_before_action :check_2fa_requirement, only: [:destroy] + prepend_before_action :check_initial_setup, only: [:new] prepend_before_action :authenticate_with_two_factor, only: [:create] prepend_before_action :store_redirect_path, only: [:new] + before_action :auto_sign_in_with_provider, only: [:new] before_action :load_recaptcha @@ -33,6 +35,22 @@ class SessionsController < Devise::SessionsController private + # Handle an "initial setup" state, where there's only one user, it's an admin, + # and they require a password change. + def check_initial_setup + return unless User.count == 1 + + user = User.admins.last + + return unless user && user.require_password? + + token = user.generate_reset_token + user.save + + redirect_to edit_user_password_path(reset_password_token: token), + notice: "Please create a password for your new account." + end + def user_params params.require(:user).permit(:login, :password, :remember_me, :otp_attempt) end diff --git a/db/fixtures/production/001_admin.rb b/db/fixtures/production/001_admin.rb index 308b0528c9b..78746c83225 100644 --- a/db/fixtures/production/001_admin.rb +++ b/db/fixtures/production/001_admin.rb @@ -1,33 +1,38 @@ +user_args = { + email: ENV['GITLAB_ROOT_EMAIL'].presence || 'admin@example.com', + name: 'Administrator', + username: 'root', + admin: true +} + if ENV['GITLAB_ROOT_PASSWORD'].blank? - password = '5iveL!fe' - expire_time = Time.now + user_args[:password_automatically_set] = true + user_args[:force_random_password] = true else - password = ENV['GITLAB_ROOT_PASSWORD'] - expire_time = nil + user_args[:password] = ENV['GITLAB_ROOT_PASSWORD'] end -email = ENV['GITLAB_ROOT_EMAIL'].presence || 'admin@example.com' - -admin = User.create( - email: email, - name: "Administrator", - username: 'root', - password: password, - password_expires_at: expire_time, - theme_id: Gitlab::Themes::APPLICATION_DEFAULT - -) +user = User.new(user_args) +user.skip_confirmation! -admin.projects_limit = 10000 -admin.admin = true -admin.save! -admin.confirm +if user.save + puts "Administrator account created:".green + puts + puts "login: root".green -if admin.valid? -puts %Q[ -Administrator account created: + if user_args.key?(:password) + puts "password: #{user_args[:password]}".green + else + puts "password: You'll be prompted to create one on your first visit.".green + end + puts +else + puts "Could not create the default administrator account:".red + puts + user.errors.full_messages.map do |message| + puts "--> #{message}".red + end + puts -login.........root -password......#{password} -] + exit 1 end diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb index dac9205449a..4433ef2d6f1 100644 --- a/spec/features/login_spec.rb +++ b/spec/features/login_spec.rb @@ -1,6 +1,32 @@ require 'spec_helper' feature 'Login', feature: true do + describe 'initial login after setup' do + it 'allows the initial admin to create a password' do + # This behavior is dependent on there only being one user + User.delete_all + + user = create(:admin, password_automatically_set: true) + + visit root_path + expect(current_path).to eq edit_user_password_path + expect(page).to have_content('Please create a password for your new account.') + + fill_in 'user_password', with: 'password' + fill_in 'user_password_confirmation', with: 'password' + click_button 'Change your password' + + expect(current_path).to eq new_user_session_path + expect(page).to have_content(I18n.t('devise.passwords.updated_not_active')) + + fill_in 'user_login', with: user.username + fill_in 'user_password', with: 'password' + click_button 'Sign in' + + expect(current_path).to eq root_path + end + end + describe 'with two-factor authentication' do context 'with valid username/password' do let(:user) { create(:user, :two_factor) } -- cgit v1.2.1