2024-04-29 00:17:15 +02:00
# frozen_string_literal: true
2018-11-19 21:18:17 +01:00
class API :: V2 :: BaseController < ApplicationController
2024-06-06 16:28:35 +02:00
# This controller is used for API v2 through api endpoint (/api/v2/graphql)
# and through the web interface (/graphql). When used through the web interface,
# we use connected administrateur to authenticate the request. We want CSRF protection
# for the web interface, but not for the API endpoint. :null_session means that when the
# request is not CSRF protected, we will not raise an exception,
# but we will provide the controller with an empty session.
protect_from_forgery with : :null_session
2022-09-28 12:40:44 +02:00
skip_before_action :setup_tracking
2023-08-03 15:38:51 +02:00
before_action :authenticate_from_token
2023-12-21 14:00:07 +01:00
before_action :ensure_authorized_network , if : - > { @api_token . present? }
2024-01-17 09:31:21 +01:00
before_action :ensure_token_is_not_expired , if : - > { @api_token . present? }
2024-07-22 11:11:06 +02:00
before_action :allow_only_persisted_queries , if : - > { @api_token . blank? }
2018-11-19 21:18:17 +01:00
2023-10-17 12:00:16 +02:00
before_action do
Current . browser = 'api'
end
2018-11-19 21:18:17 +01:00
private
def context
2023-08-03 15:38:51 +02:00
if @api_token . present?
@api_token . context
2022-10-03 18:08:03 +02:00
# web interface (/graphql) give current_administrateur
elsif current_administrateur . present?
2023-08-03 16:33:30 +02:00
graphql_web_interface_context
else
unauthenticated_request_context
2022-09-28 12:40:44 +02:00
end
end
2023-08-03 16:33:30 +02:00
def graphql_web_interface_context
{
administrateur_id : current_administrateur . id ,
procedure_ids : current_administrateur . procedure_ids ,
write_access : true
}
end
def unauthenticated_request_context
{
administrateur_id : nil ,
procedure_ids : [ ] ,
write_access : false
}
end
2023-08-03 15:38:51 +02:00
def authenticate_from_token
@api_token = authenticate_with_http_token { | t , _o | APIToken . authenticate ( t ) }
2022-11-30 10:14:23 +01:00
2023-08-03 15:38:51 +02:00
if @api_token . present?
@api_token . touch ( :last_v2_authenticated_at )
2023-12-21 15:58:03 +01:00
@api_token . store_new_ip ( request . remote_ip )
2023-08-03 15:38:51 +02:00
@current_user = @api_token . administrateur . user
2023-11-02 11:36:03 +01:00
Current . user = @current_user
2022-09-28 12:40:44 +02:00
end
end
2023-12-21 14:00:07 +01:00
2024-07-22 11:11:06 +02:00
def allow_only_persisted_queries
if params [ :queryId ] . blank?
render json : graphql_error ( 'Without a token, only persisted queries are allowed' , :forbidden ) , status : :forbidden
end
end
2023-12-21 14:00:07 +01:00
def ensure_authorized_network
if @api_token . forbidden_network? ( request . remote_ip )
address = IPAddr . new ( request . remote_ip )
2024-07-22 11:04:51 +02:00
render json : graphql_error ( " Request issued from a forbidden network. Add #{ address . to_string } / #{ address . prefix } to your allowed adresses in your /profil " , :forbidden ) , status : :forbidden
2023-12-21 14:00:07 +01:00
end
end
2024-01-17 09:31:21 +01:00
def ensure_token_is_not_expired
if @api_token . expired?
2024-07-22 11:04:51 +02:00
render json : graphql_error ( 'Token expired' , :unauthorized ) , status : :unauthorized
2024-01-17 09:31:21 +01:00
end
end
2024-07-22 11:04:51 +02:00
def graphql_error ( message , code , exception_id : nil , backtrace : nil )
{
errors : [
{
message : ,
extensions : { code : , exception_id : , backtrace : } . compact
}
] ,
data : nil
}
end
2018-11-19 21:18:17 +01:00
end