Compare commits
1 Commits
c71e605abd
...
public_mod
| Author | SHA1 | Date | |
|---|---|---|---|
|
c4cb76fe0b
|
33
api.yml
33
api.yml
@@ -253,6 +253,39 @@ paths:
|
||||
$ref: "#/components/schemas/client_info"
|
||||
"401":
|
||||
$ref: "#/components/responses/unauthorized_public"
|
||||
post:
|
||||
tags:
|
||||
- "public"
|
||||
summary: "Set ipv4 client information. This is ONLY available if ENV['RAILS_API_PUBLIC'] is set"
|
||||
description: "If body is present, it will take precedence over the request IP. Response contains the newly set `ipv4` value."
|
||||
requestBody:
|
||||
description: "An existing clients properties wil only be updated if the parameter is present."
|
||||
required: false
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/client_update"
|
||||
operationId: "set_public_client_ip"
|
||||
security: []
|
||||
responses:
|
||||
"200":
|
||||
description: "Client created"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/client_info"
|
||||
"201":
|
||||
description: "Client updated"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/client_info"
|
||||
"403":
|
||||
description: "Forbidden - API not public"
|
||||
"406":
|
||||
description: "Not Acceptable - IPv4 Address is invalid"
|
||||
"429":
|
||||
description: "Too many clients - Maximum client count reached"
|
||||
|
||||
components:
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
require 'resolv'
|
||||
|
||||
class ClientsController < ApplicationController
|
||||
before_action :parse_api_key_header, except: [:show_public_ipv4]
|
||||
before_action :authenticate_client, except: [:show_public_ipv4]
|
||||
before_action :parse_api_key_header, except: %i[show_public_ipv4 create_public_ipv4]
|
||||
before_action :authenticate_client, except: %i[show_public_ipv4 create_public_ipv4]
|
||||
before_action :authorize_perm_r, only: [:show_ipv4]
|
||||
before_action :authorize_perm_w, only: %i[update_ipv4 destroy_ipv4]
|
||||
before_action :authorize_perm_x, only: %i[create update index show destroy]
|
||||
before_action :authorize_public, only: [:create_public_ipv4] if ENV['RAILS_API_PUBLIC']
|
||||
before_action :client_authorized, except: [:show_public_ipv4]
|
||||
before_action :demo, only: %i[create update destroy] if ENV['RAILS_API_DEMO']
|
||||
|
||||
@@ -129,6 +130,29 @@ class ClientsController < ApplicationController
|
||||
json_response(client_read_object(client))
|
||||
end
|
||||
|
||||
# POST /public/:id
|
||||
def create_public_ipv4
|
||||
ipv4 = request_ip
|
||||
|
||||
# return 406 if body with invalid ipv4 is present
|
||||
# TODO: move this into the model (update)
|
||||
return head(406) unless ipv4
|
||||
|
||||
client_params = params.permit(:name)
|
||||
client = Client.find_by name: params[:name]
|
||||
status_code = client ? 200 : 201
|
||||
|
||||
# create new client or update existing
|
||||
if client.nil?
|
||||
client ||= Client.new_client(client_params)
|
||||
return head(429) if client.nil? # reached max client count
|
||||
end
|
||||
client.public_ip = true
|
||||
client.ipv4 = ipv4
|
||||
client.save
|
||||
json_response(client_read_object(client), status_code)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# helper methods
|
||||
@@ -215,6 +239,10 @@ class ClientsController < ApplicationController
|
||||
@authorized = @requesting_client.admin?
|
||||
end
|
||||
|
||||
def authorize_public
|
||||
@authorized = true
|
||||
end
|
||||
|
||||
# check if request is authorized
|
||||
def client_authorized
|
||||
return head(403) unless @authorized
|
||||
|
||||
@@ -21,6 +21,7 @@ Rails.application.routes.draw do
|
||||
# separate public path to allow for easier segregation and controls via reverse proxy
|
||||
scope '/public' do
|
||||
get ':name', to: 'clients#show_public_ipv4', format: false
|
||||
post ':name', to: 'clients#create_public_ipv4', format: false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -587,4 +587,49 @@ RSpec.describe 'Clients', type: :request do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /public/:name' do
|
||||
# FIXME: rather have this automated than adding ENV by hand
|
||||
if ENV['RAILS_API_PUBLIC']
|
||||
|
||||
context 'when request to write public client' do
|
||||
before { post "/public/#{public_client.name}" }
|
||||
it 'returns status code 200' do
|
||||
expect(json_response['name']).to eq public_client.name
|
||||
expect(json_response['ipv4']).to eq '127.0.0.1'
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when requesting to write public client with body' do
|
||||
before { post "/public/#{public_client.name}", params: { ipv4: '99.55.66.2' } }
|
||||
it 'returns status code 200' do
|
||||
expect(json_response['name']).to eq public_client.name
|
||||
expect(json_response['ipv4']).to eq '99.55.66.2'
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when requesting to write non existing client' do
|
||||
before { post "/public/#{non_existing_client}" }
|
||||
it 'returns status code 201' do
|
||||
expect(json_response['name']).to eq non_existing_client
|
||||
expect(json_response['ipv4']).to eq '127.0.0.1'
|
||||
expect(response).to have_http_status(201)
|
||||
end
|
||||
end
|
||||
# TODO: 406 and 429, check client count on 200
|
||||
else
|
||||
|
||||
context 'when request to write public client' do
|
||||
before { post "/public/#{public_client.name}" }
|
||||
it 'returns status code 403' do
|
||||
expect(response.body).to be_empty
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
# TODO: check client count/modification
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user