Skip to content

Instantly share code, notes, and snippets.

@burningTyger
Forked from clody69/server.rb
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save burningTyger/12f457f2459fd21f8c42 to your computer and use it in GitHub Desktop.
Save burningTyger/12f457f2459fd21f8c42 to your computer and use it in GitHub Desktop.
require 'sinatra'
require 'haml'
$users = {'john' => {:roles => [:user] }, 'mike' => {:roles => [:user, :admin] } }
$tokens = {'123' => {:username => 'john', :expires_at => Time.now+60}}
helpers do
def authenticate_user!
@auth_token = auth_token
if $tokens.has_key?(@auth_token) && !$tokens[@auth_token][:expires_at].nil? && $tokens[@auth_token][:expires_at] > Time.now
@current_user = $tokens[@auth_token][:username]
else
@current_user = nil
end
end
def current_user
@current_user
end
def login?
!@current_user.nil?
end
def activate!(token)
if $tokens.has_key?(token) && $tokens[token][:expires_at].nil?
$tokens[token][:expires_at] = Time.now + 600
return true
end
end
def logout
$tokens.delete(@auth_token)
end
def roles?(roles)
return true if roles.include?(:any)
!(roles & $users[@current_user][:roles]).empty?
end
def auth_token
if params.has_key?("auth_token")
return params["auth_token"]
elsif request.env.has_key?('HTTP_AUTHENTICATION')
return request.env["HTTP_AUTHENTICATION"][/Token token="?(\w+)"?/,1]
end
end
def generate_auth_token
begin
token = SecureRandom.hex(20)
end while $tokens.has_key?(token)
token
end
end
set(:auth) do |*roles|
condition do
halt 401, 'Unauthorized' unless login?
halt 403, 'Forbidden' unless roles?(roles.to_a)
end
end
before do
authenticate_user!
end
get '/' do
haml :index
end
get "/resource", :auth => [:user, :admin] do
"You can access the resource for authorized users"
end
get "/secret", :auth => [:admin] do
"You can accesss the resource only for admins"
end
get "/login" do
haml :login
end
get "/logout", :auth => [:any] do
logout
haml :logout
end
post "/login" do
haml :not_authorized unless $users.include?(params[:email])
@token = generate_auth_token
$tokens[@token] = {:username => params[:email], :expires_at => nil}
haml :authentication_email
end
get "/activate/:token" do
@token = params[:token]
if activate!(params[:token])
haml :authenticated
else
haml :not_authenticated
end
end
__END__
@@layout
!!! 5
%html
%head
%title Sinatra Instant Email Authentication
%body
=yield
@@index
:javascript
fetch = function(url,id) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader('Authentication', 'Token token=' + localStorage.getItem('auth_token') );
xhr.onload = function(e) {
document.getElementById(id).innerHTML = (this.status == 200) ? this.responseText : this.status + ' ' + this.statusText;
};
xhr.send();
}
logout = function() {
window.location.href = "/logout?auth_token=" + localStorage.getItem('auth_token');
}
fetch('/resource', 'resource');
fetch('/secret', 'secret');
%a(href="/login") Login
%a(href="#" onclick="logout();" ) Logout
%p
XHR Repsonse on authorized users:
%span#resource
%p
XHR Response on a secret resource only for admin:
%span#secret
@@login
%form(action="/login" method="post")
%div
%label(for="email")Enter your email:
%input#email(type="text" name="email")
%div
%input(type="submit" value="Login")
@@authentication_email
:javascript
localStorage.setItem('auth_token', '#{@token}');
%p Here is your email for authenticating.
%p In order to login into the system, please follow this link:
%a(href="/activate/#{@token}") Log me in
@@logout
:javascript
localStorage.removeItem('auth_token');
%p You have logged out
%a(href="/") Home
@@authenticated
%p
You have logged in and now you can access your
%a(href="/") home
@@not_authenticated
%p
You activation failed.
@@not_authorized
%p You are not authorized.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment