[add] added maximum client and demo client protection
- default demo clients can no longer be modified/deleted when in demo mode - increased default demo reset to 60 minutes
This commit is contained in:
33
api.yml
33
api.yml
@@ -1,11 +1,34 @@
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
description: "Simple dynDNS via Rest-API."
|
||||
description: "Simple dynDNS via Rest-API.
|
||||
|
||||
|
||||
The demo database will reset every **60** minutes. A maximum of 250 clients can exist in the demo database.
|
||||
|
||||
The following default clients and api keys can be used:
|
||||
|
||||
| client name | api key |
|
||||
|
||||
|--------------|------------------------------------------------------------------------------------------|
|
||||
|
||||
| admin | `zW3If4s5.41a7c846.23b142e6451df545d5034ca8f6050b80ff3e9689f20d5e45d72d160fa7e1cf32` |
|
||||
|
||||
| read_client | `zW3If4s5.28aef5cb.d502cb94ba0802c6363f95ecb3a70de7e2e4b889779e435b7c033f2c72ed4f20` |
|
||||
|
||||
| write_client | `zW3If4s5.3d6129cc.48d41d2a28b16a9a274d3f407026aee2b82cddbb3c11a5496ffe329c78e5d54b` |
|
||||
|
||||
In `demo-mode` it is not possible to call `POST /admin/client`, `PUT /admin/client` or `DELETE /admin/clients/{client_name}` for any of the above default clients. Any newly created client can be freely modified.
|
||||
|
||||
|
||||
***Note**: the X-API-Key value entered when using Authorize takes precedence over values entered in the X-API-Key parameters field.
|
||||
|
||||
Since the X-API-Key parameter field is flagged as required a simple space (or any other character) will still be needed for executing the request here.*
|
||||
"
|
||||
version: "1.0"
|
||||
title: "rynDNS"
|
||||
|
||||
servers:
|
||||
- url: "https://api.pdev.dev/rynDNS/v1"
|
||||
- url: "https://demo.api.pdev.dev/rynDNS"
|
||||
description: ""
|
||||
|
||||
security:
|
||||
@@ -49,6 +72,8 @@ paths:
|
||||
description: "Invalid input"
|
||||
"406":
|
||||
description: "Not Acceptable - Can not remove last admin account permissions"
|
||||
"429":
|
||||
description: "Too many clients - Maximum client count reached"
|
||||
put:
|
||||
tags:
|
||||
- "admin"
|
||||
@@ -356,5 +381,5 @@ components:
|
||||
example: "115.16.0.99"
|
||||
pattern: "^(((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(.(?!$)|$)){4})?$"
|
||||
externalDocs:
|
||||
description: "Source"
|
||||
url: "https://git.pdev.dev"
|
||||
description: "<rynDNS source code>"
|
||||
url: "https://git.pdev.dev/pdev/ryndns"
|
||||
|
||||
@@ -9,6 +9,7 @@ class ClientsController < ApplicationController
|
||||
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 :client_authorized, except: [:show_public_ipv4]
|
||||
before_action :demo, only: %i[create update destroy] if ENV['RAILS_API_DEMO']
|
||||
|
||||
# URL Methods
|
||||
# POST /admin/client
|
||||
@@ -22,6 +23,7 @@ class ClientsController < ApplicationController
|
||||
# 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
|
||||
else
|
||||
# return 406 if request is trying to remove perm_x from last admin account to prevent lockout
|
||||
# TODO: move this into the model (update)
|
||||
@@ -217,4 +219,11 @@ class ClientsController < ApplicationController
|
||||
def client_authorized
|
||||
return head(403) unless @authorized
|
||||
end
|
||||
|
||||
# TODO: put this into a demo environment
|
||||
def demo
|
||||
demo_clients = %w[admin read_client write_client]
|
||||
request_params = params.key?(:name) ? params[:name] : ''
|
||||
return head(406) if demo_clients.include? request_params
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
class Client < ApplicationRecord
|
||||
|
||||
def self.new_client(params)
|
||||
return nil if count >= RynDNS::Application::MAX_CLIENTS
|
||||
|
||||
perm_string = params[:permission] || 'w' # create write client by default
|
||||
perm_rwx = Client.parse_perm_string(perm_string)
|
||||
|
||||
@@ -28,7 +30,7 @@ class Client < ApplicationRecord
|
||||
def gen_api_key
|
||||
api_key = SecureRandom.hex(32)
|
||||
self.api_key = api_key
|
||||
"#{RynDNS::Application::API_KEY_PREFIX}.#{self.name_id}.#{api_key}"
|
||||
"#{RynDNS::Application::API_KEY_PREFIX}.#{name_id}.#{api_key}"
|
||||
end
|
||||
|
||||
def api_key
|
||||
|
||||
@@ -58,5 +58,6 @@ module RynDNS
|
||||
puts "WARNING: Please modify api_key -> #{API_KEY_PREFIX}.########.############"
|
||||
end
|
||||
API_KEY_HEADER = ENV['RAILS_API_KEY_HEADER'] || 'X-API-Key'
|
||||
MAX_CLIENTS = ENV['RAILS_MAX_CLIENTS'] || 250
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,6 +10,8 @@ services:
|
||||
environment:
|
||||
# set to run app in subdirectory
|
||||
RAILS_RELATIVE_URL_ROOT: /rynDNS
|
||||
# set maximum number of clients in db
|
||||
#RAILS_MAX_CLIENTS: 250
|
||||
# set custom api key prefix
|
||||
#API_KEY_PREFIX: zW3If4s5
|
||||
# set custom header name for api key
|
||||
@@ -19,7 +21,7 @@ services:
|
||||
# set app to run as demo
|
||||
#RAILS_API_DEMO: 1
|
||||
# set cycle to reset demo data
|
||||
#RAILS_DEMO_RESET: 300
|
||||
#RAILS_DEMO_RESET: 60m
|
||||
restart: always
|
||||
image: ryndns
|
||||
container_name: ryndns
|
||||
|
||||
@@ -7,7 +7,7 @@ prefix_file="${API_PREFIX_FILE:-/app/data/api_prefix}"
|
||||
db_file="${RAILS_DB_PATH:-/app/data/rynDNS.sqlite3}"
|
||||
default_admin_file="${API_DEFAULT_KEY_FILE:-/app/data/api_default_admin}"
|
||||
rails_bin="${RAILS_BINARY:-/app/bin/rails}"
|
||||
demo_cycle="${RAILS_DEMO_RESET:-300s}"
|
||||
demo_cycle="${RAILS_DEMO_RESET:-60m}"
|
||||
demo_prefix="zW3If4s5"
|
||||
seed_default_key_text="Created default admin with api_key" # for grep'ing the default admin key
|
||||
|
||||
|
||||
@@ -160,6 +160,20 @@ RSpec.describe 'Clients', type: :request do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when sending a valid request to add another client above the MAX_CLIENTS limit' do
|
||||
before do
|
||||
clients_to_create = RynDNS::Application::MAX_CLIENTS - Client.count
|
||||
create_list(:client, clients_to_create)
|
||||
post '/admin/client', params: { name: 'extra_user' }, headers: api_key_header(admin_client)
|
||||
end
|
||||
|
||||
it 'does not add another client and returns status code 429' do
|
||||
expect(Client.count).to eq RynDNS::Application::MAX_CLIENTS
|
||||
expect(response.body).to be_empty
|
||||
expect(response).to have_http_status(429)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT /admin/client' do
|
||||
|
||||
Reference in New Issue
Block a user