-
-
Save pketh/0ec4095d4a808b596a1e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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