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

Allow users to edit and delete their account #2762

Merged
merged 8 commits into from
May 18, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions app/controllers/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ def update
end
end

def destroy
if current_user.valid_password?(params[:user][:current_password])
UserInfoScrubber.scrub_personal_info!(current_user)
Activation.disable_instances!([current_user])
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
set_flash_message! :notice, :destroyed
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
else
flash[:delete_alert] = "Incorrect password"
render action: :edit
end
end

private

def create_from_json
Expand Down
88 changes: 65 additions & 23 deletions app/views/devise/registrations/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,35 +1,77 @@
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<div class="form-container panel panel-default">
<div class="panel-body">
<h2>Update your profile</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>

<div><%= f.label :login %><br />
<%= f.text_field :login, autofocus: true %></div>
<div class="form-group">
<%= f.label :login %><br />
<%= f.text_field :login, autofocus: true, class: 'form-control' %>
</div>

<div><%= f.label :display_name %><br />
<%= f.text_field :display_name %></div>
<div class="form-group">
<%= f.label :display_name %><br />
<%= f.text_field :display_name, class: 'form-control' %>
</div>

<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div class="form-group">
<%= f.label :email %><br />
<%= f.email_field :email, class: 'form-control' %>

<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
</div>

<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "off" %></div>
<div class="form-group">
<div class="fieldset--password">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "off", class: 'form-control' %>
</div>

<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %></div>
<div class="fieldset--password">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control' %>
</div>
</div>

<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off" %></div>
<div class="form-group">
<div class="fieldset--password">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off", class: 'form-control' %>
</div>
</div>

<div><%= f.submit "Update" %></div>
<% end %>
<%= f.submit "Update", class: 'btn btn-primary' %>
<% end %>
</div>
</div>

<h3>Cancel my account</h3>
<hr>

<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
<div class="form-container" >
<h6>Cancel my account</h6>

<%= link_to "Back", :back %>
<p>
If for whatever reason you no longer wish to maintain an account with us,
you can delete it here. Please note that any classifications you've made on
projects, and any comments you've posted on our Talk discussion fora will
remain.
</p>

<% if flash[:delete_alert] %>
<p class="alert"><%= flash[:delete_alert] %></p>
<% end %>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :delete }) do |f| %>
<div class="form-group">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off", class: 'form-control' %>
</div>

<%= f.submit "Cancel my account", class: 'btn btn-danger' %>
<% end %>

<%= link_to "Back", :back %>
</div>
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
post "/users/sign_in" => "sessions#create", as: :user_session
delete "/users/sign_out" => "sessions#destroy", as: :destroy_user_session

get '/profile' => 'registrations#edit', as: :edit_user_registration
get "/users/sign_up" => "registrations#new", as: :new_user_registration
post "/users" => "registrations#create", as: :user_registration
put "/users" => "registrations#update"
delete "/users" => "registrations#destroy", as: :destroy_user_registration
end

get "unsubscribe", to: "emails#unsubscribe_via_token"
Expand Down
50 changes: 49 additions & 1 deletion spec/controllers/registrations_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@
end

describe "#create" do

context "with valid user attributes" do
let(:login) { "zoonser" }
let(:extra_attributes) { { login: login } }
Expand Down Expand Up @@ -339,5 +338,54 @@
end
end
end

describe '#destroy' do
let(:password) { 'password' }
let(:user) { create :user, password: password }
let(:user_id) { user.id }
let(:access_token) { create(:access_token, resource_owner_id: user_id) }

before(:each) do
sign_in user
request.env["HTTP_ACCEPT"] = "text/html"
end

context 'with correct password' do
it 'redirects to root' do
delete :destroy, user: {current_password: password}
expect(response).to redirect_to('/')
expect(flash[:notice]).to be_present
end

it 'deactivates the user' do
delete :destroy, user: {current_password: password}
expect(user.reload.active?).to be_falsey
end

it 'scrubs the users information' do
expect(UserInfoScrubber).to receive(:scrub_personal_info!).with(user)
delete :destroy, user: {current_password: password}
end
end

context 'with incorrect password' do
it 'renders error' do
delete :destroy, user: {current_password: 'wrong'}
expect(user.reload.active?).to be_truthy
expect(flash[:delete_alert]).to be_present
end
end

let(:authorized_user) { user }
let(:resource) { user }
let(:instances_to_disable) do
[resource] |
resource.projects |
resource.memberships |
resource.collections
end

# it_behaves_like "is deactivatable"
end
end
end