52 lines
1.9 KiB
Ruby
52 lines
1.9 KiB
Ruby
module AccessTokenAuthHelper
|
|
BOT_ACCESSIBLE_ENDPOINTS = {
|
|
'api/v1/accounts/conversations' => %w[show toggle_status toggle_typing_status toggle_priority create update custom_attributes],
|
|
'api/v1/accounts/conversations/messages' => ['create'],
|
|
'api/v1/accounts/conversations/assignments' => ['create'],
|
|
'api/v1/accounts/conversations/labels' => %w[index create]
|
|
}.freeze
|
|
|
|
def ensure_access_token
|
|
token = request.headers[:api_access_token] || request.headers[:HTTP_API_ACCESS_TOKEN]
|
|
@access_token = AccessToken.find_by(token: token) if token.present?
|
|
end
|
|
|
|
def authenticate_access_token!
|
|
ensure_access_token
|
|
render_unauthorized('Invalid Access Token') && return if @access_token.blank?
|
|
|
|
# NOTE: This ensures that current_user is set and available for the rest of the controller actions
|
|
@resource = @access_token.owner
|
|
Current.user = @resource if allowed_current_user_type?(@resource)
|
|
end
|
|
|
|
def allowed_current_user_type?(resource)
|
|
return true if resource.is_a?(User)
|
|
return true if resource.is_a?(AgentBot)
|
|
|
|
false
|
|
end
|
|
|
|
def validate_bot_access_token!
|
|
return if Current.user.is_a?(User)
|
|
return if @resource.is_a?(AgentBot) && agent_bot_accessible?
|
|
|
|
render_unauthorized('Access to this endpoint is not authorized for bots')
|
|
end
|
|
|
|
def agent_bot_accessible?
|
|
BOT_ACCESSIBLE_ENDPOINTS.fetch(params[:controller], []).include?(params[:action])
|
|
end
|
|
|
|
# Blocks read-only access tokens from reaching write endpoints that live outside
|
|
# Api::BaseController (e.g. controllers inheriting from ActiveStorage). Resolves
|
|
# the token directly since these controllers skip the Api::BaseController chain.
|
|
def prevent_read_only_access_token!
|
|
ensure_access_token
|
|
return unless @access_token&.scope == 'read_only'
|
|
|
|
render json: { error: 'This access token is read-only and cannot perform write operations.' },
|
|
status: :forbidden
|
|
end
|
|
end
|