dynette/dynette.rb

213 lines
6.3 KiB
Ruby
Raw Normal View History

2013-06-15 21:06:14 +02:00
#!/usr/bin/ruby
require 'rubygems'
require 'sinatra'
require 'data_mapper'
require 'json'
2013-07-07 12:46:39 +02:00
require 'base64'
2013-06-15 21:06:14 +02:00
2013-06-16 00:13:29 +02:00
DataMapper.setup(:default, ENV['DATABASE_URL'] || "postgres://postgres:yayaya@localhost/dynette")
2013-06-19 09:52:35 +02:00
DOMAINS = ["nohost.me", "noho.st"]
2013-07-07 10:44:40 +02:00
ALLOWED_IP = ["82.196.13.142", "192.81.223.119", "127.0.0.1"]
2013-06-15 21:06:14 +02:00
class Entry
include DataMapper::Resource
property :id, Serial
property :public_key, String
property :subdomain, String
property :current_ip, String
2013-06-16 10:21:06 +02:00
property :created_at, DateTime
2013-06-15 21:06:14 +02:00
has n, :ips
end
class Ip
include DataMapper::Resource
property :id, Serial
property :ip_addr, String
belongs_to :entry
end
2013-06-16 00:13:29 +02:00
class Iplog
include DataMapper::Resource
property :ip_addr, String, :key => true
property :visited_at, DateTime
end
class Ipban
include DataMapper::Resource
property :ip_addr, String, :key => true
end
2013-06-16 10:21:06 +02:00
not_found do
content_type :json
halt 404, { :error => "Not found" }.to_json
end
2013-06-16 00:13:29 +02:00
before do
if Ipban.first(:ip_addr => request.ip)
halt 410, "Your ip is banned from the service"
end
2013-06-16 10:21:06 +02:00
unless %w[domains test all ban unban].include? request.path_info.split('/')[1]
if iplog = Iplog.last(:ip_addr => request.ip)
if iplog.visited_at.to_time > Time.now - 30
halt 410, "Please wait 30sec\n"
else
iplog.update(:visited_at => Time.now)
end
2013-06-16 00:13:29 +02:00
else
2013-06-16 10:21:06 +02:00
Iplog.create(:ip_addr => request.ip, :visited_at => Time.now)
2013-06-16 00:13:29 +02:00
end
end
2013-06-16 09:45:02 +02:00
content_type :json
2013-06-16 10:21:06 +02:00
end
2013-06-16 09:45:02 +02:00
2013-06-16 10:21:06 +02:00
# Check params
['/test/:subdomain', '/key/:public_key', '/ips/:public_key', '/ban/:ip', '/unban/:ip' ].each do |path|
before path do
if params.has_key?("public_key")
2013-07-07 13:20:39 +02:00
public_key = Base64.decode64(params[:public_key].encode('ascii-8bit'))
2013-07-07 12:52:37 +02:00
unless public_key.length == 24
2013-07-07 13:00:21 +02:00
halt 400, { :error => "Key is invalid: #{public_key.to_s.encode('UTF-8', {:invalid => :replace, :undef => :replace, :replace => '?'})}" }.to_json
2013-06-16 10:21:06 +02:00
end
2013-06-16 09:45:02 +02:00
end
2013-06-16 10:21:06 +02:00
if params.has_key?("subdomain")
unless params[:subdomain].match /^([a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)(\.[a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)*(\.[a-zA-Z]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)$/
halt 400, { :error => "Subdomain is invalid: #{params[:subdomain]}" }.to_json
end
unless DOMAINS.include? params[:subdomain].gsub(params[:subdomain].split('.')[0]+'.', '')
halt 400, { :error => "Subdomain #{params[:subdomain]} is not part of available domains: #{DOMAINS.join(', ')}" }.to_json
end
2013-06-16 09:45:02 +02:00
end
2013-06-16 10:21:06 +02:00
if params.has_key?("ip")
unless params[:ip].match /^(?:(?: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]?)$/
halt 400, { :error => "IP is invalid: #{params[:ip]}" }.to_json
end
2013-06-16 09:45:02 +02:00
end
end
2013-06-16 00:13:29 +02:00
end
2013-06-15 21:57:12 +02:00
get '/' do
2013-06-16 00:17:33 +02:00
"Wanna play the dynette ?"
2013-06-15 21:57:12 +02:00
end
2013-06-15 21:06:14 +02:00
2013-06-16 09:45:02 +02:00
get '/domains' do
DOMAINS.to_json
end
2013-06-16 01:06:25 +02:00
get '/test/:subdomain' do
if entry = Entry.first(:subdomain => params[:subdomain])
2013-06-16 10:21:06 +02:00
halt 409, { :error => "Subdomain already taken: #{entry.subdomain}" }.to_json
2013-06-16 01:06:25 +02:00
else
2013-06-16 10:21:06 +02:00
halt 200, "Domain #{params[:subdomain]} is available".to_json
2013-06-16 01:06:25 +02:00
end
end
2013-06-16 10:21:06 +02:00
post '/key/:public_key' do
2013-07-07 13:28:56 +02:00
params[:public_key] = Base64.decode64(params[:public_key].encode('ascii-8bit'))
2013-06-15 21:57:12 +02:00
# Check params
2013-06-16 09:45:02 +02:00
halt 400, { :error => "Please indicate a subdomain" }.to_json unless params.has_key?("subdomain")
2013-06-15 21:57:12 +02:00
# If already exists
2013-06-15 22:19:33 +02:00
if entry = Entry.first(:subdomain => params[:subdomain])
2013-06-16 10:21:06 +02:00
halt 409, { :error => "Subdomain already taken: #{entry.subdomain}" }.to_json
2013-06-15 22:19:33 +02:00
end
if entry = Entry.first(:public_key => params[:public_key])
2013-06-16 10:21:06 +02:00
halt 409, { :error => "Key already exists for domain #{entry.subdomain}" }.to_json
2013-06-15 22:19:33 +02:00
end
2013-06-15 22:13:57 +02:00
# Process
2013-06-16 10:21:06 +02:00
entry = Entry.new(:public_key => params[:public_key], :subdomain => params[:subdomain], :current_ip => request.ip, :created_at => Time.now)
2013-06-15 21:57:12 +02:00
entry.ips << Ip.create(:ip_addr => request.ip)
2013-06-15 21:06:14 +02:00
if entry.save
2013-06-16 09:45:02 +02:00
halt 201, { :public_key => entry.public_key, :subdomain => entry.subdomain, :current_ip => entry.current_ip }.to_json
2013-06-15 21:06:14 +02:00
else
2013-06-16 09:45:02 +02:00
halt 412, { :error => "A problem occured during DNS registration" }.to_json
2013-06-15 21:06:14 +02:00
end
end
2013-06-16 10:21:06 +02:00
put '/key/:public_key' do
2013-07-07 13:28:56 +02:00
params[:public_key] = Base64.decode64(params[:public_key].encode('ascii-8bit'))
2013-06-15 22:13:57 +02:00
entry = Entry.first(:public_key => params[:public_key])
unless request.ip == entry.current_ip
entry.ips << Ip.create(:ip_addr => request.ip)
end
entry.current_ip = request.ip
if entry.save
2013-06-16 09:45:02 +02:00
halt 201, { :public_key => entry.public_key, :subdomain => entry.subdomain, :current_ip => entry.current_ip }.to_json
2013-06-15 22:13:57 +02:00
else
2013-06-16 09:45:02 +02:00
halt 412, { :error => "A problem occured during DNS update" }.to_json
2013-06-15 22:13:57 +02:00
end
end
2013-06-16 10:21:06 +02:00
delete '/key/:public_key' do
2013-07-07 13:28:56 +02:00
params[:public_key] = Base64.decode64(params[:public_key].encode('ascii-8bit'))
2013-06-16 00:13:29 +02:00
if entry = Entry.first(:public_key => params[:public_key])
2013-06-16 09:45:02 +02:00
if entry.destroy
halt 200, "OK".to_json
else
halt 412, { :error => "A problem occured during DNS deletion" }.to_json
end
2013-06-16 00:13:29 +02:00
end
end
2013-06-15 21:06:14 +02:00
get '/all' do
2013-07-07 10:03:15 +02:00
unless ALLOWED_IP.include? request.ip
2013-06-15 21:06:14 +02:00
status 403
return "Access denied"
end
Entry.all.to_json
end
2013-06-16 10:39:41 +02:00
get '/all/:domain' do
2013-07-07 10:03:15 +02:00
unless ALLOWED_IP.include? request.ip
2013-06-16 10:39:41 +02:00
status 403
return "Access denied"
end
result = []
Entry.all.each do |entry|
result.push(entry) if params[:domain] == entry.subdomain.gsub(entry.subdomain.split('.')[0]+'.', '')
end
halt 200, result.to_json
end
2013-06-16 10:21:06 +02:00
get '/ips/:public_key' do
2013-07-07 13:28:56 +02:00
params[:public_key] = Base64.decode64(params[:public_key].encode('ascii-8bit'))
2013-07-07 10:03:15 +02:00
unless ALLOWED_IP.include? request.ip
2013-06-15 22:33:45 +02:00
status 403
return "Access denied"
end
2013-06-16 00:13:29 +02:00
ips = []
Entry.first(:public_key => params[:public_key]).ips.all.each do |ip|
ips.push(ip.ip_addr)
end
ips.to_json
end
2013-06-16 09:45:02 +02:00
get '/ban/:ip' do
2013-07-07 10:03:15 +02:00
unless ALLOWED_IP.include? request.ip
2013-06-16 00:13:29 +02:00
status 403
return "Access denied"
end
2013-06-16 09:45:02 +02:00
Ipban.create(:ip_addr => params[:ip])
2013-06-16 00:13:29 +02:00
Ipban.all.to_json
end
2013-06-16 09:45:02 +02:00
get '/unban/:ip' do
2013-07-07 10:03:15 +02:00
unless ALLOWED_IP.include? request.ip
2013-06-16 00:13:29 +02:00
status 403
return "Access denied"
end
2013-06-16 09:45:02 +02:00
Ipban.first(:ip_addr => params[:ip]).destroy
2013-06-16 00:13:29 +02:00
Ipban.all.to_json
2013-06-15 22:33:45 +02:00
end
2013-06-19 11:44:46 +02:00
DataMapper.auto_migrate!