Skip to content

Commit

Permalink
Kind of running gatekeeper app
Browse files Browse the repository at this point in the history
  • Loading branch information
mpasternacki committed Feb 3, 2015
1 parent 548d0cf commit 51bb880
Show file tree
Hide file tree
Showing 22 changed files with 222 additions and 101 deletions.
4 changes: 4 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ generate_file 'regexp.go' => 'script/compose_regexp.go' do
sh 'go run script/compose_regexp.go > regexp.go'
end

generate_file 'lib/cardea/regexp.rb' => ['regexp.go', 'script/regexp2ruby.pl'] do
sh 'script/regexp2ruby.pl < regexp.go > lib/cardea/regexp.rb'
end

desc 'Generate secondary files'
task :generate => :prereqs
task :generate => GENERATED do
Expand Down
4 changes: 2 additions & 2 deletions cardea-gatekeeper.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ Gem::Specification.new do |spec|
spec.files = %w(LICENSE.txt
README.md
cardea-gatekeeper.gemspec
config.ru
config/gatekeeper.rb
lib/cardea/gatekeeper.rb)
# lib/cardea/gatekeeper/**
Expand All @@ -28,5 +27,6 @@ Gem::Specification.new do |spec|
spec.add_dependency 'erubis', '~> 2.7', '>= 2.7.0'
spec.add_dependency 'sinatra', '~> 1.4', '>= 1.4.5'
spec.add_dependency 'tinyconfig', '~> 0.1', '>= 0.1.1'
spec.add_dependency 'unicorn', '~> 4.8', '>= 4.8.3'
spec.add_dependency 'omniauth', '~> 1.2', '>= 1.2.2'
spec.add_dependency 'haml'
end
2 changes: 0 additions & 2 deletions config.ru

This file was deleted.

1 change: 1 addition & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Gemfile.lock
7 changes: 7 additions & 0 deletions example/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
source 'https://rubygems.org'

gem 'cardea', path: '..'
gem 'cardea-gatekeeper', path: '..'

gem 'omniauth-google-oauth2', '~> 0.2.6'
gem 'unicorn', '~> 4.8', '>= 4.8.3'
16 changes: 16 additions & 0 deletions example/config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'cardea/gatekeeper'

class Gatekeeper < Cardea::Gatekeeper::App
set :cardea_secret, 'SWORDFISH'

omniauth do
provider :developer, :uid_field => :name
end

set :login_href, '/auth/developer'
set :login_text, 'Pretend to log in'
set :company_name, 'Three of Coins'
set :company_url, 'http://3ofcoins.net/'
end

run Gatekeeper.new
Binary file added favicon.ico
Binary file not shown.
4 changes: 4 additions & 0 deletions lib/cardea.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ module Cardea
def self.token(*args)
Token.new(*args)
end

def self.parse(*args)
Token.parse(*args)
end
end
1 change: 0 additions & 1 deletion lib/cardea/gatekeeper.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
require 'cardea'
require 'cardea/gatekeeper/config'
require 'cardea/gatekeeper/app'
115 changes: 90 additions & 25 deletions lib/cardea/gatekeeper/app.rb
Original file line number Diff line number Diff line change
@@ -1,45 +1,110 @@
require 'erubis'
require 'cgi'
require 'haml'
require 'sinatra'

module Cardea
module Gatekeeper
class App < Sinatra::Base
set :erb, escape_html: true
set :root, Config.root_dir
# General Sinatra settings

def config
@config ||= Config.load
end
enable :sessions

set :root, File.expand_path(File.join(
File.dirname(__FILE__), '../../..'))

# Cardea settings

def ref
ref = params[:ref]
ref = url('/') if !ref || ref == ''
ref
set :cardea_secret, ENV['CARDEA_SECRET']
set :company_name, nil
set :company_url, nil
set :cookie_domain, nil
set :cookie_name, 'ca'
set :cookie_secure, nil
set :login_href, 'https://github.com/3ofcoins/cardea/'
set :login_text, 'NOT CONFIGURED'
set :odin_cookie_name, nil

def request_token
return unless request.cookies.include?(settings.cookie_name)
@token ||= Cardea.parse(request.cookies[settings.cookie_name], settings.cardea_secret, *hmac_extras)
rescue => e
# FIXME: proper log?
puts "ERROR parsing cookie: #{e}"
end

get '/' do
erb :landing
if request_token
haml :landing
else
login_url = '/login'
if params[:return_to] && params[:return_to] != ''
login_url << "?return_to=#{CGI.escape(params[:return_to])}"
end
redirect url(login_url), 302
end
end

get '/logout' do
logout
end

get '/login' do
erb :login
if params[:return_to] && params[:return_to] != ''
session[:return_to] = params[:return_to]
else
session.delete(:return_to)
end
haml :login
end

def cookie_parameters
{
domain: settings.cookie_domain || ".#{request.host}",
path: '/',
secure: settings.cookie_secure,
httponly: true,
}
end
private :cookie_parameters

def hmac_extras
[ request.env['HTTP_USER_AGENT'] ]
end

post '/login' do
def login(username, meta={})
tk = Cardea.token(username, meta)
# TODO: expires (smart); ¿max_age?
response.set_cookie config.cardea_cookie,
value: "You are #{params[:username]}",
domain: ".#{request.host}",
secure: config.cookie_secure,
httponly: true
if config.odin_compatible
response.set_cookie config.odin_cookie,
value: "You are #{params[:username]}",
domain: ".#{request.host}",
secure: config.cookie_secure,
httponly: true
response.set_cookie(settings.cookie_name, cookie_parameters.merge(value: tk.cookie(settings.cardea_secret, *hmac_extras)))
response.set_cookie(settings.odin_cookie_name, cookie_parameters.merge(value: tk.legacy.cookie(settings.cardea_secret, *hmac_extras))) if settings.odin_cookie_name
redirect session.delete(:return_to) || url('/'), 303
end

def logout
response.delete_cookie(settings.cookie_name, cookie_parameters)
response.delete_cookie(settings.odin_cookie_name, cookie_parameters) if settings.odin_cookie_name
session.delete(:return_to)
redirect url('/login'), 303
end

# OmniAuth Integration

def omniauth_username(auth)
auth['uid']
end

def omniauth_extras(auth)
{}
end

def self.omniauth(&block)
require 'omniauth'

use OmniAuth::Builder, &block

post '/auth/:name/callback' do
auth = request.env['omniauth.auth']
login(omniauth_username(auth), omniauth_extras(auth))
end
redirect ref, 303
end
end
end
Expand Down
30 changes: 0 additions & 30 deletions lib/cardea/gatekeeper/config.rb

This file was deleted.

3 changes: 3 additions & 0 deletions lib/cardea/regexp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module Cardea
TOKEN_RX = Regexp.compile("\\A[\\t-\\n\\f-\\r ]*(?<USERNAME>[\\--9A-Z_a-z]+)(?<PAYLOAD>,(?<LEGACY_GROUPS>[\\--9A-Z_a-z]*),(?<LEGACY_TIMESTAMP>[0-9]+),|:(?:(?<FORMAT>[0-9A-Z_a-z]+)\\?)?(?<QUERY>[^#]+)#)(?<HMAC>[0-9a-f]+|[\\--9A-Z_a-z]+)[\\t-\\n\\f-\\r ]*(?-m:$)");
end
40 changes: 36 additions & 4 deletions lib/cardea/token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'hashie'

require 'cardea/helpers'
require 'cardea/regexp'

module Cardea
class Token < Hashie::Mash
Expand Down Expand Up @@ -57,22 +58,35 @@ def hmac(secret, *hmac_extras)
encode_hmac(
OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, secret, [
to_s,
Helpers.b64(hmac_extras.map(&:to_s).join("\r\n")),
encode_extras(hmac_extras),
].join(cardea_glue)))
end

def encode_hmac(bin_hmac)
def self.encode_hmac(bin_hmac)
Helpers.b64(bin_hmac)
end

def cookie(secret, *hmac_extras)
[to_s, hmac(secret, *hmac_extras)].join(cardea_glue)
end

def basic_auth(secret, hmac_extras)
def basic_auth(secret, *hmac_extras)
"Basic #{Base64.strict_encode64(cookie(secret, hmac_extras))}"
end

def self.parse(cookie, secret, *hmac_extras)
if cookie =~ TOKEN_RX
m = Regexp.last_match
raise "Unsupported legacy cookie" if m[:LEGACY_TIMESTAMP]
computed_hmac = encode_hmac(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, secret,
"#{m[:USERNAME]}:#{m[:QUERY]}##{encode_extras(hmac_extras)}"))
raise "HMAC mismatch" if computed_hmac != m[:HMAC]
return self.new(m[:USERNAME], CGI.parse(m[:QUERY]))
else
raise "Invalid cookie"
end
end

def legacy
Odin[self]
end
Expand All @@ -82,7 +96,7 @@ def to_s
[Helpers.b64(user), Helpers.b64(g.join(',')), t.to_s].join(',')
end

def encode_hmac(bin_hmac)
def self.encode_hmac(bin_hmac)
Digest.hexencode(bin_hmac)
end

Expand All @@ -93,6 +107,24 @@ def cardea_glue
def basic_auth(_secret, _hmac_extras)
fail NotImplementedError
end

def self.parse(_cookie, _secret, *_hmac_extras)
fail NotImplementedError
end
end

private

def self.encode_extras(hmac_extras)
Helpers.b64(hmac_extras.map(&:to_s).join("\r\n"))
end

def encode_extras(hmac_extras)
self.class.encode_extras(hmac_extras)
end

def encode_hmac(bin_hmac)
self.class.encode_hmac(bin_hmac)
end
end
end
Binary file added public/img/cardea-max-600.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/img/cardea-max-otwarte-600.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions script/regexp2ruby.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env perl
use warnings;
use strict;

print "module Cardea\n";

while (<>) {
/^\s*var\s+(\w+)\s*=\s*regexp\.MustCompile\(\"(.*)\"\)$/ or next;
my ($name, $rx) = ($1, $2);
$rx =~ s/\(\?P</(?</g;
print " $name = Regexp.compile(\"$rx\");\n";
}

print "end\n";
1 change: 0 additions & 1 deletion views/landing.erb

This file was deleted.

6 changes: 6 additions & 0 deletions views/landing.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
%p.lead
Hello,
= succeed '!' do
%em= request_token.user

%a.btn.btn-default.btn-lg.btn-block{href: url('/logout')} Sign Out
28 changes: 0 additions & 28 deletions views/layout.erb

This file was deleted.

Loading

0 comments on commit 51bb880

Please sign in to comment.