Skip to content

Commit

Permalink
Use resourceful route for user status
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonKhorev committed Dec 23, 2024
1 parent 99af52b commit 0764432
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 100 deletions.
3 changes: 2 additions & 1 deletion app/abilities/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ def initialize(user)
can [:hide, :unhide], [DiaryEntry, DiaryComment]
can [:read, :resolve, :ignore, :reopen], Issue
can :create, IssueComment
can [:set_status, :destroy], User

can [:update, :destroy], :user_status
can [:read, :update], :users_list
can [:create, :destroy], UserRole
end
Expand Down
42 changes: 42 additions & 0 deletions app/controllers/users/statuses_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module Users
class StatusesController < ApplicationController
layout "site"

before_action :authorize_web
before_action :set_locale
before_action :check_database_readable

authorize_resource :class => :user_status

before_action :lookup_user_by_name

##
# sets a user's status
def update
@user.activate! if params[:event] == "activate"
@user.confirm! if params[:event] == "confirm"
@user.unconfirm! if params[:event] == "unconfirm"
@user.hide! if params[:event] == "hide"
@user.unhide! if params[:event] == "unhide"
@user.unsuspend! if params[:event] == "unsuspend"
redirect_to user_path(params[:user_display_name])
end

##
# destroy a user, marking them as deleted and removing personal data
def destroy
@user.soft_destroy!
redirect_to user_path(params[:user_display_name])
end

private

##
# ensure that there is a "user" instance variable
def lookup_user_by_name
@user = User.find_by!(:display_name => params[:user_display_name])
rescue ActiveRecord::RecordNotFound
redirect_to user_path(params[:user_display_name]) unless @user
end
end
end
28 changes: 0 additions & 28 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class UsersController < ApplicationController

before_action :check_database_writable, :only => [:new, :go_public]
before_action :require_cookies, :only => [:new]
before_action :lookup_user_by_name, :only => [:set_status, :destroy]

allow_thirdparty_images :only => :show
allow_social_login :only => :new
Expand Down Expand Up @@ -82,13 +81,6 @@ def create
end
end

##
# destroy a user, marking them as deleted and removing personal data
def destroy
@user.soft_destroy!
redirect_to user_path(:display_name => params[:display_name])
end

def terms
@legale = params[:legale] || OSM.ip_to_country(request.remote_ip) || Settings.default_legale
@text = OSM.legal_text_for_country(@legale)
Expand Down Expand Up @@ -147,18 +139,6 @@ def go_public
redirect_to edit_account_path
end

##
# sets a user's status
def set_status
@user.activate! if params[:event] == "activate"
@user.confirm! if params[:event] == "confirm"
@user.unconfirm! if params[:event] == "unconfirm"
@user.hide! if params[:event] == "hide"
@user.unhide! if params[:event] == "unhide"
@user.unsuspend! if params[:event] == "unsuspend"
redirect_to user_path(:display_name => params[:display_name])
end

##
# omniauth success callback
def auth_success
Expand Down Expand Up @@ -289,14 +269,6 @@ def welcome_options(referer = nil)
end
end

##
# ensure that there is a "user" instance variable
def lookup_user_by_name
@user = User.find_by(:display_name => params[:display_name])
rescue ActiveRecord::RecordNotFound
redirect_to :action => "view", :display_name => params[:display_name] unless @user
end

##
# return permitted user parameters
def user_params
Expand Down
20 changes: 10 additions & 10 deletions app/views/users/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -161,50 +161,50 @@
</small>
</div>

<% if can?(:set_status, User) || can?(:destroy, User) %>
<% if can?(:update, :user_status) || can?(:destroy, User) %>
<nav class='secondary-actions'>
<ul class='clearfix'>
<% if can? :set_status, User %>
<% if can? :update, :user_status %>
<% if @user.may_activate? %>
<li>
<%= link_to t(".activate_user"), set_status_user_path(:event => "activate", :display_name => @user.display_name), :method => :post, :data => { :confirm => t(".confirm") } %>
<%= link_to t(".activate_user"), user_status_path(@user, :event => "activate"), :method => :put, :data => { :confirm => t(".confirm") } %>
</li>
<% end %>

<% if @user.may_unsuspend? %>
<li>
<%= link_to t(".unsuspend_user"), set_status_user_path(:event => "unsuspend", :display_name => @user.display_name), :method => :post, :data => { :confirm => t(".confirm") } %>
<%= link_to t(".unsuspend_user"), user_status_path(@user, :event => "unsuspend"), :method => :put, :data => { :confirm => t(".confirm") } %>
</li>
<% end %>

<% if @user.may_confirm? %>
<li>
<%= link_to t(".confirm_user"), set_status_user_path(:event => "confirm", :display_name => @user.display_name), :method => :post, :data => { :confirm => t(".confirm") } %>
<%= link_to t(".confirm_user"), user_status_path(@user, :event => "confirm"), :method => :put, :data => { :confirm => t(".confirm") } %>
</li>
<% end %>

<% if @user.may_unconfirm? %>
<li>
<%= link_to t(".unconfirm_user"), set_status_user_path(:event => "unconfirm", :display_name => @user.display_name), :method => :post, :data => { :confirm => t(".confirm") } %>
<%= link_to t(".unconfirm_user"), user_status_path(@user, :event => "unconfirm"), :method => :put, :data => { :confirm => t(".confirm") } %>
</li>
<% end %>

<% if @user.may_hide? %>
<li>
<%= link_to t(".hide_user"), set_status_user_path(:event => "hide", :display_name => @user.display_name), :method => :post, :data => { :confirm => t(".confirm") } %>
<%= link_to t(".hide_user"), user_status_path(@user, :event => "hide"), :method => :put, :data => { :confirm => t(".confirm") } %>
</li>
<% end %>

<% if @user.may_unhide? %>
<li>
<%= link_to t(".unhide_user"), set_status_user_path(:event => "unhide", :display_name => @user.display_name), :method => :post, :data => { :confirm => t(".confirm") } %>
<%= link_to t(".unhide_user"), user_status_path(@user, :event => "unhide"), :method => :put, :data => { :confirm => t(".confirm") } %>
</li>
<% end %>
<% end %>

<% if can?(:destroy, User) && @user.may_soft_destroy? %>
<% if can?(:destroy, :user_status) && @user.may_soft_destroy? %>
<li>
<%= link_to t(".delete_user"), user_path(:display_name => @user.display_name), :method => :delete, :data => { :confirm => t(".confirm") } %>
<%= link_to t(".delete_user"), user_status_path(@user), :method => :delete, :data => { :confirm => t(".confirm") } %>
</li>
<% end %>
</ul>
Expand Down
4 changes: 2 additions & 2 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,11 @@
post "/diary_comments/:comment/unhide" => "diary_comments#unhide", :comment => /\d+/, :as => :unhide_diary_comment

# user pages
resources :users, :path => "user", :param => :display_name, :only => [:show, :destroy] do
resources :users, :path => "user", :param => :display_name, :only => :show do
resource :role, :controller => "user_roles", :path => "roles/:role", :only => [:create, :destroy]
resource :status, :module => :users, :only => [:update, :destroy]
end
get "/user/:display_name/account", :to => redirect(:path => "/account/edit")
post "/user/:display_name/set_status" => "users#set_status", :as => :set_status_user

resource :account, :only => [:edit, :update, :destroy]

Expand Down
68 changes: 68 additions & 0 deletions test/controllers/users/statuses_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
require "test_helper"

module Users
class StatusesControllerTest < ActionDispatch::IntegrationTest
##
# test all routes which lead to this controller
def test_routes
assert_routing(
{ :path => "/user/username/status", :method => :put },
{ :controller => "users/statuses", :action => "update", :user_display_name => "username" }
)
assert_routing(
{ :path => "/user/username/status", :method => :delete },
{ :controller => "users/statuses", :action => "destroy", :user_display_name => "username" }
)
end

def test_update
user = create(:user)

# Try without logging in
put user_status_path(user, :event => "confirm")
assert_response :forbidden

# Now try as a normal user
session_for(user)
put user_status_path(user, :event => "confirm")
assert_redirected_to :controller => "/errors", :action => :forbidden

# Finally try as an administrator
session_for(create(:administrator_user))
put user_status_path(user, :event => "confirm")
assert_redirected_to user_path(user)
assert_equal "confirmed", User.find(user.id).status
end

def test_destroy
user = create(:user, :home_lat => 12.1, :home_lon => 12.1, :description => "test")

# Try without logging in
delete user_status_path(user)
assert_response :forbidden

# Now try as a normal user
session_for(user)
delete user_status_path(user)
assert_redirected_to :controller => "/errors", :action => :forbidden

# Finally try as an administrator
session_for(create(:administrator_user))
delete user_status_path(user)
assert_redirected_to user_path(user)

# Check that the user was deleted properly
user.reload
assert_equal "user_#{user.id}", user.display_name
assert_equal "", user.description
assert_nil user.home_lat
assert_nil user.home_lon
assert_not user.avatar.attached?
assert_not user.email_valid
assert_nil user.new_email
assert_nil user.auth_provider
assert_nil user.auth_uid
assert_equal "deleted", user.status
end
end
end
59 changes: 0 additions & 59 deletions test/controllers/users_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,6 @@ def test_routes
{ :path => "/user/username", :method => :get },
{ :controller => "users", :action => "show", :display_name => "username" }
)

assert_routing(
{ :path => "/user/username/set_status", :method => :post },
{ :controller => "users", :action => "set_status", :display_name => "username" }
)
assert_routing(
{ :path => "/user/username", :method => :delete },
{ :controller => "users", :action => "destroy", :display_name => "username" }
)
end

# The user creation page loads
Expand Down Expand Up @@ -404,56 +395,6 @@ def test_terms_not_agreed
end
end

def test_set_status
user = create(:user)

# Try without logging in
post set_status_user_path(user), :params => { :event => "confirm" }
assert_response :forbidden

# Now try as a normal user
session_for(user)
post set_status_user_path(user), :params => { :event => "confirm" }
assert_redirected_to :controller => :errors, :action => :forbidden

# Finally try as an administrator
session_for(create(:administrator_user))
post set_status_user_path(user), :params => { :event => "confirm" }
assert_redirected_to :action => :show, :display_name => user.display_name
assert_equal "confirmed", User.find(user.id).status
end

def test_destroy
user = create(:user, :home_lat => 12.1, :home_lon => 12.1, :description => "test")

# Try without logging in
delete user_path(user)
assert_response :forbidden

# Now try as a normal user
session_for(user)
delete user_path(user)
assert_redirected_to :controller => :errors, :action => :forbidden

# Finally try as an administrator
session_for(create(:administrator_user))
delete user_path(user)
assert_redirected_to :action => :show, :display_name => user.display_name

# Check that the user was deleted properly
user.reload
assert_equal "user_#{user.id}", user.display_name
assert_equal "", user.description
assert_nil user.home_lat
assert_nil user.home_lon
assert_not user.avatar.attached?
assert_not user.email_valid
assert_nil user.new_email
assert_nil user.auth_provider
assert_nil user.auth_uid
assert_equal "deleted", user.status
end

def test_auth_failure_callback
get auth_failure_path
assert_redirected_to login_path
Expand Down

0 comments on commit 0764432

Please sign in to comment.