feature(api): add ensure_authorized_network for api_controller v1 and v2
This commit is contained in:
parent
6e5678d1c2
commit
d8bc38bc69
4 changed files with 103 additions and 0 deletions
|
@ -2,6 +2,7 @@ class API::V2::BaseController < ApplicationController
|
||||||
skip_forgery_protection if: -> { request.headers.key?('HTTP_AUTHORIZATION') }
|
skip_forgery_protection if: -> { request.headers.key?('HTTP_AUTHORIZATION') }
|
||||||
skip_before_action :setup_tracking
|
skip_before_action :setup_tracking
|
||||||
before_action :authenticate_from_token
|
before_action :authenticate_from_token
|
||||||
|
before_action :ensure_authorized_network, if: -> { @api_token.present? }
|
||||||
|
|
||||||
before_action do
|
before_action do
|
||||||
Current.browser = 'api'
|
Current.browser = 'api'
|
||||||
|
@ -46,4 +47,11 @@ class API::V2::BaseController < ApplicationController
|
||||||
Current.user = @current_user
|
Current.user = @current_user
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ensure_authorized_network
|
||||||
|
if @api_token.forbidden_network?(request.remote_ip)
|
||||||
|
address = IPAddr.new(request.remote_ip)
|
||||||
|
render json: { errors: ["request issued from a forbidden network. Add #{address.to_string}/#{address.prefix} to your allowed adresses in your /profil"] }, status: :forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
class APIController < ApplicationController
|
class APIController < ApplicationController
|
||||||
before_action :default_format_json
|
before_action :default_format_json
|
||||||
before_action :authenticate_from_token
|
before_action :authenticate_from_token
|
||||||
|
before_action :ensure_authorized_network, if: -> { @api_token.present? }
|
||||||
|
|
||||||
before_action do
|
before_action do
|
||||||
Current.browser = 'api'
|
Current.browser = 'api'
|
||||||
|
@ -33,4 +34,11 @@ class APIController < ApplicationController
|
||||||
@current_user = @api_token.administrateur.user
|
@current_user = @api_token.administrateur.user
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ensure_authorized_network
|
||||||
|
if @api_token.forbidden_network?(request.remote_ip)
|
||||||
|
address = IPAddr.new(request.remote_ip)
|
||||||
|
render json: { errors: ["request issued from a forbidden network. Add #{address.to_string}/#{address.prefix} to your allowed adresses in your /profil"] }, status: :forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
44
spec/controllers/api/v2/base_controller_spec.rb
Normal file
44
spec/controllers/api/v2/base_controller_spec.rb
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
describe API::V2::BaseController, type: :controller do
|
||||||
|
describe 'ensure_authorized_network' do
|
||||||
|
let(:admin) { create(:administrateur) }
|
||||||
|
let(:token_bearer_couple) { APIToken.generate(admin) }
|
||||||
|
let(:token) { token_bearer_couple[0] }
|
||||||
|
let(:bearer) { token_bearer_couple[1] }
|
||||||
|
let(:remote_ip) { '0.0.0.0' }
|
||||||
|
|
||||||
|
controller(API::V2::BaseController) { def fake_action = render(plain: 'Hello, World!') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
routes.draw { get 'fake_action' => 'api/v2/base#fake_action' }
|
||||||
|
valid_headers = { 'Authorization' => "Bearer token=#{bearer}" }
|
||||||
|
request.headers.merge!(valid_headers)
|
||||||
|
request.remote_ip = remote_ip
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET #index' do
|
||||||
|
subject { get :fake_action }
|
||||||
|
|
||||||
|
context 'when no authorized networks are defined' do
|
||||||
|
it { is_expected.to have_http_status(:ok) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a single authorized network is defined' do
|
||||||
|
before do
|
||||||
|
token.update!(authorized_networks: [IPAddr.new('192.168.1.0/24')])
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the request comes from it' do
|
||||||
|
let(:remote_ip) { '192.168.1.23' }
|
||||||
|
|
||||||
|
it { is_expected.to have_http_status(:ok) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the request does not come from it' do
|
||||||
|
let(:remote_ip) { '192.168.2.2' }
|
||||||
|
|
||||||
|
it { is_expected.to have_http_status(:forbidden) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -39,4 +39,47 @@ describe APIController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'ensure_authorized_network' do
|
||||||
|
let(:admin) { create(:administrateur) }
|
||||||
|
let(:token_bearer_couple) { APIToken.generate(admin) }
|
||||||
|
let(:token) { token_bearer_couple[0] }
|
||||||
|
let(:bearer) { token_bearer_couple[1] }
|
||||||
|
let(:remote_ip) { '0.0.0.0' }
|
||||||
|
|
||||||
|
controller(APIController) { def fake_action = render(plain: 'Hello, World!') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
routes.draw { get 'fake_action' => 'api#fake_action' }
|
||||||
|
valid_headers = { 'Authorization' => "Bearer token=#{bearer}" }
|
||||||
|
request.headers.merge!(valid_headers)
|
||||||
|
request.remote_ip = remote_ip
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET #index' do
|
||||||
|
subject { get :fake_action }
|
||||||
|
|
||||||
|
context 'when no authorized networks are defined' do
|
||||||
|
it { is_expected.to have_http_status(:ok) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a single authorized network is defined' do
|
||||||
|
before do
|
||||||
|
token.update!(authorized_networks: [IPAddr.new('192.168.1.0/24')])
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the request comes from it' do
|
||||||
|
let(:remote_ip) { '192.168.1.23' }
|
||||||
|
|
||||||
|
it { is_expected.to have_http_status(:ok) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the request does not come from it' do
|
||||||
|
let(:remote_ip) { '192.168.2.2' }
|
||||||
|
|
||||||
|
it { is_expected.to have_http_status(:forbidden) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue