Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block password reset for Globus confined users #1393

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
8 changes: 4 additions & 4 deletions BrainPortal/app/controllers/nh_users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def edit #:nodoc:
def change_password #:nodoc:
@user = current_user
if user_must_link_to_oidc?(@user)
cb_error "Your account can only authenticate with Globus identities.", :redirect => { :action => :myaccount }
cb_error "Your account can only authenticate with OpenID identities (such as Globus).", :redirect => { :action => :myaccount }
end
end

Expand All @@ -87,9 +87,9 @@ def update
attr_to_update.delete(:zenodo_sandbox_token) if attr_to_update[:zenodo_sandbox_token].blank?
attr_to_update.delete(:zenodo_main_token) if attr_to_update[:zenodo_main_token].blank?

# Do not update password if user must use globus
if user_must_link_to_oidc?(@user)
flash[:error] = "You cannot change the password for your account." if attr_to_update[:password].present?
# Do not update password if user must use globus (or other oidc)
if user_must_link_to_oidc?(@user) && attr_to_update[:password].present?
flash[:error] = "You cannot change the password for your account because you should use OpenID." if attr_to_update[:password].present?
attr_to_update.delete(:password)
attr_to_update.delete(:password_confirmation)
end
Expand Down
10 changes: 10 additions & 0 deletions BrainPortal/app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,16 @@ def send_password #:nodoc:
@user = User.where( :login => params[:login], :email => params[:email] ).first

if @user
if user_must_link_to_oidc?(@user)
contact = RemoteResource.current_resource.support_email.presence || User.admin.email.presence || "the support staff"
wipe_user_password_after_oidc_link("password-rest", @user) # for legacy or erroneously set users
flash[:error] = "Your account can only authenticate with OpenID identities. Thus you are not allowed to use or reset password. Please contact #{contact} for help."
respond_to do |format|
format.html { redirect_to login_path }
format.any { head :unauthorized }
end
return
end
if @user.account_locked?
contact = RemoteResource.current_resource.support_email.presence || User.admin.email.presence || "the support staff"
flash[:error] = "This account is locked, please write to #{contact} to get this account unlocked."
Expand Down
5 changes: 3 additions & 2 deletions BrainPortal/lib/globus_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ def user_must_link_to_oidc?(user)
end

def wipe_user_password_after_oidc_link(oidc, user)
user.update_attribute(:crypted_password, "Wiped-By-#{oidc.name}-Link-" + User.random_string)
user.update_attribute(:salt , "Wiped-By-#{oidc.name}-Link-" + User.random_string)
wipe_by = oidc.is_a?(String) ? "Wiped-By-#{oidc}-Link-" : "Wiped-By-#{oidc.name}-Link-"
user.update_attribute(:crypted_password, wipe_by + User.random_string)
user.update_attribute(:salt , wipe_by + User.random_string)
user.update_attribute(:password_reset , false)
end

Expand Down
18 changes: 17 additions & 1 deletion BrainPortal/spec/controllers/users_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,22 @@
expect(assigns[:user].password).not_to eq(user.password)
end

context "when the account must use OIDC identification only" do

it "should display a message" do
allow(mock_user).to receive(:account_locked?).and_return(true)
allow(User).to receive_message_chain(:where, :first).and_return(mock_user)
post :send_password, params: {:login => user.login, :email => user.email}
expect(flash[:error]).to match(/OpenID/i)
end

end

context "when the account is locked" do

it "should display a message" do
allow(mock_user).to receive(:account_locked?).and_return(true)
allow(mock_user).to receive(:meta).and_return({ "allowed_globus_provider_names" => "" })
allow(User).to receive_message_chain(:where, :first).and_return(mock_user)
post :send_password, params: {:login => user.login, :email => user.email}
expect(flash[:error]).to match(/locked/i)
Expand All @@ -251,7 +263,11 @@
context "when reset fails" do

it "should display flash message about problem" do
mock_user = mock_model(User, :save => false, :account_locked? => false).as_null_object
mock_user = mock_model(User,
:save => false,
:account_locked? => false,
:meta => { "allowed_globus_provider_names" => "" }
).as_null_object
allow(User).to receive_message_chain(:where, :first).and_return(mock_user)
post :send_password
expect(flash[:error]).to match(/^Unable to reset password/)
Expand Down
Loading