pelle-ruby-openid 2.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +215 -0
- data/CHANGES-2.1.0 +36 -0
- data/INSTALL +47 -0
- data/LICENSE +210 -0
- data/NOTICE +2 -0
- data/README +82 -0
- data/UPGRADE +127 -0
- data/VERSION +1 -0
- data/examples/README +32 -0
- data/examples/active_record_openid_store/README +58 -0
- data/examples/active_record_openid_store/XXX_add_open_id_store_to_db.rb +24 -0
- data/examples/active_record_openid_store/XXX_upgrade_open_id_store.rb +26 -0
- data/examples/active_record_openid_store/init.rb +8 -0
- data/examples/active_record_openid_store/lib/association.rb +10 -0
- data/examples/active_record_openid_store/lib/nonce.rb +3 -0
- data/examples/active_record_openid_store/lib/open_id_setting.rb +4 -0
- data/examples/active_record_openid_store/lib/openid_ar_store.rb +57 -0
- data/examples/active_record_openid_store/test/store_test.rb +212 -0
- data/examples/discover +49 -0
- data/examples/rails_openid/README +153 -0
- data/examples/rails_openid/Rakefile +10 -0
- data/examples/rails_openid/app/controllers/application.rb +4 -0
- data/examples/rails_openid/app/controllers/consumer_controller.rb +122 -0
- data/examples/rails_openid/app/controllers/login_controller.rb +45 -0
- data/examples/rails_openid/app/controllers/server_controller.rb +265 -0
- data/examples/rails_openid/app/helpers/application_helper.rb +3 -0
- data/examples/rails_openid/app/helpers/login_helper.rb +2 -0
- data/examples/rails_openid/app/helpers/server_helper.rb +9 -0
- data/examples/rails_openid/app/views/consumer/index.rhtml +81 -0
- data/examples/rails_openid/app/views/layouts/server.rhtml +68 -0
- data/examples/rails_openid/app/views/login/index.rhtml +56 -0
- data/examples/rails_openid/app/views/server/decide.rhtml +26 -0
- data/examples/rails_openid/config/boot.rb +19 -0
- data/examples/rails_openid/config/database.yml +74 -0
- data/examples/rails_openid/config/environment.rb +54 -0
- data/examples/rails_openid/config/environments/development.rb +19 -0
- data/examples/rails_openid/config/environments/production.rb +19 -0
- data/examples/rails_openid/config/environments/test.rb +19 -0
- data/examples/rails_openid/config/routes.rb +24 -0
- data/examples/rails_openid/doc/README_FOR_APP +2 -0
- data/examples/rails_openid/public/.htaccess +40 -0
- data/examples/rails_openid/public/404.html +8 -0
- data/examples/rails_openid/public/500.html +8 -0
- data/examples/rails_openid/public/dispatch.cgi +12 -0
- data/examples/rails_openid/public/dispatch.fcgi +26 -0
- data/examples/rails_openid/public/dispatch.rb +12 -0
- data/examples/rails_openid/public/favicon.ico +0 -0
- data/examples/rails_openid/public/images/openid_login_bg.gif +0 -0
- data/examples/rails_openid/public/javascripts/controls.js +750 -0
- data/examples/rails_openid/public/javascripts/dragdrop.js +584 -0
- data/examples/rails_openid/public/javascripts/effects.js +854 -0
- data/examples/rails_openid/public/javascripts/prototype.js +1785 -0
- data/examples/rails_openid/public/robots.txt +1 -0
- data/examples/rails_openid/script/about +3 -0
- data/examples/rails_openid/script/breakpointer +3 -0
- data/examples/rails_openid/script/console +3 -0
- data/examples/rails_openid/script/destroy +3 -0
- data/examples/rails_openid/script/generate +3 -0
- data/examples/rails_openid/script/performance/benchmarker +3 -0
- data/examples/rails_openid/script/performance/profiler +3 -0
- data/examples/rails_openid/script/plugin +3 -0
- data/examples/rails_openid/script/process/reaper +3 -0
- data/examples/rails_openid/script/process/spawner +3 -0
- data/examples/rails_openid/script/process/spinner +3 -0
- data/examples/rails_openid/script/runner +3 -0
- data/examples/rails_openid/script/server +3 -0
- data/examples/rails_openid/test/functional/login_controller_test.rb +18 -0
- data/examples/rails_openid/test/functional/server_controller_test.rb +18 -0
- data/examples/rails_openid/test/test_helper.rb +28 -0
- data/lib/hmac/hmac.rb +112 -0
- data/lib/hmac/sha1.rb +11 -0
- data/lib/hmac/sha2.rb +25 -0
- data/lib/openid/association.rb +249 -0
- data/lib/openid/consumer/associationmanager.rb +344 -0
- data/lib/openid/consumer/checkid_request.rb +186 -0
- data/lib/openid/consumer/discovery.rb +498 -0
- data/lib/openid/consumer/discovery_manager.rb +123 -0
- data/lib/openid/consumer/html_parse.rb +134 -0
- data/lib/openid/consumer/idres.rb +523 -0
- data/lib/openid/consumer/responses.rb +148 -0
- data/lib/openid/consumer.rb +395 -0
- data/lib/openid/cryptutil.rb +97 -0
- data/lib/openid/dh.rb +89 -0
- data/lib/openid/extension.rb +39 -0
- data/lib/openid/extensions/ax.rb +516 -0
- data/lib/openid/extensions/oauth.rb +91 -0
- data/lib/openid/extensions/pape.rb +179 -0
- data/lib/openid/extensions/sreg.rb +277 -0
- data/lib/openid/extras.rb +11 -0
- data/lib/openid/fetchers.rb +238 -0
- data/lib/openid/kvform.rb +136 -0
- data/lib/openid/kvpost.rb +58 -0
- data/lib/openid/message.rb +553 -0
- data/lib/openid/protocolerror.rb +8 -0
- data/lib/openid/server.rb +1544 -0
- data/lib/openid/store/filesystem.rb +271 -0
- data/lib/openid/store/interface.rb +75 -0
- data/lib/openid/store/memcache.rb +107 -0
- data/lib/openid/store/memory.rb +84 -0
- data/lib/openid/store/nonce.rb +68 -0
- data/lib/openid/trustroot.rb +349 -0
- data/lib/openid/urinorm.rb +75 -0
- data/lib/openid/util.rb +110 -0
- data/lib/openid/yadis/accept.rb +148 -0
- data/lib/openid/yadis/constants.rb +21 -0
- data/lib/openid/yadis/discovery.rb +153 -0
- data/lib/openid/yadis/filters.rb +205 -0
- data/lib/openid/yadis/htmltokenizer.rb +305 -0
- data/lib/openid/yadis/parsehtml.rb +45 -0
- data/lib/openid/yadis/services.rb +42 -0
- data/lib/openid/yadis/xrds.rb +155 -0
- data/lib/openid/yadis/xri.rb +90 -0
- data/lib/openid/yadis/xrires.rb +106 -0
- data/lib/openid.rb +20 -0
- data/setup.rb +1551 -0
- data/test/data/accept.txt +124 -0
- data/test/data/dh.txt +29 -0
- data/test/data/example-xrds.xml +14 -0
- data/test/data/linkparse.txt +587 -0
- data/test/data/n2b64 +650 -0
- data/test/data/test1-discover.txt +137 -0
- data/test/data/test1-parsehtml.txt +152 -0
- data/test/data/test_discover/malformed_meta_tag.html +19 -0
- data/test/data/test_discover/openid.html +11 -0
- data/test/data/test_discover/openid2.html +11 -0
- data/test/data/test_discover/openid2_xrds.xml +12 -0
- data/test/data/test_discover/openid2_xrds_no_local_id.xml +11 -0
- data/test/data/test_discover/openid_1_and_2.html +11 -0
- data/test/data/test_discover/openid_1_and_2_xrds.xml +16 -0
- data/test/data/test_discover/openid_1_and_2_xrds_bad_delegate.xml +17 -0
- data/test/data/test_discover/openid_and_yadis.html +12 -0
- data/test/data/test_discover/openid_no_delegate.html +10 -0
- data/test/data/test_discover/yadis_0entries.xml +12 -0
- data/test/data/test_discover/yadis_2_bad_local_id.xml +15 -0
- data/test/data/test_discover/yadis_2entries_delegate.xml +22 -0
- data/test/data/test_discover/yadis_2entries_idp.xml +21 -0
- data/test/data/test_discover/yadis_another_delegate.xml +14 -0
- data/test/data/test_discover/yadis_idp.xml +12 -0
- data/test/data/test_discover/yadis_idp_delegate.xml +13 -0
- data/test/data/test_discover/yadis_no_delegate.xml +11 -0
- data/test/data/test_xrds/=j3h.2007.11.14.xrds +25 -0
- data/test/data/test_xrds/README +12 -0
- data/test/data/test_xrds/delegated-20060809-r1.xrds +34 -0
- data/test/data/test_xrds/delegated-20060809-r2.xrds +34 -0
- data/test/data/test_xrds/delegated-20060809.xrds +34 -0
- data/test/data/test_xrds/no-xrd.xml +7 -0
- data/test/data/test_xrds/not-xrds.xml +2 -0
- data/test/data/test_xrds/prefixsometimes.xrds +34 -0
- data/test/data/test_xrds/ref.xrds +109 -0
- data/test/data/test_xrds/sometimesprefix.xrds +34 -0
- data/test/data/test_xrds/spoof1.xrds +25 -0
- data/test/data/test_xrds/spoof2.xrds +25 -0
- data/test/data/test_xrds/spoof3.xrds +37 -0
- data/test/data/test_xrds/status222.xrds +9 -0
- data/test/data/test_xrds/subsegments.xrds +58 -0
- data/test/data/test_xrds/valid-populated-xrds.xml +39 -0
- data/test/data/trustroot.txt +153 -0
- data/test/data/urinorm.txt +79 -0
- data/test/discoverdata.rb +131 -0
- data/test/test_accept.rb +170 -0
- data/test/test_association.rb +266 -0
- data/test/test_associationmanager.rb +917 -0
- data/test/test_ax.rb +648 -0
- data/test/test_checkid_request.rb +294 -0
- data/test/test_consumer.rb +257 -0
- data/test/test_cryptutil.rb +119 -0
- data/test/test_dh.rb +86 -0
- data/test/test_discover.rb +838 -0
- data/test/test_discovery_manager.rb +262 -0
- data/test/test_extension.rb +46 -0
- data/test/test_extras.rb +35 -0
- data/test/test_fetchers.rb +538 -0
- data/test/test_filters.rb +270 -0
- data/test/test_idres.rb +963 -0
- data/test/test_kvform.rb +165 -0
- data/test/test_kvpost.rb +65 -0
- data/test/test_linkparse.rb +101 -0
- data/test/test_message.rb +1116 -0
- data/test/test_nonce.rb +89 -0
- data/test/test_oauth.rb +175 -0
- data/test/test_openid_yadis.rb +178 -0
- data/test/test_pape.rb +247 -0
- data/test/test_parsehtml.rb +80 -0
- data/test/test_responses.rb +63 -0
- data/test/test_server.rb +2457 -0
- data/test/test_sreg.rb +479 -0
- data/test/test_stores.rb +298 -0
- data/test/test_trustroot.rb +113 -0
- data/test/test_urinorm.rb +35 -0
- data/test/test_util.rb +145 -0
- data/test/test_xrds.rb +169 -0
- data/test/test_xri.rb +48 -0
- data/test/test_xrires.rb +63 -0
- data/test/test_yadis_discovery.rb +220 -0
- data/test/testutil.rb +127 -0
- data/test/util.rb +53 -0
- metadata +316 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
require 'openid/yadis/filters'
|
3
|
+
require 'openid/yadis/discovery'
|
4
|
+
require 'openid/yadis/xrds'
|
5
|
+
|
6
|
+
module OpenID
|
7
|
+
module Yadis
|
8
|
+
def Yadis.get_service_endpoints(input_url, flt=nil)
|
9
|
+
# Perform the Yadis protocol on the input URL and return an
|
10
|
+
# iterable of resulting endpoint objects.
|
11
|
+
#
|
12
|
+
# @param flt: A filter object or something that is convertable
|
13
|
+
# to a filter object (using mkFilter) that will be used to
|
14
|
+
# generate endpoint objects. This defaults to generating
|
15
|
+
# BasicEndpoint objects.
|
16
|
+
result = Yadis.discover(input_url)
|
17
|
+
begin
|
18
|
+
endpoints = Yadis.apply_filter(result.normalized_uri,
|
19
|
+
result.response_text, flt)
|
20
|
+
rescue XRDSError => err
|
21
|
+
raise DiscoveryFailure.new(err.to_s, nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
return [result.normalized_uri, endpoints]
|
25
|
+
end
|
26
|
+
|
27
|
+
def Yadis.apply_filter(normalized_uri, xrd_data, flt=nil)
|
28
|
+
# Generate an iterable of endpoint objects given this input data,
|
29
|
+
# presumably from the result of performing the Yadis protocol.
|
30
|
+
|
31
|
+
flt = Yadis.make_filter(flt)
|
32
|
+
et = Yadis.parseXRDS(xrd_data)
|
33
|
+
|
34
|
+
endpoints = []
|
35
|
+
each_service(et) { |service_element|
|
36
|
+
endpoints += flt.get_service_endpoints(normalized_uri, service_element)
|
37
|
+
}
|
38
|
+
|
39
|
+
return endpoints
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'rexml/element'
|
3
|
+
require 'rexml/xpath'
|
4
|
+
|
5
|
+
require 'openid/yadis/xri'
|
6
|
+
|
7
|
+
module OpenID
|
8
|
+
module Yadis
|
9
|
+
|
10
|
+
XRD_NS_2_0 = 'xri://$xrd*($v*2.0)'
|
11
|
+
XRDS_NS = 'xri://$xrds'
|
12
|
+
|
13
|
+
XRDS_NAMESPACES = {
|
14
|
+
'xrds' => XRDS_NS,
|
15
|
+
'xrd' => XRD_NS_2_0,
|
16
|
+
}
|
17
|
+
|
18
|
+
class XRDSError < StandardError; end
|
19
|
+
|
20
|
+
# Raised when there's an assertion in the XRDS that it does not
|
21
|
+
# have the authority to make.
|
22
|
+
class XRDSFraud < XRDSError
|
23
|
+
end
|
24
|
+
|
25
|
+
def Yadis::get_canonical_id(iname, xrd_tree)
|
26
|
+
# Return the CanonicalID from this XRDS document.
|
27
|
+
#
|
28
|
+
# @param iname: the XRI being resolved.
|
29
|
+
# @type iname: unicode
|
30
|
+
#
|
31
|
+
# @param xrd_tree: The XRDS output from the resolver.
|
32
|
+
#
|
33
|
+
# @returns: The XRI CanonicalID or None.
|
34
|
+
# @returntype: unicode or None
|
35
|
+
|
36
|
+
xrd_list = []
|
37
|
+
REXML::XPath::match(xrd_tree.root, '/xrds:XRDS/xrd:XRD', XRDS_NAMESPACES).each { |el|
|
38
|
+
xrd_list << el
|
39
|
+
}
|
40
|
+
|
41
|
+
xrd_list.reverse!
|
42
|
+
|
43
|
+
cid_elements = []
|
44
|
+
|
45
|
+
if !xrd_list.empty?
|
46
|
+
xrd_list[0].elements.each { |e|
|
47
|
+
if !e.respond_to?('name')
|
48
|
+
next
|
49
|
+
end
|
50
|
+
if e.name == 'CanonicalID'
|
51
|
+
cid_elements << e
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
cid_element = cid_elements[0]
|
57
|
+
|
58
|
+
if !cid_element
|
59
|
+
return nil
|
60
|
+
end
|
61
|
+
|
62
|
+
canonicalID = XRI.make_xri(cid_element.text)
|
63
|
+
|
64
|
+
childID = canonicalID.downcase
|
65
|
+
|
66
|
+
xrd_list[1..-1].each { |xrd|
|
67
|
+
parent_sought = childID[0...childID.rindex('!')]
|
68
|
+
|
69
|
+
parent = XRI.make_xri(xrd.elements["CanonicalID"].text)
|
70
|
+
|
71
|
+
if parent_sought != parent.downcase
|
72
|
+
raise XRDSFraud.new(sprintf("%s can not come from %s", parent_sought,
|
73
|
+
parent))
|
74
|
+
end
|
75
|
+
|
76
|
+
childID = parent_sought
|
77
|
+
}
|
78
|
+
|
79
|
+
root = XRI.root_authority(iname)
|
80
|
+
if not XRI.provider_is_authoritative(root, childID)
|
81
|
+
raise XRDSFraud.new(sprintf("%s can not come from root %s", childID, root))
|
82
|
+
end
|
83
|
+
|
84
|
+
return canonicalID
|
85
|
+
end
|
86
|
+
|
87
|
+
class XRDSError < StandardError
|
88
|
+
end
|
89
|
+
|
90
|
+
def Yadis::parseXRDS(text)
|
91
|
+
if text.nil?
|
92
|
+
raise XRDSError.new("Not an XRDS document.")
|
93
|
+
end
|
94
|
+
|
95
|
+
begin
|
96
|
+
d = REXML::Document.new(text)
|
97
|
+
rescue RuntimeError => why
|
98
|
+
raise XRDSError.new("Not an XRDS document. Failed to parse XML.")
|
99
|
+
end
|
100
|
+
|
101
|
+
if is_xrds?(d)
|
102
|
+
return d
|
103
|
+
else
|
104
|
+
raise XRDSError.new("Not an XRDS document.")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def Yadis::is_xrds?(xrds_tree)
|
109
|
+
xrds_root = xrds_tree.root
|
110
|
+
return (!xrds_root.nil? and
|
111
|
+
xrds_root.name == 'XRDS' and
|
112
|
+
xrds_root.namespace == XRDS_NS)
|
113
|
+
end
|
114
|
+
|
115
|
+
def Yadis::get_yadis_xrd(xrds_tree)
|
116
|
+
REXML::XPath.each(xrds_tree.root,
|
117
|
+
'/xrds:XRDS/xrd:XRD[last()]',
|
118
|
+
XRDS_NAMESPACES) { |el|
|
119
|
+
return el
|
120
|
+
}
|
121
|
+
raise XRDSError.new("No XRD element found.")
|
122
|
+
end
|
123
|
+
|
124
|
+
# aka iterServices in Python
|
125
|
+
def Yadis::each_service(xrds_tree, &block)
|
126
|
+
xrd = get_yadis_xrd(xrds_tree)
|
127
|
+
xrd.each_element('Service', &block)
|
128
|
+
end
|
129
|
+
|
130
|
+
def Yadis::services(xrds_tree)
|
131
|
+
s = []
|
132
|
+
each_service(xrds_tree) { |service|
|
133
|
+
s << service
|
134
|
+
}
|
135
|
+
return s
|
136
|
+
end
|
137
|
+
|
138
|
+
def Yadis::expand_service(service_element)
|
139
|
+
es = service_element.elements
|
140
|
+
uris = es.each('URI') { |u| }
|
141
|
+
uris = prio_sort(uris)
|
142
|
+
types = es.each('Type/text()')
|
143
|
+
# REXML::Text objects are not strings.
|
144
|
+
types = types.collect { |t| t.to_s }
|
145
|
+
uris.collect { |uri| [types, uri.text, service_element] }
|
146
|
+
end
|
147
|
+
|
148
|
+
# Sort a list of elements that have priority attributes.
|
149
|
+
def Yadis::prio_sort(elements)
|
150
|
+
elements.sort { |a,b|
|
151
|
+
a.attribute('priority').to_s.to_i <=> b.attribute('priority').to_s.to_i
|
152
|
+
}
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'openid/yadis/xrds'
|
2
|
+
require 'openid/fetchers'
|
3
|
+
|
4
|
+
module OpenID
|
5
|
+
module Yadis
|
6
|
+
module XRI
|
7
|
+
|
8
|
+
# The '(' is for cross-reference authorities, and hopefully has a
|
9
|
+
# matching ')' somewhere.
|
10
|
+
XRI_AUTHORITIES = ["!", "=", "@", "+", "$", "("]
|
11
|
+
|
12
|
+
def self.identifier_scheme(identifier)
|
13
|
+
if (!identifier.nil? and
|
14
|
+
identifier.length > 0 and
|
15
|
+
(identifier.match('^xri://') or
|
16
|
+
XRI_AUTHORITIES.member?(identifier[0].chr)))
|
17
|
+
return :xri
|
18
|
+
else
|
19
|
+
return :uri
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Transform an XRI reference to an IRI reference. Note this is
|
24
|
+
# not not idempotent, so do not apply this to an identifier more
|
25
|
+
# than once. XRI Syntax section 2.3.1
|
26
|
+
def self.to_iri_normal(xri)
|
27
|
+
iri = xri.dup
|
28
|
+
iri.insert(0, 'xri://') if not iri.match('^xri://')
|
29
|
+
return escape_for_iri(iri)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Note this is not not idempotent, so do not apply this more than
|
33
|
+
# once. XRI Syntax section 2.3.2
|
34
|
+
def self.escape_for_iri(xri)
|
35
|
+
esc = xri.dup
|
36
|
+
# encode all %
|
37
|
+
esc.gsub!(/%/, '%25')
|
38
|
+
esc.gsub!(/\((.*?)\)/) { |xref_match|
|
39
|
+
xref_match.gsub(/[\/\?\#]/) { |char_match|
|
40
|
+
CGI::escape(char_match)
|
41
|
+
}
|
42
|
+
}
|
43
|
+
return esc
|
44
|
+
end
|
45
|
+
|
46
|
+
# Transform an XRI reference to a URI reference. Note this is not
|
47
|
+
# not idempotent, so do not apply this to an identifier more than
|
48
|
+
# once. XRI Syntax section 2.3.1
|
49
|
+
def self.to_uri_normal(xri)
|
50
|
+
return iri_to_uri(to_iri_normal(xri))
|
51
|
+
end
|
52
|
+
|
53
|
+
# RFC 3987 section 3.1
|
54
|
+
def self.iri_to_uri(iri)
|
55
|
+
uri = iri.dup
|
56
|
+
# for char in ucschar or iprivate
|
57
|
+
# convert each char to %HH%HH%HH (as many %HH as octets)
|
58
|
+
return uri
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.provider_is_authoritative(provider_id, canonical_id)
|
62
|
+
lastbang = canonical_id.rindex('!')
|
63
|
+
return false unless lastbang
|
64
|
+
parent = canonical_id[0...lastbang]
|
65
|
+
return parent == provider_id
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.root_authority(xri)
|
69
|
+
xri = xri[6..-1] if xri.index('xri://') == 0
|
70
|
+
authority = xri.split('/', 2)[0]
|
71
|
+
if authority[0].chr == '('
|
72
|
+
root = authority[0...authority.index(')')+1]
|
73
|
+
elsif XRI_AUTHORITIES.member?(authority[0].chr)
|
74
|
+
root = authority[0].chr
|
75
|
+
else
|
76
|
+
root = authority.split(/[!*]/)[0]
|
77
|
+
end
|
78
|
+
|
79
|
+
self.make_xri(root)
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.make_xri(xri)
|
83
|
+
if xri.index('xri://') != 0
|
84
|
+
xri = 'xri://' + xri
|
85
|
+
end
|
86
|
+
return xri
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require "cgi"
|
2
|
+
require "openid/yadis/xri"
|
3
|
+
require "openid/yadis/xrds"
|
4
|
+
require "openid/fetchers"
|
5
|
+
|
6
|
+
module OpenID
|
7
|
+
|
8
|
+
module Yadis
|
9
|
+
|
10
|
+
module XRI
|
11
|
+
|
12
|
+
class XRIHTTPError < StandardError; end
|
13
|
+
|
14
|
+
class ProxyResolver
|
15
|
+
|
16
|
+
DEFAULT_PROXY = 'http://proxy.xri.net/'
|
17
|
+
|
18
|
+
def initialize(proxy_url=nil)
|
19
|
+
if proxy_url
|
20
|
+
@proxy_url = proxy_url
|
21
|
+
else
|
22
|
+
@proxy_url = DEFAULT_PROXY
|
23
|
+
end
|
24
|
+
|
25
|
+
@proxy_url += '/' unless @proxy_url.match('/$')
|
26
|
+
end
|
27
|
+
|
28
|
+
def query_url(xri, service_type=nil)
|
29
|
+
# URI normal form has a leading xri://, but we need to strip
|
30
|
+
# that off again for the QXRI. This is under discussion for
|
31
|
+
# XRI Resolution WD 11.
|
32
|
+
qxri = XRI.to_uri_normal(xri)[6..-1]
|
33
|
+
hxri = @proxy_url + qxri
|
34
|
+
args = {'_xrd_r' => 'application/xrds+xml'}
|
35
|
+
if service_type
|
36
|
+
args['_xrd_t'] = service_type
|
37
|
+
else
|
38
|
+
# don't perform service endpoint selection
|
39
|
+
args['_xrd_r'] += ';sep=false'
|
40
|
+
end
|
41
|
+
|
42
|
+
return XRI.append_args(hxri, args)
|
43
|
+
end
|
44
|
+
|
45
|
+
def query(xri, service_types)
|
46
|
+
# these can be query args or http headers, needn't be both.
|
47
|
+
# headers = {'Accept' => 'application/xrds+xml;sep=true'}
|
48
|
+
canonicalID = nil
|
49
|
+
|
50
|
+
services = service_types.collect { |service_type|
|
51
|
+
url = self.query_url(xri, service_type)
|
52
|
+
begin
|
53
|
+
response = OpenID.fetch(url)
|
54
|
+
rescue
|
55
|
+
raise XRIHTTPError, ["Could not fetch #{xri}", $!]
|
56
|
+
end
|
57
|
+
raise XRIHTTPError, "Could not fetch #{xri}" if response.nil?
|
58
|
+
|
59
|
+
xrds = Yadis::parseXRDS(response.body)
|
60
|
+
canonicalID = Yadis::get_canonical_id(xri, xrds)
|
61
|
+
|
62
|
+
Yadis::services(xrds) unless xrds.nil?
|
63
|
+
}
|
64
|
+
# TODO:
|
65
|
+
# * If we do get hits for multiple service_types, we're almost
|
66
|
+
# certainly going to have duplicated service entries and
|
67
|
+
# broken priority ordering.
|
68
|
+
services = services.inject([]) { |flatter, some_services|
|
69
|
+
flatter += some_services unless some_services.nil?
|
70
|
+
}
|
71
|
+
|
72
|
+
return canonicalID, services
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.urlencode(args)
|
77
|
+
a = []
|
78
|
+
args.each do |key, val|
|
79
|
+
a << (CGI::escape(key) + "=" + CGI::escape(val))
|
80
|
+
end
|
81
|
+
a.join("&")
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.append_args(url, args)
|
85
|
+
return url if args.length == 0
|
86
|
+
|
87
|
+
# rstrip question marks
|
88
|
+
rstripped = url.dup
|
89
|
+
while rstripped[-1].chr == '?'
|
90
|
+
rstripped = rstripped[0...rstripped.length-1]
|
91
|
+
end
|
92
|
+
|
93
|
+
if rstripped.index('?')
|
94
|
+
sep = '&'
|
95
|
+
else
|
96
|
+
sep = '?'
|
97
|
+
end
|
98
|
+
|
99
|
+
return url + sep + XRI.urlencode(args)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
data/lib/openid.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# Copyright 2006-2007 JanRain, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you
|
4
|
+
# may not use this file except in compliance with the License. You may
|
5
|
+
# obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
12
|
+
# implied. See the License for the specific language governing
|
13
|
+
# permissions and limitations under the License.
|
14
|
+
|
15
|
+
module OpenID
|
16
|
+
VERSION = "2.1.8"
|
17
|
+
end
|
18
|
+
|
19
|
+
require "openid/consumer"
|
20
|
+
require 'openid/server'
|