1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-24 23:59:40 +02:00

Impersonation (#1325)

* Initial impersonation

* Impersonation audit

* Keep super admin separate

* Remove vscode settings

* Comment cleanup

* Comment out impersonation fixtures for now

* Remove unused controlelr

* Add impersonation testing (#1326)

* Add impersonation testing

* Remove unused method

* Update schema.rb

* Update brakeman

---------

Co-authored-by: Zach Gollwitzer <zach@maybe.co>
This commit is contained in:
Josh Pigford 2024-10-18 11:26:58 -05:00 committed by GitHub
parent 4a3685f503
commit c7c281073f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 477 additions and 16 deletions

View file

@ -1,5 +1,5 @@
class ApplicationController < ActionController::Base
include Localize, AutoSync, Authentication, Invitable, SelfHostable, StoreLocation
include Localize, AutoSync, Authentication, Invitable, SelfHostable, StoreLocation, Impersonatable
include Pagy::Backend
private

View file

@ -14,7 +14,7 @@ module Authentication
private
def authenticate_user!
if session_record = Session.find_by_id(cookies.signed[:session_token])
if session_record = find_session_by_cookie
Current.session = session_record
else
if self_hosted_first_login?
@ -25,6 +25,10 @@ module Authentication
end
end
def find_session_by_cookie
Session.find_by(id: cookies.signed[:session_token])
end
def create_session_for(user)
session = user.sessions.create!
cookies.signed.permanent[:session_token] = { value: session.id, httponly: true }

View file

@ -0,0 +1,21 @@
module Impersonatable
extend ActiveSupport::Concern
included do
after_action :create_impersonation_session_log
end
private
def create_impersonation_session_log
return unless Current.session&.active_impersonator_session.present?
Current.session.active_impersonator_session.logs.create!(
controller: controller_name,
action: action_name,
path: request.fullpath,
method: request.method,
ip_address: request.ip,
user_agent: request.user_agent
)
end
end

View file

@ -0,0 +1,58 @@
class ImpersonationSessionsController < ApplicationController
before_action :require_super_admin!, only: [ :create, :join, :leave ]
before_action :set_impersonation_session, only: [ :approve, :reject, :complete ]
def create
Current.true_user.request_impersonation_for(session_params[:impersonated_id])
redirect_to root_path, notice: t(".success")
end
def join
@impersonation_session = Current.true_user.impersonator_support_sessions.find_by(id: params[:impersonation_session_id])
Current.session.update!(active_impersonator_session: @impersonation_session)
redirect_to root_path, notice: t(".success")
end
def leave
Current.session.update!(active_impersonator_session: nil)
redirect_to root_path, notice: t(".success")
end
def approve
raise_unauthorized! unless @impersonation_session.impersonated == Current.true_user
@impersonation_session.approve!
redirect_to root_path, notice: t(".success")
end
def reject
raise_unauthorized! unless @impersonation_session.impersonated == Current.true_user
@impersonation_session.reject!
redirect_to root_path, notice: t(".success")
end
def complete
@impersonation_session.complete!
redirect_to root_path, notice: t(".success")
end
private
def session_params
params.require(:impersonation_session).permit(:impersonated_id)
end
def set_impersonation_session
@impersonation_session =
Current.true_user.impersonated_support_sessions.find_by(id: params[:id]) ||
Current.true_user.impersonator_support_sessions.find_by(id: params[:id])
end
def require_super_admin!
raise_unauthorized! unless Current.true_user&.super_admin?
end
def raise_unauthorized!
raise ActionController::RoutingError.new("Not Found")
end
end