ruby-openid2 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +136 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/CONTRIBUTING.md +54 -0
- data/LICENSE.txt +210 -0
- data/README.md +81 -0
- data/SECURITY.md +15 -0
- data/lib/hmac/hmac.rb +110 -0
- data/lib/hmac/sha1.rb +11 -0
- data/lib/hmac/sha2.rb +25 -0
- data/lib/openid/association.rb +246 -0
- data/lib/openid/consumer/associationmanager.rb +354 -0
- data/lib/openid/consumer/checkid_request.rb +179 -0
- data/lib/openid/consumer/discovery.rb +516 -0
- data/lib/openid/consumer/discovery_manager.rb +144 -0
- data/lib/openid/consumer/html_parse.rb +142 -0
- data/lib/openid/consumer/idres.rb +513 -0
- data/lib/openid/consumer/responses.rb +147 -0
- data/lib/openid/consumer/session.rb +36 -0
- data/lib/openid/consumer.rb +406 -0
- data/lib/openid/cryptutil.rb +112 -0
- data/lib/openid/dh.rb +84 -0
- data/lib/openid/extension.rb +38 -0
- data/lib/openid/extensions/ax.rb +552 -0
- data/lib/openid/extensions/oauth.rb +88 -0
- data/lib/openid/extensions/pape.rb +170 -0
- data/lib/openid/extensions/sreg.rb +268 -0
- data/lib/openid/extensions/ui.rb +49 -0
- data/lib/openid/fetchers.rb +277 -0
- data/lib/openid/kvform.rb +113 -0
- data/lib/openid/kvpost.rb +62 -0
- data/lib/openid/message.rb +555 -0
- data/lib/openid/protocolerror.rb +7 -0
- data/lib/openid/server.rb +1571 -0
- data/lib/openid/store/filesystem.rb +260 -0
- data/lib/openid/store/interface.rb +73 -0
- data/lib/openid/store/memcache.rb +109 -0
- data/lib/openid/store/memory.rb +79 -0
- data/lib/openid/store/nonce.rb +72 -0
- data/lib/openid/trustroot.rb +597 -0
- data/lib/openid/urinorm.rb +72 -0
- data/lib/openid/util.rb +119 -0
- data/lib/openid/version.rb +5 -0
- data/lib/openid/yadis/accept.rb +141 -0
- data/lib/openid/yadis/constants.rb +16 -0
- data/lib/openid/yadis/discovery.rb +151 -0
- data/lib/openid/yadis/filters.rb +192 -0
- data/lib/openid/yadis/htmltokenizer.rb +290 -0
- data/lib/openid/yadis/parsehtml.rb +50 -0
- data/lib/openid/yadis/services.rb +44 -0
- data/lib/openid/yadis/xrds.rb +160 -0
- data/lib/openid/yadis/xri.rb +86 -0
- data/lib/openid/yadis/xrires.rb +87 -0
- data/lib/openid.rb +27 -0
- data/lib/ruby-openid.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +331 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
# An implementation of the OpenID OAuth Extension
|
2
|
+
# Extension 1.0
|
3
|
+
# see: http://openid.net/specs/
|
4
|
+
|
5
|
+
require_relative "../extension"
|
6
|
+
|
7
|
+
module OpenID
|
8
|
+
module OAuth
|
9
|
+
NS_URI = "http://specs.openid.net/extensions/oauth/1.0"
|
10
|
+
# An OAuth token request, sent from a relying
|
11
|
+
# party to a provider
|
12
|
+
class Request < Extension
|
13
|
+
attr_accessor :consumer, :scope, :ns_alias, :ns_uri
|
14
|
+
|
15
|
+
def initialize(consumer = nil, scope = nil)
|
16
|
+
@ns_alias = "oauth"
|
17
|
+
@ns_uri = NS_URI
|
18
|
+
@consumer = consumer
|
19
|
+
@scope = scope
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_extension_args
|
23
|
+
ns_args = {}
|
24
|
+
ns_args["consumer"] = @consumer if @consumer
|
25
|
+
ns_args["scope"] = @scope if @scope
|
26
|
+
ns_args
|
27
|
+
end
|
28
|
+
|
29
|
+
# Instantiate a Request object from the arguments in a
|
30
|
+
# checkid_* OpenID message
|
31
|
+
# return nil if the extension was not requested.
|
32
|
+
def self.from_openid_request(oid_req)
|
33
|
+
oauth_req = new
|
34
|
+
args = oid_req.message.get_args(NS_URI)
|
35
|
+
return if args == {}
|
36
|
+
|
37
|
+
oauth_req.parse_extension_args(args)
|
38
|
+
oauth_req
|
39
|
+
end
|
40
|
+
|
41
|
+
# Set the state of this request to be that expressed in these
|
42
|
+
# OAuth arguments
|
43
|
+
def parse_extension_args(args)
|
44
|
+
@consumer = args["consumer"]
|
45
|
+
@scope = args["scope"]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# A OAuth request token response, sent from a provider
|
50
|
+
# to a relying party
|
51
|
+
class Response < Extension
|
52
|
+
attr_accessor :request_token, :scope
|
53
|
+
|
54
|
+
def initialize(request_token = nil, scope = nil)
|
55
|
+
@ns_alias = "oauth"
|
56
|
+
@ns_uri = NS_URI
|
57
|
+
@request_token = request_token
|
58
|
+
@scope = scope
|
59
|
+
end
|
60
|
+
|
61
|
+
# Create a Response object from an OpenID::Consumer::SuccessResponse
|
62
|
+
def self.from_success_response(success_response)
|
63
|
+
args = success_response.get_signed_ns(NS_URI)
|
64
|
+
return if args.nil?
|
65
|
+
|
66
|
+
oauth_resp = new
|
67
|
+
oauth_resp.parse_extension_args(args)
|
68
|
+
oauth_resp
|
69
|
+
end
|
70
|
+
|
71
|
+
# parse the oauth request arguments into the
|
72
|
+
# internal state of this object
|
73
|
+
# if strict is specified, raise an exception when bad data is
|
74
|
+
# encountered
|
75
|
+
def parse_extension_args(args, _strict = false)
|
76
|
+
@request_token = args["request_token"]
|
77
|
+
@scope = args["scope"]
|
78
|
+
end
|
79
|
+
|
80
|
+
def get_extension_args
|
81
|
+
ns_args = {}
|
82
|
+
ns_args["request_token"] = @request_token if @request_token
|
83
|
+
ns_args["scope"] = @scope if @scope
|
84
|
+
ns_args
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# An implementation of the OpenID Provider Authentication Policy
|
2
|
+
# Extension 1.0
|
3
|
+
# see: http://openid.net/specs/
|
4
|
+
|
5
|
+
require_relative "../extension"
|
6
|
+
|
7
|
+
module OpenID
|
8
|
+
module PAPE
|
9
|
+
NS_URI = "http://specs.openid.net/extensions/pape/1.0"
|
10
|
+
AUTH_MULTI_FACTOR_PHYSICAL =
|
11
|
+
"http://schemas.openid.net/pape/policies/2007/06/multi-factor-physical"
|
12
|
+
AUTH_MULTI_FACTOR =
|
13
|
+
"http://schemas.openid.net/pape/policies/2007/06/multi-factor"
|
14
|
+
AUTH_PHISHING_RESISTANT =
|
15
|
+
"http://schemas.openid.net/pape/policies/2007/06/phishing-resistant"
|
16
|
+
TIME_VALIDATOR = /\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ/
|
17
|
+
# A Provider Authentication Policy request, sent from a relying
|
18
|
+
# party to a provider
|
19
|
+
class Request < Extension
|
20
|
+
attr_accessor :preferred_auth_policies, :max_auth_age, :ns_alias, :ns_uri
|
21
|
+
|
22
|
+
def initialize(preferred_auth_policies = [], max_auth_age = nil)
|
23
|
+
@ns_alias = "pape"
|
24
|
+
@ns_uri = NS_URI
|
25
|
+
@preferred_auth_policies = preferred_auth_policies
|
26
|
+
@max_auth_age = max_auth_age
|
27
|
+
end
|
28
|
+
|
29
|
+
# Add an acceptable authentication policy URI to this request
|
30
|
+
# This method is intended to be used by the relying party to add
|
31
|
+
# acceptable authentication types to the request.
|
32
|
+
def add_policy_uri(policy_uri)
|
33
|
+
return if @preferred_auth_policies.member?(policy_uri)
|
34
|
+
|
35
|
+
@preferred_auth_policies << policy_uri
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_extension_args
|
39
|
+
ns_args = {
|
40
|
+
"preferred_auth_policies" => @preferred_auth_policies.join(" "),
|
41
|
+
}
|
42
|
+
ns_args["max_auth_age"] = @max_auth_age.to_s if @max_auth_age
|
43
|
+
ns_args
|
44
|
+
end
|
45
|
+
|
46
|
+
# Instantiate a Request object from the arguments in a
|
47
|
+
# checkid_* OpenID message
|
48
|
+
# return nil if the extension was not requested.
|
49
|
+
def self.from_openid_request(oid_req)
|
50
|
+
pape_req = new
|
51
|
+
args = oid_req.message.get_args(NS_URI)
|
52
|
+
return if args == {}
|
53
|
+
|
54
|
+
pape_req.parse_extension_args(args)
|
55
|
+
pape_req
|
56
|
+
end
|
57
|
+
|
58
|
+
# Set the state of this request to be that expressed in these
|
59
|
+
# PAPE arguments
|
60
|
+
def parse_extension_args(args)
|
61
|
+
@preferred_auth_policies = []
|
62
|
+
policies_str = args["preferred_auth_policies"]
|
63
|
+
if policies_str
|
64
|
+
policies_str.split(" ").each do |uri|
|
65
|
+
add_policy_uri(uri)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
max_auth_age_str = args["max_auth_age"]
|
70
|
+
@max_auth_age = (max_auth_age_str.to_i if max_auth_age_str)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Given a list of authentication policy URIs that a provider
|
74
|
+
# supports, this method returns the subset of those types
|
75
|
+
# that are preferred by the relying party.
|
76
|
+
def preferred_types(supported_types)
|
77
|
+
@preferred_auth_policies.select { |uri| supported_types.member?(uri) }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# A Provider Authentication Policy response, sent from a provider
|
82
|
+
# to a relying party
|
83
|
+
class Response < Extension
|
84
|
+
attr_accessor :ns_alias, :auth_policies, :auth_time, :nist_auth_level
|
85
|
+
|
86
|
+
def initialize(auth_policies = [], auth_time = nil, nist_auth_level = nil)
|
87
|
+
@ns_alias = "pape"
|
88
|
+
@ns_uri = NS_URI
|
89
|
+
@auth_policies = auth_policies
|
90
|
+
@auth_time = auth_time
|
91
|
+
@nist_auth_level = nist_auth_level
|
92
|
+
end
|
93
|
+
|
94
|
+
# Add a policy URI to the response
|
95
|
+
# see http://openid.net/specs/openid-provider-authentication-policy-extension-1_0-01.html#auth_policies
|
96
|
+
def add_policy_uri(policy_uri)
|
97
|
+
@auth_policies << policy_uri unless @auth_policies.member?(policy_uri)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Create a Response object from an OpenID::Consumer::SuccessResponse
|
101
|
+
def self.from_success_response(success_response)
|
102
|
+
args = success_response.get_signed_ns(NS_URI)
|
103
|
+
return if args.nil?
|
104
|
+
|
105
|
+
pape_resp = new
|
106
|
+
pape_resp.parse_extension_args(args)
|
107
|
+
pape_resp
|
108
|
+
end
|
109
|
+
|
110
|
+
# parse the provider authentication policy arguments into the
|
111
|
+
# internal state of this object
|
112
|
+
# if strict is specified, raise an exception when bad data is
|
113
|
+
# encountered
|
114
|
+
def parse_extension_args(args, strict = false)
|
115
|
+
policies_str = args["auth_policies"]
|
116
|
+
@auth_policies = policies_str.split(" ") if policies_str and policies_str != "none"
|
117
|
+
|
118
|
+
nist_level_str = args["nist_auth_level"]
|
119
|
+
if nist_level_str
|
120
|
+
# special handling of zero to handle to_i behavior
|
121
|
+
if nist_level_str.strip == "0"
|
122
|
+
nist_level = 0
|
123
|
+
else
|
124
|
+
nist_level = nist_level_str.to_i
|
125
|
+
# if it's zero here we have a bad value
|
126
|
+
nist_level = nil if nist_level == 0
|
127
|
+
end
|
128
|
+
if nist_level and nist_level >= 0 and nist_level < 5
|
129
|
+
@nist_auth_level = nist_level
|
130
|
+
elsif strict
|
131
|
+
raise ArgumentError, "nist_auth_level must be an integer 0 through 4, not #{nist_level_str.inspect}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
auth_time_str = args["auth_time"]
|
136
|
+
return unless auth_time_str
|
137
|
+
|
138
|
+
# validate time string
|
139
|
+
if TIME_VALIDATOR.match?(auth_time_str)
|
140
|
+
@auth_time = auth_time_str
|
141
|
+
elsif strict
|
142
|
+
raise ArgumentError, "auth_time must be in RFC3339 format"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def get_extension_args
|
147
|
+
ns_args = {}
|
148
|
+
ns_args["auth_policies"] = if @auth_policies.empty?
|
149
|
+
"none"
|
150
|
+
else
|
151
|
+
@auth_policies.join(" ")
|
152
|
+
end
|
153
|
+
if @nist_auth_level
|
154
|
+
unless (0..4).member?(@nist_auth_level)
|
155
|
+
raise ArgumentError, "nist_auth_level must be an integer 0 through 4, not #{@nist_auth_level.inspect}"
|
156
|
+
end
|
157
|
+
|
158
|
+
ns_args["nist_auth_level"] = @nist_auth_level.to_s
|
159
|
+
end
|
160
|
+
|
161
|
+
if @auth_time
|
162
|
+
raise ArgumentError, "auth_time must be in RFC3339 format" unless TIME_VALIDATOR.match?(@auth_time)
|
163
|
+
|
164
|
+
ns_args["auth_time"] = @auth_time
|
165
|
+
end
|
166
|
+
ns_args
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
require_relative "../extension"
|
2
|
+
require_relative "../util"
|
3
|
+
require_relative "../message"
|
4
|
+
|
5
|
+
module OpenID
|
6
|
+
module SReg
|
7
|
+
DATA_FIELDS = {
|
8
|
+
"fullname" => "Full Name",
|
9
|
+
"nickname" => "Nickname",
|
10
|
+
"dob" => "Date of Birth",
|
11
|
+
"email" => "E-mail Address",
|
12
|
+
"gender" => "Gender",
|
13
|
+
"postcode" => "Postal Code",
|
14
|
+
"country" => "Country",
|
15
|
+
"language" => "Language",
|
16
|
+
"timezone" => "Time Zone",
|
17
|
+
}
|
18
|
+
|
19
|
+
NS_URI_1_0 = "http://openid.net/sreg/1.0"
|
20
|
+
NS_URI_1_1 = "http://openid.net/extensions/sreg/1.1"
|
21
|
+
NS_URI = NS_URI_1_1
|
22
|
+
|
23
|
+
begin
|
24
|
+
Message.register_namespace_alias(NS_URI_1_1, "sreg")
|
25
|
+
rescue NamespaceAliasRegistrationError => e
|
26
|
+
Util.log(e)
|
27
|
+
end
|
28
|
+
|
29
|
+
# raise ArgumentError if fieldname is not in the defined sreg fields
|
30
|
+
def OpenID.check_sreg_field_name(fieldname)
|
31
|
+
return if DATA_FIELDS.member?(fieldname)
|
32
|
+
|
33
|
+
raise ArgumentError, "#{fieldname} is not a defined simple registration field"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Does the given endpoint advertise support for simple registration?
|
37
|
+
def OpenID.supports_sreg?(endpoint)
|
38
|
+
endpoint.uses_extension(NS_URI_1_1) || endpoint.uses_extension(NS_URI_1_0)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Extract the simple registration namespace URI from the given
|
42
|
+
# OpenID message. Handles OpenID 1 and 2, as well as both sreg
|
43
|
+
# namespace URIs found in the wild, as well as missing namespace
|
44
|
+
# definitions (for OpenID 1)
|
45
|
+
def OpenID.get_sreg_ns(message)
|
46
|
+
[NS_URI_1_1, NS_URI_1_0].each do |ns|
|
47
|
+
return ns if message.namespaces.get_alias(ns)
|
48
|
+
end
|
49
|
+
# try to add an alias, since we didn't find one
|
50
|
+
ns = NS_URI_1_1
|
51
|
+
begin
|
52
|
+
message.namespaces.add_alias(ns, "sreg")
|
53
|
+
rescue IndexError
|
54
|
+
raise NamespaceError
|
55
|
+
end
|
56
|
+
ns
|
57
|
+
end
|
58
|
+
|
59
|
+
# The simple registration namespace was not found and could not
|
60
|
+
# be created using the expected name (there's another extension
|
61
|
+
# using the name 'sreg')
|
62
|
+
#
|
63
|
+
# This is not <em>illegal</em>, for OpenID 2, although it probably
|
64
|
+
# indicates a problem, since it's not expected that other extensions
|
65
|
+
# will re-use the alias that is in use for OpenID 1.
|
66
|
+
#
|
67
|
+
# If this is an OpenID 1 request, then there is no recourse. This
|
68
|
+
# should not happen unless some code has modified the namespaces for
|
69
|
+
# the message that is being processed.
|
70
|
+
class NamespaceError < ArgumentError
|
71
|
+
end
|
72
|
+
|
73
|
+
# An object to hold the state of a simple registration request.
|
74
|
+
class Request < Extension
|
75
|
+
attr_reader :optional, :required, :ns_uri
|
76
|
+
attr_accessor :policy_url
|
77
|
+
|
78
|
+
def initialize(required = nil, optional = nil, policy_url = nil, ns_uri = NS_URI)
|
79
|
+
super()
|
80
|
+
|
81
|
+
@policy_url = policy_url
|
82
|
+
@ns_uri = ns_uri
|
83
|
+
@ns_alias = "sreg"
|
84
|
+
@required = []
|
85
|
+
@optional = []
|
86
|
+
|
87
|
+
request_fields(required, true, true) if required
|
88
|
+
return unless optional
|
89
|
+
|
90
|
+
request_fields(optional, false, true)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Create a simple registration request that contains the
|
94
|
+
# fields that were requested in the OpenID request with the
|
95
|
+
# given arguments
|
96
|
+
# Takes an OpenID::CheckIDRequest, returns an OpenID::Sreg::Request
|
97
|
+
# return nil if the extension was not requested.
|
98
|
+
def self.from_openid_request(request)
|
99
|
+
# Since we're going to mess with namespace URI mapping, don't
|
100
|
+
# mutate the object that was passed in.
|
101
|
+
message = request.message.copy
|
102
|
+
ns_uri = OpenID.get_sreg_ns(message)
|
103
|
+
args = message.get_args(ns_uri)
|
104
|
+
return if args == {}
|
105
|
+
|
106
|
+
req = new(nil, nil, nil, ns_uri)
|
107
|
+
req.parse_extension_args(args)
|
108
|
+
req
|
109
|
+
end
|
110
|
+
|
111
|
+
# Parse the unqualified simple registration request
|
112
|
+
# parameters and add them to this object.
|
113
|
+
#
|
114
|
+
# This method is essentially the inverse of
|
115
|
+
# getExtensionArgs. This method restores the serialized simple
|
116
|
+
# registration request fields.
|
117
|
+
#
|
118
|
+
# If you are extracting arguments from a standard OpenID
|
119
|
+
# checkid_* request, you probably want to use fromOpenIDRequest,
|
120
|
+
# which will extract the sreg namespace and arguments from the
|
121
|
+
# OpenID request. This method is intended for cases where the
|
122
|
+
# OpenID server needs more control over how the arguments are
|
123
|
+
# parsed than that method provides.
|
124
|
+
def parse_extension_args(args, strict = false)
|
125
|
+
required_items = args["required"]
|
126
|
+
unless required_items.nil? or required_items.empty?
|
127
|
+
required_items.split(",").each do |field_name|
|
128
|
+
request_field(field_name, true, strict)
|
129
|
+
rescue ArgumentError
|
130
|
+
raise if strict
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
optional_items = args["optional"]
|
135
|
+
unless optional_items.nil? or optional_items.empty?
|
136
|
+
optional_items.split(",").each do |field_name|
|
137
|
+
request_field(field_name, false, strict)
|
138
|
+
rescue ArgumentError
|
139
|
+
raise if strict
|
140
|
+
end
|
141
|
+
end
|
142
|
+
@policy_url = args["policy_url"]
|
143
|
+
end
|
144
|
+
|
145
|
+
# A list of all of the simple registration fields that were
|
146
|
+
# requested, whether they were required or optional.
|
147
|
+
def all_requested_fields
|
148
|
+
@required + @optional
|
149
|
+
end
|
150
|
+
|
151
|
+
# Have any simple registration fields been requested?
|
152
|
+
def were_fields_requested?
|
153
|
+
!all_requested_fields.empty?
|
154
|
+
end
|
155
|
+
|
156
|
+
# Request the specified field from the OpenID user
|
157
|
+
# field_name: the unqualified simple registration field name
|
158
|
+
# required: whether the given field should be presented
|
159
|
+
# to the user as being a required to successfully complete
|
160
|
+
# the request
|
161
|
+
# strict: whether to raise an exception when a field is
|
162
|
+
# added to a request more than once
|
163
|
+
# Raises ArgumentError if the field_name is not a simple registration
|
164
|
+
# field, or if strict is set and a field is added more than once
|
165
|
+
def request_field(field_name, required = false, strict = false)
|
166
|
+
OpenID.check_sreg_field_name(field_name)
|
167
|
+
|
168
|
+
if strict
|
169
|
+
raise ArgumentError, "That field has already been requested" if (@required + @optional).member?(field_name)
|
170
|
+
else
|
171
|
+
return if @required.member?(field_name)
|
172
|
+
|
173
|
+
if @optional.member?(field_name)
|
174
|
+
return unless required
|
175
|
+
|
176
|
+
@optional.delete(field_name)
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
180
|
+
if required
|
181
|
+
@required << field_name
|
182
|
+
else
|
183
|
+
@optional << field_name
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Add the given list of fields to the request.
|
188
|
+
def request_fields(field_names, required = false, strict = false)
|
189
|
+
raise ArgumentError unless field_names.respond_to?(:each) and
|
190
|
+
field_names[0].is_a?(String)
|
191
|
+
|
192
|
+
field_names.each { |fn| request_field(fn, required, strict) }
|
193
|
+
end
|
194
|
+
|
195
|
+
# Get a hash of unqualified simple registration arguments
|
196
|
+
# representing this request.
|
197
|
+
# This method is essentially the inverse of parse_extension_args.
|
198
|
+
# This method serializes the simple registration request fields.
|
199
|
+
def get_extension_args
|
200
|
+
args = {}
|
201
|
+
args["required"] = @required.join(",") unless @required.empty?
|
202
|
+
args["optional"] = @optional.join(",") unless @optional.empty?
|
203
|
+
args["policy_url"] = @policy_url unless @policy_url.nil?
|
204
|
+
args
|
205
|
+
end
|
206
|
+
|
207
|
+
def member?(field_name)
|
208
|
+
all_requested_fields.member?(field_name)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Represents the data returned in a simple registration response
|
213
|
+
# inside of an OpenID id_res response. This object will be
|
214
|
+
# created by the OpenID server, added to the id_res response
|
215
|
+
# object, and then extracted from the id_res message by the Consumer.
|
216
|
+
class Response < Extension
|
217
|
+
attr_reader :ns_uri, :data
|
218
|
+
|
219
|
+
def initialize(data = {}, ns_uri = NS_URI)
|
220
|
+
@ns_alias = "sreg"
|
221
|
+
@data = data
|
222
|
+
@ns_uri = ns_uri
|
223
|
+
end
|
224
|
+
|
225
|
+
# Take a Request and a hash of simple registration
|
226
|
+
# values and create a Response object containing that data.
|
227
|
+
def self.extract_response(request, data)
|
228
|
+
arf = request.all_requested_fields
|
229
|
+
resp_data = data.reject { |k, v| !arf.member?(k) || v.nil? }
|
230
|
+
new(resp_data, request.ns_uri)
|
231
|
+
end
|
232
|
+
|
233
|
+
# Create an Response object from an
|
234
|
+
# OpenID::Consumer::SuccessResponse from consumer.complete
|
235
|
+
# If you set the signed_only parameter to false, unsigned data from
|
236
|
+
# the id_res message from the server will be processed.
|
237
|
+
def self.from_success_response(success_response, signed_only = true)
|
238
|
+
ns_uri = OpenID.get_sreg_ns(success_response.message)
|
239
|
+
if signed_only
|
240
|
+
args = success_response.get_signed_ns(ns_uri)
|
241
|
+
return if args.nil? # No signed args, so fail
|
242
|
+
else
|
243
|
+
args = success_response.message.get_args(ns_uri)
|
244
|
+
end
|
245
|
+
args.reject! { |k, _v| !DATA_FIELDS.member?(k) }
|
246
|
+
new(args, ns_uri)
|
247
|
+
end
|
248
|
+
|
249
|
+
# Get the fields to put in the simple registration namespace
|
250
|
+
# when adding them to an id_res message.
|
251
|
+
def get_extension_args
|
252
|
+
@data
|
253
|
+
end
|
254
|
+
|
255
|
+
# Read-only hashlike interface.
|
256
|
+
# Raises an exception if the field name is bad
|
257
|
+
def [](field_name)
|
258
|
+
OpenID.check_sreg_field_name(field_name)
|
259
|
+
data[field_name]
|
260
|
+
end
|
261
|
+
|
262
|
+
def empty?
|
263
|
+
@data.empty?
|
264
|
+
end
|
265
|
+
# XXX is there more to a hashlike interface I should add?
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# An implementation of the OpenID User Interface Extension 1.0 - DRAFT 0.5
|
2
|
+
# see: http://svn.openid.net/repos/specifications/user_interface/1.0/trunk/openid-user-interface-extension-1_0.html
|
3
|
+
|
4
|
+
require_relative "../extension"
|
5
|
+
|
6
|
+
module OpenID
|
7
|
+
module UI
|
8
|
+
NS_URI = "http://specs.openid.net/extensions/ui/1.0"
|
9
|
+
|
10
|
+
class Request < Extension
|
11
|
+
attr_accessor :lang, :icon, :mode, :ns_alias, :ns_uri
|
12
|
+
|
13
|
+
def initialize(mode = nil, icon = nil, lang = nil)
|
14
|
+
@ns_alias = "ui"
|
15
|
+
@ns_uri = NS_URI
|
16
|
+
@lang = lang
|
17
|
+
@icon = icon
|
18
|
+
@mode = mode
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_extension_args
|
22
|
+
ns_args = {}
|
23
|
+
ns_args["lang"] = @lang if @lang
|
24
|
+
ns_args["icon"] = @icon if @icon
|
25
|
+
ns_args["mode"] = @mode if @mode
|
26
|
+
ns_args
|
27
|
+
end
|
28
|
+
|
29
|
+
# Instantiate a Request object from the arguments in a
|
30
|
+
# checkid_* OpenID message
|
31
|
+
# return nil if the extension was not requested.
|
32
|
+
def self.from_openid_request(oid_req)
|
33
|
+
ui_req = new
|
34
|
+
args = oid_req.message.get_args(NS_URI)
|
35
|
+
return if args == {}
|
36
|
+
|
37
|
+
ui_req.parse_extension_args(args)
|
38
|
+
ui_req
|
39
|
+
end
|
40
|
+
|
41
|
+
# Set UI extension parameters
|
42
|
+
def parse_extension_args(args)
|
43
|
+
@lang = args["lang"]
|
44
|
+
@icon = args["icon"]
|
45
|
+
@mode = args["mode"]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|