diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb new file mode 100644 index 0000000..2d5bf65 --- /dev/null +++ b/app/controllers/api_controller.rb @@ -0,0 +1,27 @@ +class ApiController < ApplicationController + # This a private trusted API + skip_before_action :verify_authenticity_token + + before_action :authenticate_token + + # GET /ping + def ping + render json: { ok: true, response: :pong } + end + + # GET /whoami + def whoami + render json: { ok: true, response: current_user.to_api } + end + + private + + def authenticate_token + if user = User.find_by_token(params.require(:token)) + warden.set_user(user, store: false) + else + head(403) + end + end + +end diff --git a/app/models/user.rb b/app/models/user.rb index dcafc46..b9f1cbe 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,23 +1,30 @@ class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable has_many :memberships has_many :groups, through: :memberships scope :orphans, -> { includes(:memberships).where(:memberships => { user_id: nil }) } # Check if the user can change his password # # Remote users are not able to change their password def can_change_password? !identifier? end + def to_api + Hash[ + :id, id, + :email, email + ].with_indifferent_access + end + def self.find_for_database_authentication(conditions) # Override devise method for database auth # We only want to auth local user via the database. find_first_by_auth_conditions(conditions, identifier: '') end end diff --git a/config/initializers/00_settings.rb b/config/initializers/00_settings.rb index 57b321d..5216419 100644 --- a/config/initializers/00_settings.rb +++ b/config/initializers/00_settings.rb @@ -1,48 +1,50 @@ WebDNS.settings[:soa_defaults] = { primary_ns: 'ns1.example.com', contact: 'domainmaster@example.com', serial: 1, refresh: 10_800, retry: 3600, expire: 604_800, nx: 3600 } WebDNS.settings[:default_ns] = [ 'ns1.example.com', 'ns2.example.com' ] WebDNS.settings[:dnssec] = true WebDNS.settings[:dnssec_parent_authorities] = { webdns: { valid: -> (parent) { Domain.find_by_name(parent) } # Check if parent is self-hosted }, papaki: { valid: -> (parent) { parent.split('.').size == 1 } # TLDs } } WebDNS.settings[:dnssec_ds_removal_sleep] = 14400 * 2 # Testing helper WebDNS.settings[:dnssec_parent_authorities].merge!( test_authority: { valid: -> (parent) { true } } ) if Rails.env.test? WebDNS.settings[:serial_strategy] = Strategies::Date WebDNS.settings[:prohibit_records_types] = [] WebDNS.settings[:prohibit_domain_types] = ['NATIVE'] WebDNS.settings[:contact_mail] = 'webdns@example.com' WebDNS.settings[:mail_from] = 'webdns@example.com' WebDNS.settings[:admin_group] = 'admin' WebDNS.settings[:saml] = false WebDNS.settings[:saml_required_entitlement] = 'webdns' WebDNS.settings[:saml_login_text] = 'Login with SAML' +WebDNS.settings[:api] = true + # Allow local overrides local_settings = File.expand_path('../../local_settings.rb', __FILE__) require_relative local_settings if File.exist?(local_settings) diff --git a/config/routes.rb b/config/routes.rb index ca7ed0f..0ecff57 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,69 +1,75 @@ 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' + 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' end