diff --git a/app/assets/images/pictograms/incognito-off.svg b/app/assets/images/pictograms/incognito-off.svg new file mode 100644 index 0000000..718453c --- /dev/null +++ b/app/assets/images/pictograms/incognito-off.svg @@ -0,0 +1 @@ + diff --git a/app/assets/images/pictograms/incognito.svg b/app/assets/images/pictograms/incognito.svg new file mode 100644 index 0000000..a06ebef --- /dev/null +++ b/app/assets/images/pictograms/incognito.svg @@ -0,0 +1 @@ + diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6205d12..029951e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,6 @@ class ApplicationController < ActionController::Base + helper_method :current_user_disguised? + before_action :authenticate_user! class AccessForbidden < StandardError @@ -6,6 +8,10 @@ class ApplicationController < ActionController::Base protected + def current_user_disguised? + session[:revert_to_id].present? + end + def after_sign_in_path_for(scope) if current_user.at_least(:admin) users_path diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 1305292..c026731 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,8 +1,13 @@ class UsersController < ApplicationController - before_action :find_user, only: [:show] - before_action do + helper_method :allow_disguise? + + before_action :find_user, only: [:show, :disguise] + before_action except: :revert do raise AccessForbidden unless current_user.at_least(:admin) end + before_action only: :revert do + raise AccessForbidden unless current_user_disguised? + end def index @users = User.all @@ -11,16 +16,35 @@ class UsersController < ApplicationController def show end + def disguise + raise ActionController::BadRequest unless allow_disguise?(@user) + session[:revert_to_id] = current_user.id + bypass_sign_in(@user) + redirect_to root_url + end + + def revert + @user = User.find(session.delete(:revert_to_id)) + bypass_sign_in(@user) + redirect_to users_url + end + # TODO: add #update to change user status - # TODO: add #become/#revert to change to user view # NOTE: limited actions availabe to :admin by design. Users are meant to # manage their accounts by themselves through registrations. In future :admin # may be allowed to sing-in as user and make changes there. + protected + + def allow_disguise?(user) + user&.confirmed? && (user != current_user) && !current_user_disguised? + end + private def find_user @user = User.find(params[:id]) end + end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 19a549b..1c875df 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -13,10 +13,15 @@