ruby-openid 2.0.4 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ruby-openid might be problematic. Click here for more details.
- data/CHANGELOG +65 -28
- data/LICENSE +4 -1
- data/README +19 -12
- data/UPGRADE +5 -0
- data/examples/README +8 -22
- data/examples/active_record_openid_store/XXX_add_open_id_store_to_db.rb +6 -6
- data/examples/active_record_openid_store/lib/association.rb +2 -1
- data/examples/active_record_openid_store/lib/openid_ar_store.rb +3 -3
- data/examples/rails_openid/app/controllers/consumer_controller.rb +11 -5
- data/lib/openid.rb +4 -0
- data/lib/openid/association.rb +7 -7
- data/lib/openid/consumer/checkid_request.rb +11 -0
- data/lib/openid/consumer/discovery.rb +12 -3
- data/lib/openid/consumer/idres.rb +35 -43
- data/lib/openid/extension.rb +9 -1
- data/lib/openid/extensions/pape.rb +22 -25
- data/lib/openid/extensions/sreg.rb +1 -0
- data/lib/openid/fetchers.rb +25 -5
- data/lib/openid/kvform.rb +8 -5
- data/lib/openid/kvpost.rb +6 -5
- data/lib/openid/message.rb +53 -34
- data/lib/openid/server.rb +87 -52
- data/lib/openid/trustroot.rb +25 -17
- data/lib/openid/util.rb +19 -4
- data/lib/openid/yadis/discovery.rb +3 -3
- data/lib/openid/yadis/htmltokenizer.rb +8 -5
- data/lib/openid/yadis/parsehtml.rb +22 -14
- data/lib/openid/yadis/xrds.rb +6 -9
- data/test/data/linkparse.txt +1 -1
- data/test/data/test1-parsehtml.txt +24 -0
- data/test/data/trustroot.txt +8 -2
- data/test/test_association.rb +7 -7
- data/test/test_associationmanager.rb +1 -1
- data/test/test_extension.rb +46 -0
- data/test/test_idres.rb +81 -21
- data/test/test_kvform.rb +5 -5
- data/test/test_message.rb +61 -3
- data/test/test_pape.rb +36 -22
- data/test/test_server.rb +190 -12
- data/test/test_sreg.rb +0 -1
- data/test/test_trustroot.rb +1 -0
- data/test/test_yadis_discovery.rb +13 -0
- metadata +3 -19
- data/examples/rails_openid/app/views/consumer/start.rhtml +0 -8
- data/examples/rails_openid_login_generator/USAGE +0 -23
- data/examples/rails_openid_login_generator/gemspec +0 -13
- data/examples/rails_openid_login_generator/openid_login_generator.rb +0 -36
- data/examples/rails_openid_login_generator/templates/README +0 -116
- data/examples/rails_openid_login_generator/templates/controller.rb +0 -113
- data/examples/rails_openid_login_generator/templates/controller_test.rb +0 -0
- data/examples/rails_openid_login_generator/templates/helper.rb +0 -2
- data/examples/rails_openid_login_generator/templates/openid_login_system.rb +0 -87
- data/examples/rails_openid_login_generator/templates/user.rb +0 -14
- data/examples/rails_openid_login_generator/templates/user_test.rb +0 -0
- data/examples/rails_openid_login_generator/templates/users.yml +0 -0
- data/examples/rails_openid_login_generator/templates/view_login.rhtml +0 -15
- data/examples/rails_openid_login_generator/templates/view_logout.rhtml +0 -10
- data/examples/rails_openid_login_generator/templates/view_welcome.rhtml +0 -9
data/lib/openid/extension.rb
CHANGED
@@ -19,9 +19,17 @@ module OpenID
|
|
19
19
|
# message, or create a new message containing only those
|
20
20
|
# arguments. Returns the message with added extension args.
|
21
21
|
def to_message(message = nil)
|
22
|
+
if message.nil?
|
23
|
+
# warnings.warn('Passing None to Extension.toMessage is deprecated. '
|
24
|
+
# 'Creating a message assuming you want OpenID 2.',
|
25
|
+
# DeprecationWarning, stacklevel=2)
|
26
|
+
Message.new(OPENID2_NS)
|
27
|
+
end
|
22
28
|
message = Message.new if message.nil?
|
23
29
|
|
24
|
-
message.
|
30
|
+
implicit = message.is_openid1()
|
31
|
+
|
32
|
+
message.namespaces.add_alias(@ns_uri, @ns_alias, implicit)
|
25
33
|
# XXX python ignores keyerror if m.ns.getAlias(uri) == alias
|
26
34
|
|
27
35
|
message.update_args(@ns_uri, get_extension_args)
|
@@ -14,7 +14,7 @@ module OpenID
|
|
14
14
|
'http://schemas.openid.net/pape/policies/2007/06/multi-factor'
|
15
15
|
AUTH_PHISHING_RESISTANT =
|
16
16
|
'http://schemas.openid.net/pape/policies/2007/06/phishing-resistant'
|
17
|
-
|
17
|
+
TIME_VALIDATOR = /\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ/
|
18
18
|
# A Provider Authentication Policy request, sent from a relying
|
19
19
|
# party to a provider
|
20
20
|
class Request < Extension
|
@@ -86,12 +86,12 @@ module OpenID
|
|
86
86
|
# A Provider Authentication Policy response, sent from a provider
|
87
87
|
# to a relying party
|
88
88
|
class Response < Extension
|
89
|
-
attr_accessor :ns_alias, :auth_policies, :
|
90
|
-
def initialize(auth_policies=[],
|
89
|
+
attr_accessor :ns_alias, :auth_policies, :auth_time, :nist_auth_level
|
90
|
+
def initialize(auth_policies=[], auth_time=nil, nist_auth_level=nil)
|
91
91
|
@ns_alias = 'pape'
|
92
92
|
@ns_uri = NS_URI
|
93
93
|
@auth_policies = auth_policies
|
94
|
-
@
|
94
|
+
@auth_time = auth_time
|
95
95
|
@nist_auth_level = nist_auth_level
|
96
96
|
end
|
97
97
|
|
@@ -104,6 +104,7 @@ module OpenID
|
|
104
104
|
# Create a Response object from an OpenID::Consumer::SuccessResponse
|
105
105
|
def self.from_success_response(success_response)
|
106
106
|
args = success_response.get_signed_ns(NS_URI)
|
107
|
+
return nil if args.nil?
|
107
108
|
pape_resp = new
|
108
109
|
pape_resp.parse_extension_args(args)
|
109
110
|
return pape_resp
|
@@ -115,7 +116,7 @@ module OpenID
|
|
115
116
|
# encountered
|
116
117
|
def parse_extension_args(args, strict=false)
|
117
118
|
policies_str = args['auth_policies']
|
118
|
-
if policies_str
|
119
|
+
if policies_str and policies_str != 'none'
|
119
120
|
@auth_policies = policies_str.split(' ')
|
120
121
|
end
|
121
122
|
|
@@ -138,28 +139,24 @@ module OpenID
|
|
138
139
|
end
|
139
140
|
end
|
140
141
|
|
141
|
-
|
142
|
-
if
|
143
|
-
#
|
144
|
-
if
|
145
|
-
|
146
|
-
else
|
147
|
-
auth_age = auth_age_str.to_i
|
148
|
-
# if it's zero here we have a bad value
|
149
|
-
if auth_age == 0
|
150
|
-
auth_age = nil
|
151
|
-
end
|
152
|
-
end
|
153
|
-
if auth_age and auth_age >= 0
|
154
|
-
@auth_age = auth_age
|
142
|
+
auth_time_str = args['auth_time']
|
143
|
+
if auth_time_str
|
144
|
+
# validate time string
|
145
|
+
if auth_time_str =~ TIME_VALIDATOR
|
146
|
+
@auth_time = auth_time_str
|
155
147
|
elsif strict
|
156
|
-
raise ArgumentError, "
|
148
|
+
raise ArgumentError, "auth_time must be in RFC3339 format"
|
157
149
|
end
|
158
150
|
end
|
159
151
|
end
|
160
152
|
|
161
153
|
def get_extension_args
|
162
|
-
ns_args = {
|
154
|
+
ns_args = {}
|
155
|
+
if @auth_policies.empty?
|
156
|
+
ns_args['auth_policies'] = 'none'
|
157
|
+
else
|
158
|
+
ns_args['auth_policies'] = @auth_policies.join(' ')
|
159
|
+
end
|
163
160
|
if @nist_auth_level
|
164
161
|
unless (0..4).member? @nist_auth_level
|
165
162
|
raise ArgumentError, "nist_auth_level must be an integer 0 through 4, not #{@nist_auth_level.inspect}"
|
@@ -167,11 +164,11 @@ module OpenID
|
|
167
164
|
ns_args['nist_auth_level'] = @nist_auth_level.to_s
|
168
165
|
end
|
169
166
|
|
170
|
-
if @
|
171
|
-
|
172
|
-
raise ArgumentError, "
|
167
|
+
if @auth_time
|
168
|
+
unless @auth_time =~ TIME_VALIDATOR
|
169
|
+
raise ArgumentError, "auth_time must be in RFC3339 format"
|
173
170
|
end
|
174
|
-
ns_args['
|
171
|
+
ns_args['auth_time'] = @auth_time
|
175
172
|
end
|
176
173
|
return ns_args
|
177
174
|
end
|
@@ -246,6 +246,7 @@ module OpenID
|
|
246
246
|
ns_uri = OpenID::get_sreg_ns(success_response.message)
|
247
247
|
if signed_only
|
248
248
|
args = success_response.get_signed_ns(ns_uri)
|
249
|
+
return nil if args.nil? # No signed args, so fail
|
249
250
|
else
|
250
251
|
args = success_response.message.get_args(ns_uri)
|
251
252
|
end
|
data/lib/openid/fetchers.rb
CHANGED
@@ -10,6 +10,8 @@ rescue LoadError
|
|
10
10
|
require 'net/http'
|
11
11
|
end
|
12
12
|
|
13
|
+
MAX_RESPONSE_KB = 1024
|
14
|
+
|
13
15
|
module Net
|
14
16
|
class HTTP
|
15
17
|
def post_connection_check(hostname)
|
@@ -115,14 +117,17 @@ module OpenID
|
|
115
117
|
USER_AGENT = "ruby-openid/#{OpenID::VERSION} (#{RUBY_PLATFORM})"
|
116
118
|
|
117
119
|
REDIRECT_LIMIT = 5
|
120
|
+
TIMEOUT = 60
|
118
121
|
|
119
122
|
attr_accessor :ca_file
|
123
|
+
attr_accessor :timeout
|
120
124
|
|
121
125
|
# I can fetch through a HTTP proxy; arguments are as for Net::HTTP::Proxy.
|
122
126
|
def initialize(proxy_addr=nil, proxy_port=nil,
|
123
127
|
proxy_user=nil, proxy_pass=nil)
|
124
128
|
@ca_file = nil
|
125
129
|
@proxy = Net::HTTP::Proxy(proxy_addr, proxy_port, proxy_user, proxy_pass)
|
130
|
+
@timeout = TIMEOUT
|
126
131
|
end
|
127
132
|
|
128
133
|
def supports_ssl?(conn)
|
@@ -130,7 +135,10 @@ module OpenID
|
|
130
135
|
end
|
131
136
|
|
132
137
|
def make_http(uri)
|
133
|
-
@proxy.new(uri.host, uri.port)
|
138
|
+
http = @proxy.new(uri.host, uri.port)
|
139
|
+
http.read_timeout = @timeout
|
140
|
+
http.open_timeout = @timeout
|
141
|
+
return http
|
134
142
|
end
|
135
143
|
|
136
144
|
def set_verified(conn, verify)
|
@@ -173,14 +181,18 @@ module OpenID
|
|
173
181
|
def fetch(url, body=nil, headers=nil, redirect_limit=REDIRECT_LIMIT)
|
174
182
|
unparsed_url = url.dup
|
175
183
|
url = URI::parse(url)
|
184
|
+
if url.nil?
|
185
|
+
raise FetchingError, "Invalid URL: #{unparsed_url}"
|
186
|
+
end
|
176
187
|
|
177
188
|
headers ||= {}
|
178
189
|
headers['User-agent'] ||= USER_AGENT
|
179
|
-
|
180
|
-
conn = make_connection(url)
|
181
|
-
response = nil
|
190
|
+
headers['Range'] ||= "0-#{MAX_RESPONSE_KB*1024}"
|
182
191
|
|
183
192
|
begin
|
193
|
+
conn = make_connection(url)
|
194
|
+
response = nil
|
195
|
+
|
184
196
|
response = conn.start {
|
185
197
|
# Check the certificate against the URL's hostname
|
186
198
|
if supports_ssl?(conn) and conn.use_ssl?
|
@@ -194,6 +206,8 @@ module OpenID
|
|
194
206
|
conn.request_post(url.request_uri, body, headers)
|
195
207
|
end
|
196
208
|
}
|
209
|
+
rescue RuntimeError => why
|
210
|
+
raise why
|
197
211
|
rescue OpenSSL::SSL::SSLError => why
|
198
212
|
raise SSLFetchingError, "Error connecting to SSL URL #{url}: #{why}"
|
199
213
|
rescue FetchingError => why
|
@@ -210,7 +224,13 @@ module OpenID
|
|
210
224
|
raise HTTPRedirectLimitReached.new(
|
211
225
|
"Too many redirects, not fetching #{response['location']}")
|
212
226
|
end
|
213
|
-
|
227
|
+
begin
|
228
|
+
return fetch(response['location'], body, headers, redirect_limit - 1)
|
229
|
+
rescue HTTPRedirectLimitReached => e
|
230
|
+
raise e
|
231
|
+
rescue FetchingError => why
|
232
|
+
raise FetchingError, "Error encountered in redirect from #{url}: #{why}"
|
233
|
+
end
|
214
234
|
else
|
215
235
|
return HTTPResponse._from_net_response(response, unparsed_url)
|
216
236
|
end
|
data/lib/openid/kvform.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
|
2
2
|
module OpenID
|
3
3
|
|
4
|
+
class KVFormError < Exception
|
5
|
+
end
|
6
|
+
|
4
7
|
module Util
|
5
8
|
|
6
9
|
def Util.seq_to_kv(seq, strict=false)
|
@@ -13,7 +16,7 @@ module OpenID
|
|
13
16
|
err = lambda { |msg|
|
14
17
|
msg = "seq_to_kv warning: #{msg}: #{seq.inspect}"
|
15
18
|
if strict
|
16
|
-
raise
|
19
|
+
raise KVFormError, msg
|
17
20
|
else
|
18
21
|
Util.log(msg)
|
19
22
|
end
|
@@ -27,11 +30,11 @@ module OpenID
|
|
27
30
|
end
|
28
31
|
|
29
32
|
if !k.index("\n").nil?
|
30
|
-
raise
|
33
|
+
raise KVFormError, "Invalid input for seq_to_kv: key contains newline: #{k.inspect}"
|
31
34
|
end
|
32
35
|
|
33
36
|
if !k.index(":").nil?
|
34
|
-
raise
|
37
|
+
raise KVFormError, "Invalid input for seq_to_kv: key contains colon: #{k.inspect}"
|
35
38
|
end
|
36
39
|
|
37
40
|
if k.strip() != k
|
@@ -44,7 +47,7 @@ module OpenID
|
|
44
47
|
end
|
45
48
|
|
46
49
|
if !v.index("\n").nil?
|
47
|
-
raise
|
50
|
+
raise KVFormError, "Invalid input for seq_to_kv: value contains newline: #{v.inspect}"
|
48
51
|
end
|
49
52
|
|
50
53
|
if v.strip() != v
|
@@ -66,7 +69,7 @@ module OpenID
|
|
66
69
|
err = lambda { |msg|
|
67
70
|
msg = "kv_to_seq warning: #{msg}: #{data.inspect}"
|
68
71
|
if strict
|
69
|
-
raise
|
72
|
+
raise KVFormError, msg
|
70
73
|
else
|
71
74
|
Util.log(msg)
|
72
75
|
end
|
data/lib/openid/kvpost.rb
CHANGED
@@ -7,19 +7,18 @@ module OpenID
|
|
7
7
|
class ServerError < OpenIDError
|
8
8
|
attr_reader :error_text, :error_code, :message
|
9
9
|
|
10
|
-
def initialize(error_text, error_code, message
|
10
|
+
def initialize(error_text, error_code, message)
|
11
11
|
super(error_text)
|
12
12
|
@error_text = error_text
|
13
13
|
@error_code = error_code
|
14
|
-
@server_url = server_url
|
15
14
|
@message = message
|
16
15
|
end
|
17
16
|
|
18
|
-
def self.from_message(msg
|
17
|
+
def self.from_message(msg)
|
19
18
|
error_text = msg.get_arg(OPENID_NS, 'error',
|
20
19
|
'<no error message supplied>')
|
21
20
|
error_code = msg.get_arg(OPENID_NS, 'error_code')
|
22
|
-
return self.new(error_text, error_code, msg
|
21
|
+
return self.new(error_text, error_code, msg)
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
@@ -34,8 +33,10 @@ module OpenID
|
|
34
33
|
case response.code.to_i
|
35
34
|
when 200
|
36
35
|
return msg
|
36
|
+
when 206
|
37
|
+
return msg
|
37
38
|
when 400
|
38
|
-
raise ServerError.from_message(msg
|
39
|
+
raise ServerError.from_message(msg)
|
39
40
|
else
|
40
41
|
error_message = "bad status code from server #{server_url}: "\
|
41
42
|
"#{response.code}"
|
data/lib/openid/message.rb
CHANGED
@@ -9,8 +9,10 @@ module OpenID
|
|
9
9
|
# OpenID 1.x extension, and so a special case.
|
10
10
|
SREG_URI = 'http://openid.net/sreg/1.0'
|
11
11
|
|
12
|
-
# The OpenID 1.x namespace
|
12
|
+
# The OpenID 1.x namespace URIs
|
13
13
|
OPENID1_NS = 'http://openid.net/signon/1.0'
|
14
|
+
OPENID11_NS = 'http://openid.net/signon/1.1'
|
15
|
+
OPENID1_NAMESPACES = [OPENID1_NS, OPENID11_NS]
|
14
16
|
|
15
17
|
# The OpenID 2.0 namespace URI
|
16
18
|
OPENID2_NS = 'http://specs.openid.net/auth/2.0'
|
@@ -54,6 +56,10 @@ module OpenID
|
|
54
56
|
# Raised when an alias or namespace URI has already been registered.
|
55
57
|
class NamespaceAliasRegistrationError < Exception; end
|
56
58
|
|
59
|
+
# Raised if openid.ns is not a recognized value.
|
60
|
+
# See Message class variable @@allowed_openid_namespaces
|
61
|
+
class InvalidOpenIDNamespace < Exception; end
|
62
|
+
|
57
63
|
class Message
|
58
64
|
attr_reader :namespaces
|
59
65
|
|
@@ -87,19 +93,24 @@ module OpenID
|
|
87
93
|
@@registered_aliases[alias_] = namespace_uri
|
88
94
|
end
|
89
95
|
|
90
|
-
@@allowed_openid_namespaces = [OPENID1_NS, OPENID2_NS]
|
96
|
+
@@allowed_openid_namespaces = [OPENID1_NS, OPENID2_NS, OPENID11_NS]
|
91
97
|
|
92
|
-
|
98
|
+
# Raises InvalidNamespaceError if you try to instantiate a Message
|
99
|
+
# with a namespace not in the above allowed list
|
100
|
+
def initialize(openid_namespace=nil)
|
93
101
|
@args = {}
|
94
102
|
@namespaces = NamespaceMap.new
|
95
|
-
if
|
96
|
-
|
103
|
+
if openid_namespace
|
104
|
+
implicit = OPENID1_NAMESPACES.member? openid_namespace
|
105
|
+
self.set_openid_namespace(openid_namespace, implicit)
|
97
106
|
else
|
98
107
|
@openid_ns_uri = nil
|
99
108
|
end
|
100
109
|
end
|
101
110
|
|
102
111
|
# Construct a Message containing a set of POST arguments.
|
112
|
+
# Raises InvalidNamespaceError if you try to instantiate a Message
|
113
|
+
# with a namespace not in the above allowed list
|
103
114
|
def Message.from_post_args(args)
|
104
115
|
m = Message.new
|
105
116
|
openid_args = {}
|
@@ -123,12 +134,16 @@ module OpenID
|
|
123
134
|
end
|
124
135
|
|
125
136
|
# Construct a Message from a parsed KVForm message.
|
137
|
+
# Raises InvalidNamespaceError if you try to instantiate a Message
|
138
|
+
# with a namespace not in the above allowed list
|
126
139
|
def Message.from_openid_args(openid_args)
|
127
140
|
m = Message.new
|
128
141
|
m._from_openid_args(openid_args)
|
129
142
|
return m
|
130
143
|
end
|
131
144
|
|
145
|
+
# Raises InvalidNamespaceError if you try to instantiate a Message
|
146
|
+
# with a namespace not in the above allowed list
|
132
147
|
def _from_openid_args(openid_args)
|
133
148
|
ns_args = []
|
134
149
|
|
@@ -143,47 +158,46 @@ module OpenID
|
|
143
158
|
if ns_alias == 'ns'
|
144
159
|
@namespaces.add_alias(value, ns_key)
|
145
160
|
elsif ns_alias == NULL_NAMESPACE and ns_key == 'ns'
|
146
|
-
|
161
|
+
set_openid_namespace(value, false)
|
147
162
|
else
|
148
163
|
ns_args << [ns_alias, ns_key, value]
|
149
164
|
end
|
150
165
|
}
|
151
166
|
|
152
|
-
#
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
self.set_openid_namespace(openid_ns_uri)
|
167
|
+
# implicitly set an OpenID 1 namespace
|
168
|
+
unless get_openid_namespace
|
169
|
+
set_openid_namespace(OPENID1_NS, true)
|
170
|
+
end
|
157
171
|
|
158
172
|
# put the pairs into the appropriate namespaces
|
159
173
|
ns_args.each { |ns_alias, ns_key, value|
|
160
174
|
ns_uri = @namespaces.get_namespace_uri(ns_alias)
|
161
175
|
unless ns_uri
|
162
|
-
|
163
|
-
# OpenID 1.x namespace
|
164
|
-
@@registered_aliases.each { |_alias, _uri|
|
165
|
-
if _alias == ns_alias
|
166
|
-
ns_uri = _uri
|
167
|
-
break
|
168
|
-
end
|
169
|
-
}
|
170
|
-
|
176
|
+
ns_uri = _get_default_namespace(ns_alias)
|
171
177
|
unless ns_uri
|
172
|
-
ns_uri =
|
178
|
+
ns_uri = get_openid_namespace
|
173
179
|
ns_key = "#{ns_alias}.#{ns_key}"
|
174
180
|
else
|
175
|
-
@namespaces.add_alias(ns_uri, ns_alias)
|
181
|
+
@namespaces.add_alias(ns_uri, ns_alias, true)
|
176
182
|
end
|
177
183
|
end
|
178
184
|
self.set_arg(ns_uri, ns_key, value)
|
179
185
|
}
|
180
186
|
end
|
181
187
|
|
182
|
-
def
|
188
|
+
def _get_default_namespace(mystery_alias)
|
189
|
+
# only try to map an alias to a default if it's an
|
190
|
+
# OpenID 1.x namespace
|
191
|
+
if is_openid1
|
192
|
+
@@registered_aliases[mystery_alias]
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def set_openid_namespace(openid_ns_uri, implicit)
|
183
197
|
if !@@allowed_openid_namespaces.include?(openid_ns_uri)
|
184
|
-
raise
|
198
|
+
raise InvalidOpenIDNamespace, "Invalid null namespace: #{openid_ns_uri}"
|
185
199
|
end
|
186
|
-
@namespaces.add_alias(openid_ns_uri, NULL_NAMESPACE)
|
200
|
+
@namespaces.add_alias(openid_ns_uri, NULL_NAMESPACE, implicit)
|
187
201
|
@openid_ns_uri = openid_ns_uri
|
188
202
|
end
|
189
203
|
|
@@ -192,7 +206,7 @@ module OpenID
|
|
192
206
|
end
|
193
207
|
|
194
208
|
def is_openid1
|
195
|
-
return @openid_ns_uri
|
209
|
+
return OPENID1_NAMESPACES.member?(@openid_ns_uri)
|
196
210
|
end
|
197
211
|
|
198
212
|
def is_openid2
|
@@ -214,16 +228,15 @@ module OpenID
|
|
214
228
|
|
215
229
|
# add namespace defs to the output
|
216
230
|
@namespaces.each { |ns_uri, ns_alias|
|
231
|
+
if @namespaces.implicit?(ns_uri)
|
232
|
+
next
|
233
|
+
end
|
217
234
|
if ns_alias == NULL_NAMESPACE
|
218
|
-
|
219
|
-
args['openid.ns'] = ns_uri
|
220
|
-
end
|
235
|
+
ns_key = 'openid.ns'
|
221
236
|
else
|
222
|
-
|
223
|
-
ns_key = 'openid.ns.' + ns_alias
|
224
|
-
args[ns_key] = ns_uri
|
225
|
-
end
|
237
|
+
ns_key = 'openid.ns.' + ns_alias
|
226
238
|
end
|
239
|
+
args[ns_key] = ns_uri
|
227
240
|
}
|
228
241
|
|
229
242
|
@args.each { |k, value|
|
@@ -447,6 +460,7 @@ module OpenID
|
|
447
460
|
def initialize
|
448
461
|
@alias_to_namespace = {}
|
449
462
|
@namespace_to_alias = {}
|
463
|
+
@implicit_namespaces = []
|
450
464
|
end
|
451
465
|
|
452
466
|
def get_alias(namespace_uri)
|
@@ -458,7 +472,7 @@ module OpenID
|
|
458
472
|
end
|
459
473
|
|
460
474
|
# Add an alias from this namespace URI to the alias.
|
461
|
-
def add_alias(namespace_uri, desired_alias)
|
475
|
+
def add_alias(namespace_uri, desired_alias, implicit=false)
|
462
476
|
# Check that desired_alias is not an openid protocol field as
|
463
477
|
# per the spec.
|
464
478
|
Util.assert(!OPENID_PROTOCOL_FIELDS.include?(desired_alias),
|
@@ -487,6 +501,7 @@ module OpenID
|
|
487
501
|
|
488
502
|
@alias_to_namespace[desired_alias] = namespace_uri
|
489
503
|
@namespace_to_alias[namespace_uri] = desired_alias
|
504
|
+
@implicit_namespaces << namespace_uri if implicit
|
490
505
|
return desired_alias
|
491
506
|
end
|
492
507
|
|
@@ -526,6 +541,10 @@ module OpenID
|
|
526
541
|
return @namespace_to_alias.keys()
|
527
542
|
end
|
528
543
|
|
544
|
+
def implicit?(namespace_uri)
|
545
|
+
return @implicit_namespaces.member?(namespace_uri)
|
546
|
+
end
|
547
|
+
|
529
548
|
def aliases
|
530
549
|
# Return an iterator over the aliases
|
531
550
|
return @alias_to_namespace.keys()
|