Merge pull request #5437 from AntonKhorev/user-status-resource

Use resourceful route for user status
This commit is contained in:
Andy Allan 2025-01-17 17:55:02 +00:00 committed by GitHub
commit 4370fe45ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 141 additions and 129 deletions

View file

@ -67,7 +67,8 @@ class Ability
can [:hide, :unhide], [DiaryEntry, DiaryComment]
can [:read, :resolve, :ignore, :reopen], Issue
can :create, IssueComment
can [:set_status, :destroy], User
can [:update], :user_status
can [:read, :update], :users_list
can [:create, :destroy], UserRole
end

View file

@ -0,0 +1,36 @@
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"
@user.soft_destroy! if params[:event] == "soft_destroy" # destroy a user, marking them as deleted and removing personal data
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

View file

@ -14,7 +14,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
@ -98,13 +97,6 @@ class UsersController < ApplicationController
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 go_public
current_user.data_public = true
current_user.save
@ -112,18 +104,6 @@ class UsersController < ApplicationController
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
@ -237,14 +217,6 @@ class UsersController < ApplicationController
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

View file

@ -161,50 +161,48 @@
</small>
</div>
<% if can?(:set_status, User) || can?(:destroy, User) %>
<% if can?(:update, :user_status) %>
<nav class='secondary-actions'>
<ul class='clearfix'>
<% if can? :set_status, User %>
<% 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 @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, :event => "soft_destroy"), :method => :put, :data => { :confirm => t(".confirm") } %>
</li>
<% end %>
</ul>

View file

@ -266,15 +266,15 @@ OpenStreetMap::Application.routes.draw do
# user pages
get "/user/terms", :to => redirect(:path => "/account/terms")
resources :users, :path => "user", :param => :display_name, :only => [:new, :create, :show, :destroy] do
resources :users, :path => "user", :param => :display_name, :only => [:new, :create, :show] do
resource :role, :controller => "user_roles", :path => "roles/:role", :only => [:create, :destroy]
scope :module => :users do
resource :issued_blocks, :path => "blocks_by", :only => :show
resource :received_blocks, :path => "blocks", :only => [:show, :edit, :destroy]
resource :status, :only => :update
end
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] do
scope :module => :accounts do

View file

@ -0,0 +1,64 @@
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" }
)
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
put user_status_path(user, :event => "soft_destroy")
assert_response :forbidden
# Now try as a normal user
session_for(user)
put user_status_path(user, :event => "soft_destroy")
assert_redirected_to :controller => "/errors", :action => :forbidden
# Finally try as an administrator
session_for(create(:administrator_user))
put user_status_path(user, :event => "soft_destroy")
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

View file

@ -28,15 +28,6 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
{ :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
@ -332,56 +323,6 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
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