ruby-openid2 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|