diff options
author | Lionel Elie Mamane <lionel@mamane.lu> | 2012-06-25 03:54:34 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2012-06-25 03:54:34 +0000 |
commit | 1ace6029b574443965ef6b2fc872f6517b430e20 (patch) | |
tree | c6c17ae994e2b4c09997c6fc39a9117fb461087a | |
parent | 836a4116373a69f6dbe9e909780403c5971fa390 (diff) | |
download | local-openid-1ace6029b574443965ef6b2fc872f6517b430e20.tar.gz |
separate OpenID Provider identifier and user identifier to be distinct
As per OpenID Authentication 2.0 specification section 11.2, the two are not allowed to be equal. The user identifier is unchanged: http://${HOST}/ The provider identifier (and provider endpoint URL) is now http://${HOST}/provider Signed-off-by: Eric Wong <normalperson@yhbt.net>
-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 |