Browse Source

token API

pull/1/head
Nicolae Claudius 13 years ago
parent
commit
bac4564923
  1. 10
      Gemfile.lock
  2. 6
      app/controllers/application_controller.rb
  3. 22
      app/controllers/as_controller.rb
  4. 7
      app/controllers/cnames_controller.rb
  5. 7
      app/controllers/mxes_controller.rb
  6. 2
      app/controllers/ns_controller.rb
  7. 2
      app/controllers/records_controller.rb
  8. 2
      app/controllers/soas_controller.rb
  9. 7
      app/controllers/txts_controller.rb
  10. 11
      app/models/record.rb
  11. 42
      app/validators/ip_validator.rb
  12. 2
      app/views/fragments/_top.html.erb
  13. 8
      config/locales/en.yml
  14. 3
      config/routes.rb
  15. 2
      db/migrate/20110917084816_create_records.rb

10
Gemfile.lock

@ -77,7 +77,7 @@ GEM
fssm (>= 0.2.7)
sass (~> 3.1)
database_cleaner (0.6.7)
devise (1.4.7)
devise (1.4.8)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.3)
warden (~> 1.0.3)
@ -98,8 +98,8 @@ GEM
thor (~> 0.14.6)
guard-rspec (0.4.5)
guard (>= 0.4.0)
guard-spork (0.3.0)
guard (>= 0.8.2)
guard-spork (0.3.1)
guard (>= 0.8.4)
spork (>= 0.8.4)
highline (1.6.2)
hike (1.2.1)
@ -107,6 +107,7 @@ GEM
jquery-rails (1.0.14)
railties (~> 3.0)
thor (~> 0.14)
json (1.6.1)
json_pure (1.6.1)
libv8 (3.3.10.2)
mail (2.3.0)
@ -159,7 +160,8 @@ GEM
thor (~> 0.14.6)
rake (0.9.2)
rb-fsevent (0.4.3.1)
rdoc (3.9.4)
rdoc (3.10)
json (~> 1.4)
rspec (2.6.0)
rspec-core (~> 2.6.0)
rspec-expectations (~> 2.6.0)

6
app/controllers/application_controller.rb

@ -23,4 +23,10 @@ class ApplicationController < ActionController::Base
def ensure_nested_under_domain
raise CanCan::AccessDenied, "not found" unless nested? and nested_parent_record.is_a?(Domain)
end
def client_remote_ip
request.env["HTTP_X_FORWARDED_FOR"]
end
helper_method :client_remote_ip
end

22
app/controllers/as_controller.rb

@ -1,6 +1,8 @@
class AsController < ApplicationController
respond_to :html, :xml, :json
active_scaffold :a do |conf|
conf.list.columns = [:name, :type, :content, :ttl, :prio, :change_date]
conf.columns = [:name, :type, :content, :ttl, :prio, :change_date, :authentication_token]
conf.create.columns = [:name, :content, :ttl,]
conf.update.columns = [:name, :content, :ttl]
conf.columns[:content].label = 'IP'
@ -9,7 +11,18 @@ class AsController < ApplicationController
conf.columns[:ttl].options = {:i18n_number => {:delimiter => ''}}
conf.actions.exclude :show
end
before_filter :ensure_nested_under_domain
before_filter :ensure_nested_under_domain, :except => 'modify'
skip_before_filter :authenticate_user!, :only => 'modify'
protect_from_forgery :except => 'modify'
skip_authorize_resource :only => :modify
# TODO: externalize
def modify
@a = A.where(:authentication_token => params[:authentication_token]).first!
@a.content = params[:ip] || client_remote_ip
@a.save!
respond_with @a
end
protected
@ -24,8 +37,9 @@ class AsController < ApplicationController
# override, we make our own sti logic
def new_model
model = beginning_of_chain
model.new
model = beginning_of_chain.new
model.name = nested_parent_record.name
model
end
# override to close create form after success

7
app/controllers/cnames_controller.rb

@ -1,6 +1,6 @@
class CnamesController < ApplicationController
active_scaffold :cname do |conf|
conf.list.columns = [:name, :type, :content, :ttl, :prio, :change_date]
conf.columns = [:name, :type, :content, :ttl, :prio, :change_date, :authentication_token]
conf.create.columns = [:name, :content, :ttl]
conf.update.columns = [:name, :content, :ttl]
conf.columns[:content].label = 'FQDN'
@ -24,8 +24,9 @@ class CnamesController < ApplicationController
# override, we make our own sti logic
def new_model
model = beginning_of_chain
model.new
model = beginning_of_chain.new
model.name = nested_parent_record.name
model
end
# override to close create form after success

7
app/controllers/mxes_controller.rb

@ -1,6 +1,6 @@
class MxesController < ApplicationController
active_scaffold :mx do |conf|
conf.list.columns = [:name, :type, :content, :ttl, :prio, :change_date]
conf.columns = [:name, :type, :content, :ttl, :prio, :change_date, :authentication_token]
conf.create.columns = [:content, :ttl, :prio]
conf.update.columns = [:content, :ttl, :prio]
conf.columns[:content].label = 'MX'
@ -32,8 +32,9 @@ class MxesController < ApplicationController
# override, we make our own sti logic
def new_model
model = beginning_of_chain
model.new
model = beginning_of_chain.new
model.name = nested_parent_record.name
model
end
# override to close create form after success

2
app/controllers/ns_controller.rb

@ -1,6 +1,6 @@
class NsController < ApplicationController
active_scaffold :ns do |conf|
conf.list.columns = [:name, :type, :content, :ttl, :prio, :change_date]
conf.columns = [:name, :type, :content, :ttl, :prio, :change_date, :authentication_token]
conf.create.columns = [:name, :content, :ttl]
conf.update.columns = [:name, :content, :ttl]
conf.subform.columns = [:content, :ttl]

2
app/controllers/records_controller.rb

@ -18,7 +18,7 @@ class RecordsController < ApplicationController
active_scaffold :record do |conf|
conf.sti_children = [:SOA, :NS, :MX, :A, :CNAME, :TXT]
conf.columns = [:name, :type, :content, :ttl, :prio, :change_date]
conf.columns = [:name, :type, :content, :ttl, :prio, :change_date, :authentication_token]
conf.columns[:change_date].list_ui = :timestamp
conf.columns[:ttl].options = {:i18n_number => {:delimiter => ''}}
# conf.create.link.label = "Add Record"

2
app/controllers/soas_controller.rb

@ -1,6 +1,6 @@
class SoasController < ApplicationController
active_scaffold :soa do |conf|
conf.list.columns = [:name, :type, :content, :ttl, :prio, :change_date]
conf.columns = [:name, :type, :content, :ttl, :prio, :change_date, :authentication_token]
conf.create.columns = [:contact, :ttl]
conf.update.columns = [:contact, :ttl]
conf.columns[:change_date].list_ui = :timestamp

7
app/controllers/txts_controller.rb

@ -1,6 +1,6 @@
class TxtsController < ApplicationController
active_scaffold :txt do |conf|
conf.list.columns = [:name, :type, :content, :ttl, :prio, :change_date]
conf.columns = [:name, :type, :content, :ttl, :prio, :change_date, :authentication_token]
conf.create.columns = [:name, :content, :ttl]
conf.update.columns = [:name, :content, :ttl]
# conf.columns[:content].label = 'Content'
@ -24,8 +24,9 @@ class TxtsController < ApplicationController
# override, we make our own sti logic
def new_model
model = beginning_of_chain
model.new
model = beginning_of_chain.new
model.name = nested_parent_record.name
model
end
# override to close create form after success

11
app/models/record.rb

@ -14,7 +14,9 @@ class Record < ActiveRecord::Base
:less_than => 2**31,
:only_integer => true
}, :allow_blank => true
validates :authentication_token, :presence => true, :uniqueness => true
before_validation :generate_token, :on => :create
before_validation :prepare_name!
before_save :update_change_date
after_save :update_soa_serial
@ -31,6 +33,15 @@ class Record < ActiveRecord::Base
def to_label; "#{type} #{content}" end
# Generate a token by looping and ensuring does not already exist.
# stolen from Devise
def generate_token
self.authentication_token = loop do
token = Devise.friendly_token
break token unless self.class.exists?(:authentication_token => token)
end
end
protected
def prepare_name!

42
app/validators/ip_validator.rb

@ -3,6 +3,27 @@
# @author Kim Nørgaard <jasen@jasen.dk>
class IpValidator < ActiveModel::EachValidator
IPV4_REGEX = /^
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
$/x
IPV6_REGEX = /^
(
(([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))
|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))
|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))
|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})
|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){1,7}:)
)$/x
# @param [Hash] options Options for validation
# @option options [Symbol] :ip_type (:any) The IP address type (:any, :v4 or :v6)
# @see ActiveModel::EachValidator#new
@ -26,31 +47,14 @@ private
# @param [String] address the ipv4 address
# @return [Boolean] the validation result
def ipv4?(address)
address =~ /^
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
$/x
address =~ IPV4_REGEX
end
# Validates IPv6 address
# @param [String] address the ipv6 address
# @return [Boolean] the validation result
def ipv6?(address)
address =~ /^
(
(([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))
|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))
|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))
|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})
|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})
|(([0-9A-Fa-f]{1,4}:){1,7}:)
)$/x
address =~ IPV6_REGEX
end
# Validates IP (v4 or v6) address

2
app/views/fragments/_top.html.erb

@ -16,7 +16,7 @@
<div id="user-navigation">
<ul class="wat-cf">
<% if user_signed_in? %>
<li><%= link_to(current_user.email, edit_user_registration_path, :data => {:pjax => '#main'}) %></li>
<li><%= link_to(current_user.email, edit_user_registration_path, :title => "IP: #{client_remote_ip}", :data => {:pjax => '#main'}) %></li>
<li><%= link_to('Sign out', destroy_user_session_path, :method => :delete) %></li>
<% else %>
<li><%= link_to('Sign up', new_user_registration_path, :data => {:pjax => '#main'}) %></li>

8
config/locales/en.yml

@ -12,6 +12,14 @@ en:
mx: "MX Record"
a: "A Record"
txt: "TXT Record"
# errors
# models
# a
# attributes
# content
# ipv4
# attributes:
# user:
# login: "Handle"

3
config/routes.rb

@ -24,6 +24,9 @@ Entrydns::Application.routes.draw do
resources :as do
as_routes
collection do
put 'modify/:authentication_token', :action => 'modify'
end
end
resources :cnames do

2
db/migrate/20110917084816_create_records.rb

@ -8,6 +8,7 @@ class CreateRecords < ActiveRecord::Migration
t.integer :ttl
t.integer :prio
t.integer :change_date
t.string :authentication_token
t.timestamps
end
@ -15,5 +16,6 @@ class CreateRecords < ActiveRecord::Migration
add_index :records, :name, :name => 'rec_name_index'
add_index :records, [:name, :type], :name => 'nametype_index'
add_index :records, :domain_id, :name => 'domain_id'
add_index :records, :authentication_token, :unique => true
end
end

Loading…
Cancel
Save