diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb new file mode 100644 index 0000000..301d4e9 --- /dev/null +++ b/app/controllers/help_controller.rb @@ -0,0 +1,7 @@ +class HelpController < ApplicationController + before_action :authenticate_user! + + def api + render layout: false + end +end diff --git a/app/views/help/api.html.erb b/app/views/help/api.html.erb new file mode 100644 index 0000000..a9b6988 --- /dev/null +++ b/app/views/help/api.html.erb @@ -0,0 +1,104 @@ +WebDNS API +

WebDNS API

+

General

+

To access WebDNS API you must have an API token. If you are a WebDNS user you can generate your token by clicking on the API Token link in the navigation bar.

+ +

Debug API

+

GET /ping

+
curl -X GET https://webdns/api/ping
+{
+  "ok": true,
+  "response": "pong"
+}
+
+

GET /whoami

+
curl -X GET https://webdns/api/whoami
+{
+  "ok": true,
+  "response": {
+    "id": 1,
+    "email": "user@example.com"
+  }
+}
+
+

Records API

+

GET /domain/<name>/list

+
curl -X GET https://webdns/api/domain/example.com/list
+
+{
+  "ok": true,
+  "response": [
+    {
+      "name": "example.com",
+      "content": "ns1.example.com webdns@example.com 2016050301 10800 3600 604800 3600",
+      "type": "SOA",
+      "ttl": null,
+      "prio": null,
+      "disabled": false
+    },
+    {
+      "name": "example.com",
+      "content": "ns1.example.com",
+      "type": "NS",
+      "ttl": null,
+      "prio": null,
+      "disabled": false
+    },
+    {
+      "name": "www.example.com",
+      "content": "192.0.0.1",
+      "type": "A",
+      "ttl": null,
+      "prio": null,
+      "disabled": false
+    },
+    {
+      "name": "www.example.com",
+      "content": "2001:db8::1",
+      "type": "AAAA",
+      "ttl": null,
+      "prio": null,
+      "disabled": false
+    }
+
+

POST /domain/<name>/bulk

+

The bulk API allows multiple operations to be perfomed as a single transactional operation. There a three supported operations and they are applied in the following order:

+ +

additions is an array of hashes. Each hash represents a record to be added. +name, type, content and prio fields are supported.

+

deletes is an array of hashes. Each hash represents a single record to be deleted. The fields musts match exactly one record.

+

upserts is an array of hashes. Each hash represents a records to be added, just like an addition. What’s different about upserts is that, before adding the records, all records matching the hash’s name and type are deleted.

+

Fields

+ +
curl -X POST https://webdns/api/domain/example.com/bulk  -H 'Content-Type: application/json' -d '{
+  "upserts": [
+    {
+      "name": "mail.example.com",
+      "type": "A",
+      "content": "1.2.3.4"
+    }
+  ],
+  "additions": [
+    {
+      "name": "www.example.com",
+      "type": "A",
+      "content": "1.2.3.4"
+    }
+  ]
+}'
+
+ + \ No newline at end of file diff --git a/app/views/help/api.md b/app/views/help/api.md new file mode 100644 index 0000000..fef7ee0 --- /dev/null +++ b/app/views/help/api.md @@ -0,0 +1,115 @@ +# WebDNS API + +## General + +To access WebDNS API you must have an API `token`. If you are a WebDNS user you can generate your token by clicking on the `API Token` link in the navigation bar. + + * All API request should be routed under the `/api/` prefix. + * The API token needs to be present as a `?token` URL parameter in all requests. + * When sending data (POST/PUT) make sure to correctly set the content encoding header (`Content-Enconding: application/json`). + +## Debug API + +### GET `/ping` +```bash +curl -X GET https://webdns/api/ping +{ + "ok": true, + "response": "pong" +} +``` + +### GET `/whoami` +```bash +curl -X GET https://webdns/api/whoami +{ + "ok": true, + "response": { + "id": 1, + "email": "user@example.com" + } +} +``` + +## Records API + +### GET `/domain//list` +```bash +curl -X GET https://webdns/api/domain/example.com/list + +{ + "ok": true, + "response": [ + { + "name": "example.com", + "content": "ns1.example.com webdns@example.com 2016050301 10800 3600 604800 3600", + "type": "SOA", + "ttl": null, + "prio": null, + "disabled": false + }, + { + "name": "example.com", + "content": "ns1.example.com", + "type": "NS", + "ttl": null, + "prio": null, + "disabled": false + }, + { + "name": "www.example.com", + "content": "192.0.0.1", + "type": "A", + "ttl": null, + "prio": null, + "disabled": false + }, + { + "name": "www.example.com", + "content": "2001:db8::1", + "type": "AAAA", + "ttl": null, + "prio": null, + "disabled": false + } +``` + +### POST `/domain//bulk` + +The `bulk` API allows multiple operations to be perfomed as a single transactional operation. There a three supported operations and they are applied in the following order: + + * `deletes` + * `upserts` + * `additions` + +`additions` is an array of hashes. Each hash represents a record to be added. +`name`, `type`, `content` and `prio` fields are supported. + +`deletes` is an array of hashes. Each hash represents a single record to be deleted. The fields musts match **exactly one** record. + +`upserts` is an array of hashes. Each hash represents a records to be added, just like an `addition`. What's different about `upserts` is that, before adding the records, all records matching the hash's `name` and `type` are deleted. + +#### Fields + * `name`: Record name. Should be expanded to contain the full domain name. + * `type`: Capitilized record type (`'A'`, `'AAAA'`, etc) + * `prio`: Record priority, if supported. + * `content`: Record content. When this is a CNANE **do not** include the trailing dot. + +```bash +curl -X POST https://webdns/api/domain/example.com/bulk -H 'Content-Type: application/json' -d '{ + "upserts": [ + { + "name": "mail.example.com", + "type": "A", + "content": "1.2.3.4" + } + ], + "additions": [ + { + "name": "www.example.com", + "type": "A", + "content": "1.2.3.4" + } + ] +}' +``` \ No newline at end of file diff --git a/app/views/shared/_nav.html.erb b/app/views/shared/_nav.html.erb index 2c7b7ff..98af7f0 100644 --- a/app/views/shared/_nav.html.erb +++ b/app/views/shared/_nav.html.erb @@ -1,56 +1,57 @@ diff --git a/config/routes.rb b/config/routes.rb index 80b5e24..c76f3ab 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,77 +1,79 @@ Rails.application.routes.draw do # Override devise user removal devise_scope :users do delete :users, to: redirect('/') end devise_for :users get '/auth/saml', to: 'auth#saml' root to: redirect('/domains') resources :users, only: [] do get :token, to: 'users#token', on: :member post :generate_token, to: 'users#generate_token', on: :member end resources :groups, only: [:show] do get :search_member, to: 'groups#search_member', on: :member post :members, to: 'groups#create_member', as: :create_member, on: :member delete 'member/:user_id', to: 'groups#destroy_member', as: :destroy_member, on: :member end resources :domains do get :edit_dnssec, to: 'domains#edit_dnssec', on: :member delete :full_destroy, to: 'domains#full_destroy', on: :member resources :records, except: [:index, :show] do # Reuse records#update instead of introducing new controller actions # # rubocop:disable Style/AlignHash put :disable, to: 'records#update', on: :member, defaults: { record: { disabled: true } } put :enable, to: 'records#update', on: :member, defaults: { record: { disabled: false } } put :editable, to: 'records#editable', on: :collection post :valid, to: 'records#valid', on: :collection post :bulk, to: 'records#bulk', on: :collection # rubocop:enable Style/AlignHash end end get '/records/search', to: 'records#search' # Admin namespace :admin do root to: redirect('/admin/groups') resources :groups, except: [:show] resources :jobs, only: [:index, :destroy] do put :done, to: 'jobs#update', on: :member, defaults: { job: { status: 1 } } put :pending, to: 'jobs#update', on: :member, defaults: { job: { status: 0 } } end resources :users, only: [:destroy] do get :orphans, to: 'users#orphans', on: :collection put :update_groups, to: 'users#update_groups', on: :collection end end # API scope '/api' do get :ping, to: 'api#ping' get :whoami, to: 'api#whoami' get '/domain/:domain/list', to: 'api#list', constraints: { domain: /[^\/]+/} post '/domain/:domain/bulk', to: 'api#bulk', constraints: { domain: /[^\/]+/} end if WebDNS.settings[:api] # Private put 'private/replace_ds', to: 'private#replace_ds' put 'private/trigger_event', to: 'private#trigger_event' get 'private/zones', to: 'private#zones' + + get 'help/api', to: 'help#api' end