Do not allow the user to mass assign their own password alongside other
parameters Much thanks to Breno Vitório (@brenu) for the report!
This commit is contained in:
parent
6ad4eb3be7
commit
1cfe0037f9
2 changed files with 37 additions and 29 deletions
|
|
@ -18,25 +18,17 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
password_changed = false
|
|
||||||
user_data = user_params
|
|
||||||
@user = current_user
|
@user = current_user
|
||||||
|
|
||||||
if user_data
|
if params[:change_password] && user_password_params
|
||||||
# change password
|
password_changed = change_password(user_password_params)
|
||||||
if params[:change_password]
|
return redirect_to new_user_session_path if password_changed
|
||||||
password_changed = change_password(user_data)
|
elsif user_params
|
||||||
else
|
update_user(user_params)
|
||||||
update_user(user_data)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if password_changed
|
set_email_preferences
|
||||||
redirect_to new_user_session_path
|
render :edit
|
||||||
else
|
|
||||||
set_email_preferences
|
|
||||||
render :edit
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_privacy_settings
|
def update_privacy_settings
|
||||||
|
|
@ -137,13 +129,9 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# rubocop:disable Metrics/MethodLength
|
|
||||||
def user_params
|
def user_params
|
||||||
params.fetch(:user).permit(
|
params.fetch(:user).permit(
|
||||||
:email,
|
:email,
|
||||||
:current_password,
|
|
||||||
:password,
|
|
||||||
:password_confirmation,
|
|
||||||
:language,
|
:language,
|
||||||
:color_theme,
|
:color_theme,
|
||||||
:disable_mail,
|
:disable_mail,
|
||||||
|
|
@ -157,7 +145,14 @@ class UsersController < ApplicationController
|
||||||
email_preferences: UserPreference::VALID_EMAIL_TYPES.map(&:to_sym)
|
email_preferences: UserPreference::VALID_EMAIL_TYPES.map(&:to_sym)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
# rubocop:enable Metrics/MethodLength
|
|
||||||
|
def user_password_params
|
||||||
|
params.fetch(:user).permit(
|
||||||
|
:current_password,
|
||||||
|
:password,
|
||||||
|
:password_confirmation
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def update_user(user_data)
|
def update_user(user_data)
|
||||||
if user_data[:email_preferences]
|
if user_data[:email_preferences]
|
||||||
|
|
@ -177,8 +172,8 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_password(user_data)
|
def change_password(password_params)
|
||||||
if @user.update_with_password(user_data)
|
if @user.update_with_password(password_params)
|
||||||
flash[:notice] = t("users.update.password_changed")
|
flash[:notice] = t("users.update.password_changed")
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -127,21 +127,34 @@ describe UsersController, :type => :controller do
|
||||||
expect(response).to render_template('edit')
|
expect(response).to render_template('edit')
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'password updates' do
|
describe "password updates" do
|
||||||
let(:password_params) do
|
let(:password_params) do
|
||||||
{:current_password => 'bluepin7',
|
{current_password: "bluepin7", password: "foobaz", password_confirmation: "foobaz"}
|
||||||
:password => "foobaz",
|
|
||||||
:password_confirmation => "foobaz"}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{id: @user.id, user: password_params, change_password: 'Change Password'}
|
{id: @user.id, user: password_params, change_password: "Change Password"}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(@controller).to receive(:current_user).and_return(@user)
|
||||||
|
allow(@user).to receive(:update_with_password)
|
||||||
|
allow(@user).to receive(:update_attributes)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "uses devise's update with password" do
|
it "uses devise's update with password" do
|
||||||
expect(@user).to receive(:update_with_password).with(hash_including(password_params))
|
|
||||||
allow(@controller).to receive(:current_user).and_return(@user)
|
|
||||||
put :update, params: params
|
put :update, params: params
|
||||||
|
|
||||||
|
expect(@user).to have_received(:update_with_password).with(hash_including(password_params))
|
||||||
|
expect(@user).not_to have_received(:update_attributes).with(hash_including(password_params))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not update the password without the change_password param" do
|
||||||
|
put :update, params: params.except(:change_password).deep_merge(user: {language: "de"})
|
||||||
|
|
||||||
|
expect(@user).not_to have_received(:update_with_password).with(hash_including(password_params))
|
||||||
|
expect(@user).not_to have_received(:update_attributes).with(hash_including(password_params))
|
||||||
|
expect(@user).to have_received(:update_attributes).with(hash_including(language: "de"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue