diff options
-rw-r--r-- | lib/local_openid.rb | 85 |
1 files changed, 62 insertions, 23 deletions
diff --git a/lib/local_openid.rb b/lib/local_openid.rb index 3d87d5f..ab342a9 100644 --- a/lib/local_openid.rb +++ b/lib/local_openid.rb @@ -23,9 +23,12 @@ class LocalOpenID < Sinatra::Base Dir.mkdir(@@dir) unless File.directory?(@@dir) # all the sinatra endpoints: - get('/xrds') { big_lock { render_xrds(true) } } - get('/') { big_lock { get_or_post } } - post('/') { big_lock { get_or_post } } + get('/xrds') { big_lock { render_identity_xrds(true) } } + get('/provider/xrds') { big_lock { render_provider_xrds(true) } } + get('/provider') { big_lock { get_or_post_provider } } + post('/provider') { big_lock { get_or_post_provider } } + get('/') { big_lock { render_identity_xrds } } + post('/') { big_lock { render_identity_xrds } } private @@ -35,21 +38,44 @@ class LocalOpenID < Sinatra::Base <body><h1>reload this page when approved: %s</h1></body> </html>! - XRDS_HTML = %q!<html><head> - <link rel="openid.server" href="%s" /> - <link rel="openid2.provider" href="%s" /> - <meta http-equiv="X-XRDS-Location" content="%sxrds" /> + PROVIDER_XRDS_HTML = %q!<html><head> + <meta http-equiv="X-XRDS-Location" content="%sprovider/xrds" /> <title>OpenID server endpoint</title> </head><body>OpenID server endpoint</body></html>! - XRDS_XML = %q!<?xml version="1.0" encoding="UTF-8"?> + IDENTITY_XRDS_HTML = %q!<html><head> + <link rel="openid.server" href="%sprovider" /> + <link rel="openid2.provider" href="%sprovider" /> + <link rel="openid2.local_id" href="%s" /> + <link rel="openid.delegate" href="%s" /> + <meta http-equiv="X-XRDS-Location" content="%sxrds" /> + <title>OpenID identity</title> + </head><body>OpenID identity</body></html>! + + PROVIDER_XRDS_XML = %q!<?xml version="1.0" encoding="UTF-8"?> + <xrds:XRDS + xmlns:xrds="xri://$xrds" + xmlns:openid="http://openid.net/xmlns/1.0" + xmlns="xri://$xrd*($v*2.0)"> + <XRD version="2.0"> + <Service priority="0"> + %types + <URI>%sprovider</URI> + </Service> + </XRD> + </xrds:XRDS>! + + IDENTITY_XRDS_XML = %q!<?xml version="1.0" encoding="UTF-8"?> <xrds:XRDS xmlns:xrds="xri://$xrds" + xmlns:openid="http://openid.net/xmlns/1.0" xmlns="xri://$xrd*($v*2.0)"> - <XRD> + <XRD version="2.0"> <Service priority="0"> %types - <URI>%s</URI> + <URI>%sprovider</URI> + <LocalID>%s</LocalID> + <openid:Delegate>%s</openid:Delegate> </Service> </XRD> </xrds:XRDS>! @@ -81,7 +107,7 @@ class LocalOpenID < Sinatra::Base - updated Time this entry was updated, strictly informational. - session_id Unique identifier in your session cookie to prevent other users from hijacking your session. You may - delete this if you've changed browsers or computers. + delete this if you have changed browsers or computers. - assoc_handle See the OpenID specs, may be empty. Do not edit this. SReg keys supported by the Ruby OpenID implementation should be @@ -97,14 +123,14 @@ class LocalOpenID < Sinatra::Base # this is the heart of our provider logic, adapted from the # Ruby OpenID gem Rails example - def get_or_post + def get_or_post_provider oidreq = begin server.decode_request(params) rescue ProtocolError => err halt(500, err.to_s) end - oidreq or return render_xrds + oidreq or return render_provider_xrds oidresp = case oidreq when CheckIDRequest @@ -116,7 +142,7 @@ class LocalOpenID < Sinatra::Base add_pape(oidreq, resp) resp elsif oidreq.immediate - oidreq.answer(false, server_root) + oidreq.answer(false, server_root + "provider") else session[:id] ||= "#{Time.now.to_i}.#$$.#{rand}" session[:ip] = request.ip @@ -144,7 +170,7 @@ class LocalOpenID < Sinatra::Base def server @server ||= Server.new( OpenID::Store::Filesystem.new("#@@dir/store"), - server_root) + server_root + "provider") end # support the simple registration extension if possible, @@ -264,22 +290,35 @@ class LocalOpenID < Sinatra::Base end # this output is designed to be parsed by OpenID consumers - def render_xrds(force = false) + def render_provider_xrds(force = false) + if force || request.accept.include?('application/xrds+xml') + + # this seems to work... + types = [ OpenID::OPENID_IDP_2_0_TYPE ] + + headers['Content-Type'] = 'application/xrds+xml' + types = types.map { |uri| "<Type>#{uri}</Type>" }.join("\n") + PROVIDER_XRDS_XML.gsub(/%s/, server_root).gsub!(/%types/, types) + else # render a browser-friendly page with an XRDS pointer + headers['X-XRDS-Location'] = "#{server_root}provider/xrds" + PROVIDER_XRDS_HTML.gsub(/%s/, server_root) + end + end + + def render_identity_xrds(force = false) if force || request.accept.include?('application/xrds+xml') # this seems to work... - types = request.accept.include?('application/xrds+xml') ? - [ OpenID::OPENID_2_0_TYPE, - OpenID::OPENID_1_0_TYPE, - OpenID::SREG_URI ] : - [ OpenID::OPENID_IDP_2_0_TYPE ] + types = [ OpenID::OPENID_2_0_TYPE, + OpenID::OPENID_1_0_TYPE, + OpenID::SREG_URI ] headers['Content-Type'] = 'application/xrds+xml' types = types.map { |uri| "<Type>#{uri}</Type>" }.join("\n") - XRDS_XML.gsub(/%s/, server_root).gsub!(/%types/, types) + IDENTITY_XRDS_XML.gsub(/%s/, server_root).gsub!(/%types/, types) else # render a browser-friendly page with an XRDS pointer headers['X-XRDS-Location'] = "#{server_root}xrds" - XRDS_HTML.gsub(/%s/, server_root) + IDENTITY_XRDS_HTML.gsub(/%s/, server_root) end end |