Skip to content

Instantly share code, notes, and snippets.

@baroquebobcat
Created September 14, 2009 14:06
Show Gist options
  • Select an option

  • Save baroquebobcat/186661 to your computer and use it in GitHub Desktop.

Select an option

Save baroquebobcat/186661 to your computer and use it in GitHub Desktop.
require 'openid_provider_sinatra'
use Rack::Auth::Basic do |username,password|
'secret' == password
end
run OpenIDProvider.new nil, :store=>OpenID::Store::Filesystem.new(Dir.pwd + '/openid-store'),
:user=>Proc.new {|env|
login=env['REMOTE_USER']
return nil unless login
OpenStruct.new :login=>login,:url=>"http://id.example.com/#{login}"
}
require 'rubygems'
require 'sinatra/base'
require 'openid'
require 'openid/consumer/discovery'
require 'openid/extensions/sreg'
require 'openid/extensions/pape'
require 'openid/store/filesystem'
#copied and pasted and transformed to make more sensical and not old rails from
# ruby-openid/examples/rails_openid
class OpenIDProvider < Sinatra::Base
include OpenID::Server
SUPPORTED_TYPES = {
:xrds=>[
OpenID::OPENID_2_0_TYPE,
OpenID::OPENID_1_0_TYPE,
OpenID::SREG_URI,
],
:idp_xrds=>[
OpenID::OPENID_IDP_2_0_TYPE,
]
}
def initialize app=nil,options={}
super app
options = {
:store=>OpenID::Store::Filesystem.new(Dir.pwd + '/openid-store')
}.merge options
@user_block = options[:user]
@mount='/'
@store= options[:store]
end
def server
@server ||= Server.new(@store, @mount)
end
helpers do
def current_user
@user_block.call request.env
end
def logged_in?
!!current_user
end
def send_openid_response
#doesn't actually do anythingvv
# if @oid_response.needs_signing
# signed_response = server.signatory.sign(@oid_response)
# end
add_sreg
add_pape
web_response = server.encode_response(@oid_response)
#headers=web_response.headers
#status=web_response.code
#web_response.body
case web_response.code
when HTTP_OK
status 200
web_response.body
when HTTP_REDIRECT
redirect web_response.headers['location']
else
status 400
web_response.body
end
end
def oid_request
@oid_request ||= session[:last_oidreq]||server.decode_request(params)
rescue ProtocolError=>e
puts e
end
def sreg_request
@sreg_request ||= OpenID::SReg::Request.from_openid_request oid_request
end
def pape_request
@pape_request ||= OpenID::PAPE::Request.from_openid_request oid_request
end
def add_sreg
return unless sreg_request
# In a real application, this data would be user-specific,
# and the user should be asked for permission to release
# it.
sreg_data = {
'nickname' => session[:username],
'fullname' => 'Mayor McCheese',
'email' => 'mayor@example.com'
}
sregresp = OpenID::SReg::Response.extract_response(sreg_request, sreg_data)
@oid_response.add_extension(sregresp)
end
def add_pape
return unless pape_request
paperesp = OpenID::PAPE::Response.new
paperesp.nist_auth_level = 0 # we don't even do auth at all!
@oid_response.add_extension(paperesp)
end
def show_decision_page oid_r, message='Do you trust this site with your identity?'
session[:last_oidreq]=oid_r
@oid_r=oid_r
#flash[:notice] if message
puts sreg_request.all_requested_fields if sreg_request
end
def is_authorized? id_url,trust_root
logged_in? && id_url == current_user.url && approved?(trust_root)
end
def approved? trust_root
session[:approvals] && session[:approvals].member?(trust_root)
end
end
get '/' do
return "This is an OpenID server endpoint. #{current_user.login}" unless params['openid.mode']
case oid_request
when CheckIDRequest
identity = if logged_in?
current_user.url
else
@oid_request.identity
end
@oid_response = if oid_request.immediate
if oid_request.id_select
oid_request.answer false
elsif is_authorized?(identity, oid_request.trust_root)
oid_request.answer(true, nil, identity)
else
oid_request.answer false, server_url
end
elsif logged_in? && is_authorized?(identity, oid_request.trust_root)
oid_request.answer(true, nil, identity)
end
unless @oid_response
show_decision_page(oid_request)
end
else
@oid_response = server.handle_request(oid_request)
end
send_openid_response
end
post '/decision' do
#oidreq = session[:last_oidreq]
session[:last_oidreq] = nil
unless params[:yes]
redirect_to oid_request.cancel_url
return
else
id_to_send = params[:id_to_send]
identity = oid_request.identity
if oid_request.id_select
if id_to_send and id_to_send != ""
session[:username] = id_to_send
session[:approvals] = []
identity = current_user.url
else
msg = "You must enter a username to in order to send " +
"an identifier to the Relying Party."
show_decision_page(oidreq, msg)
return
end
end
if session[:approvals]
session[:approvals] << oidreq.trust_root
else
session[:approvals] = [oidreq.trust_root]
end
oidresp = oidreq.answer(true, nil, identity)
add_sreg(oidreq, oidresp)
add_pape(oidreq, oidresp)
return self.render_response(oidresp)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment