public
Description: A Ruby on Rails-based OpenID server for all ya identity providers out there. It is pretty close to the current OpenID specifications and supports SReg, AX (only fetch requests, yet) and PAPE
Homepage: http://dennisbloete.de/projects/masquerade/
Clone URL: git://github.com/dbloete/masquerade.git
Search Repo:
Added support for Attribute Exchange fetch requests

Various things had to be added and changed. The most important changes are


  * Mapping for persona attributes to AX and SReg properties
  * Added identifier type to release policy to distinguish AX
    properties from SReg properties
  * Added AX test mode to the consumer testsuite
  * ReleasePolicy got setters for ax and sreg properties.

Kudos to Rakuto Furutani for his blog posts on Attribute Exchange - they
helped a lot! For further info on that see:
http://rakuto.blogspot.com/2008/03/ruby-fetch-and-store-some-attributes.ht
ml
dbloete (author)
Mon Apr 21 14:32:47 -0700 2008
commit  2c7677ea1bdb08e54cacd91bec0b6c45ac66494e
tree    51d871fd5ba61794f6ec37dc4da893d31b81a159
parent  9e4fee16d3b1c5e1d80f6efe574375cd8fd84f3a
...
12
13
14
15
16
17
 
 
 
18
19
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
22
23
...
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
40
41
42
 
 
 
 
43
44
45
46
47
48
 
49
50
51
 
52
53
54
55
56
 
 
57
58
 
59
 
 
 
 
 
 
 
 
 
 
 
60
61
62
 
63
64
65
66
67
68
69
70
 
 
 
71
72
73
74
75
76
77
78
79
80
81
82
83
 
84
85
86
...
12
13
14
 
 
 
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
44
45
46
 
47
48
49
50
51
52
53
54
55
56
57
58
...
55
56
57
58
59
60
61
62
63
64
65
66
 
67
68
69
 
70
71
72
73
 
 
74
75
76
 
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
 
92
93
94
95
96
97
 
 
 
98
99
100
101
 
 
 
 
102
103
104
105
106
107
 
 
108
109
110
111
0
@@ -12,12 +12,28 @@
0
     end
0
     if params[:use_sreg]
0
       sregreq = OpenID::SReg::Request.new
0
- sregreq.policy_url = "http://www.policy-url.com"
0
- sregreq.request_fields(['nickname', 'email'], true) # required fields
0
- sregreq.request_fields(['fullname', 'dob'], false) # optional fields
0
+ sregreq.policy_url = 'http://www.policy-url.com'
0
+ sregreq.request_fields(['nickname', 'email'], true) # required
0
+ sregreq.request_fields(['fullname', 'dob'], false) # optional
0
       oidreq.add_extension(sregreq)
0
       oidreq.return_to_args['did_sreg'] = 'y'
0
     end
0
+ if params[:use_ax]
0
+ axreq = OpenID::AX::FetchRequest.new
0
+ requested_attrs = [['http://axschema.org/namePerson/friendly', 'nickname', true],
0
+ ['http://axschema.org/contact/email', 'email', true],
0
+ ['http://axschema.org/namePerson', 'fullname'],
0
+ ['http://axschema.org/contact/web/default', 'website', false, 2],
0
+ ['http://axschema.org/contact/postalCode/home', 'postcode'],
0
+ ['http://axschema.org/person/gender', 'gender'],
0
+ ['http://axschema.org/birthDate', 'birth_date'],
0
+ ['http://axschema.org/contact/country/home', 'country'],
0
+ ['http://axschema.org/pref/language', 'language'],
0
+ ['http://axschema.org/pref/timezone', 'timezone']]
0
+ requested_attrs.each { |a| axreq.add(OpenID::AX::AttrInfo.new(a[0], a[1], a[2] || false, a[3] || 1)) }
0
+ oidreq.add_extension(axreq)
0
+ oidreq.return_to_args['did_ax'] = 'y'
0
+ end
0
     if params[:use_pape]
0
       papereq = OpenID::PAPE::Request.new
0
       papereq.add_policy_uri(OpenID::PAPE::AUTH_PHISHING_RESISTANT)
0
@@ -28,7 +44,6 @@
0
     if params[:force_post]
0
       oidreq.return_to_args['force_post'] = 'x' * 2048
0
     end
0
-
0
     if oidreq.send_redirect?(consumer_url, consumer_complete_url, params[:immediate])
0
       redirect_to oidreq.redirect_url(consumer_url, consumer_complete_url, params[:immediate])
0
     else
0
0
0
0
0
0
0
0
0
0
@@ -40,47 +55,57 @@
0
     parameters = params.reject{ |k,v| request.path_parameters[k] }
0
     oidresp = openid_consumer.complete(parameters, url_for({}))
0
     case oidresp.status
0
+ when OpenID::Consumer::SETUP_NEEDED
0
+ flash[:error] = "Immediate request failed - setup needed"
0
+ when OpenID::Consumer::CANCEL
0
+ flash[:error] = "OpenID transaction cancelled."
0
     when OpenID::Consumer::FAILURE
0
       flash[:error] = oidresp.display_identifier ?
0
         "Verification of #{oidresp.display_identifier} failed: #{oidresp.message}" :
0
         "Verification failed: #{oidresp.message}"
0
     when OpenID::Consumer::SUCCESS
0
- flash[:notice] = ("Verification of #{oidresp.display_identifier} succeeded.")
0
+ flash[:notice] = "Verification of #{oidresp.display_identifier} succeeded."
0
       if params[:did_sreg]
0
         sreg_resp = OpenID::SReg::Response.from_success_response(oidresp)
0
- sreg_message = "Simple Registration data was requested"
0
+ sreg_message = "\n\nSimple Registration data was requested"
0
         if sreg_resp.empty?
0
           sreg_message << ", but none was returned."
0
         else
0
- sreg_message << ". The following data were sent:"
0
- sreg_resp.data.each { |k,v| sreg_message << "<br/><b>#{k}</b>: #{v}" }
0
+ sreg_message << ". The following data were sent:\n"
0
+ sreg_resp.data.each { |k,v| sreg_message << "#{k}: #{v}\n" }
0
         end
0
- flash[:sreg_results] = sreg_message
0
+ flash[:notice] += sreg_message
0
       end
0
+ if params[:did_ax]
0
+ ax_resp = OpenID::AX::FetchResponse.from_success_response(oidresp)
0
+ ax_message = "\n\nAttribute Exchange data was requested"
0
+ unless ax_resp
0
+ ax_message << ", but none was returned."
0
+ else
0
+ ax_message << ". The following data were sent:\n"
0
+ ax_resp.data.each { |k,v| ax_message << "#{k}: #{v}\n" }
0
+ end
0
+ flash[:notice] += ax_message
0
+ end
0
       if params[:did_pape]
0
         pape_resp = OpenID::PAPE::Response.from_success_response(oidresp)
0
- pape_message = "A phishing resistant authentication method was requested"
0
+ pape_message = "\n\nA phishing resistant authentication method was requested"
0
         if pape_resp.auth_policies.member? OpenID::PAPE::AUTH_PHISHING_RESISTANT
0
           pape_message << ", and the server reported one."
0
         else
0
           pape_message << ", but the server did not report one."
0
         end
0
- pape_message << "<br><b>Authentication age:</b> #{pape_resp.auth_age} seconds" if pape_resp.auth_age
0
- pape_message << "<br><b>NIST Auth Level:</b> #{pape_resp.nist_auth_level}" if pape_resp.nist_auth_level
0
- flash[:pape_results] = pape_message
0
+ pape_message << "\nAuthentication age: #{pape_resp.auth_age} seconds" if pape_resp.auth_age
0
+ pape_message << "\nNIST Auth Level: #{pape_resp.nist_auth_level}" if pape_resp.nist_auth_level
0
+ flash[:notice] += pape_message
0
       end
0
- when OpenID::Consumer::SETUP_NEEDED
0
- flash[:error] = "Immediate request failed - Setup Needed"
0
- when OpenID::Consumer::CANCEL
0
- flash[:error] = "OpenID transaction cancelled."
0
     end
0
     redirect_to :action => 'index'
0
   end
0
   
0
   private
0
   
0
- # OpenID-Consumer Singleton Accessor, wird für Zugriffe
0
- # auf den Consumer im Controller verwendet
0
+ # OpenID consumer reader, used to access the consumer functionality
0
   def openid_consumer
0
     @openid_consumer ||= OpenID::Consumer.new(session, ActiveRecordStore.new)
0
   end
...
7
8
9
10
 
11
12
 
13
14
15
16
...
44
45
46
47
48
 
 
 
49
50
 
51
52
53
...
60
61
62
63
 
64
65
66
...
75
76
77
78
79
 
 
 
80
81
82
...
149
150
151
 
 
 
 
 
 
 
 
 
 
 
 
152
153
154
...
7
8
9
 
10
11
 
12
13
14
15
16
...
44
45
46
 
 
47
48
49
50
 
51
52
53
54
...
61
62
63
 
64
65
66
67
...
76
77
78
 
 
79
80
81
82
83
84
...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
0
@@ -7,9 +7,9 @@
0
   before_filter :login_required, :except => [:index, :cancel]
0
   before_filter :ensure_valid_checkid_request, :except => [:index, :cancel]
0
   before_filter :clear_checkid_request, :only => [:index]
0
- after_filter :clear_checkid_request, :only => [:cancel]
0
+ after_filter :clear_checkid_request, :only => [:cancel, :complete]
0
   # These methods are used to display information about the request to the user
0
- helper_method :sreg_request, :required_sreg_fields, :optional_sreg_fields
0
+ helper_method :sreg_request, :ax_fetch_request
0
   
0
   # This is the server endpoint which handles all incoming OpenID requests.
0
   # Associate and CheckAuth requests are answered directly - functionality
0
0
@@ -44,10 +44,11 @@
0
     identity = identifier(current_account)
0
     if @site = current_account.sites.find_by_url(checkid_request.trust_root)
0
       resp = checkid_request.answer(true, nil, identity)
0
- resp = add_sreg(checkid_request, resp, @site.properties) if sreg_request
0
- resp = add_pape(checkid_request, resp)
0
+ resp = add_sreg(resp, @site.sreg_properties) if sreg_request
0
+ resp = add_ax(resp, @site.ax_properties) if ax_fetch_request
0
+ resp = add_pape(resp)
0
       render_response(resp)
0
- elsif checkid_request.immediate && sreg_request
0
+ elsif checkid_request.immediate && (sreg_request || ax_fetch_request)
0
       render_response(checkid_request.answer(false))
0
     elsif checkid_request.immediate
0
       render_response(checkid_request.answer(true, nil, identity))
0
@@ -60,7 +61,7 @@
0
   # choose which data should be transfered to the relying party.
0
   def decide
0
     @site = current_account.sites.find_or_initialize_by_url(checkid_request.trust_root)
0
- @site.persona = current_account.personas.find(params[:persona_id] || :first) if sreg_request_request
0
+ @site.persona = current_account.personas.find(params[:persona_id] || :first) if sreg_request || ax_fetch_request
0
   end
0
   
0
   # This action is called by submitting the decision form, the information entered by
0
@@ -75,8 +76,9 @@
0
         @site.update_attributes(params[:site])
0
       end
0
       resp = checkid_request.answer(true, nil, identifier(current_account))
0
- resp = add_pape(checkid_request, resp)
0
- resp = add_sreg(checkid_request, resp, params[:site][:properties]) if sreg_request && params[:site][:properties]
0
+ resp = add_pape(resp)
0
+ resp = add_sreg(resp, params[:site][:sreg]) if sreg_request && params[:site][:sreg]
0
+ resp = add_ax(resp, transform_ax_data(params[:site][:ax])) if ax_fetch_request && params[:site][:ax]
0
       render_response(resp)
0
     end
0
   end
0
@@ -149,6 +151,18 @@
0
   def render_response(resp)
0
     clear_checkid_request
0
     render_openid_response(resp)
0
+ end
0
+
0
+ # Transforms the parameters from the form to valid AX response values
0
+ def transform_ax_data(parameters)
0
+ data = {}
0
+ parameters.each_pair do |key, details|
0
+ if details['value']
0
+ data["type.#{key}"] = details['type']
0
+ data["value.#{key}"] = details['value']
0
+ end
0
+ end
0
+ data
0
   end
0
   
0
 end
...
24
25
26
27
 
28
29
30
...
24
25
26
 
27
28
29
30
0
@@ -24,7 +24,7 @@
0
   def property_label_text(property)
0
     case property.to_sym
0
     when :fullname then 'Full name'
0
- when :dob then 'Date of birth'
0
+ when :dob then 'Birth date'
0
     else property.to_s.humanize
0
     end
0
   end
...
1
2
3
4
 
5
6
 
7
8
 
 
 
 
9
10
11
...
1
2
3
 
4
5
 
6
7
8
9
10
11
12
13
14
15
0
@@ -1,11 +1,15 @@
0
 module ServerHelper
0
   
0
   def sreg_request_for_field(field_name)
0
- if required_sreg_fields.include?(field_name)
0
+ if sreg_request.required.include?(field_name)
0
       "required"
0
- elsif optional_sreg_fields.include?(field_name)
0
+ elsif sreg_request.optional.include?(field_name)
0
       "optional"
0
     end
0
+ end
0
+
0
+ def ax_request_for_field(ax_attribute)
0
+ ax_attribute.required ? "required" : "optional"
0
   end
0
   
0
 end
...
13
14
15
16
17
18
 
19
20
 
 
 
 
 
 
21
22
23
24
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
...
13
14
15
 
16
 
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
0
@@ -13,15 +13,36 @@
0
   
0
   class NotDeletable < StandardError; end
0
   
0
- # Returns an array with all supported property keys.
0
   def self.properties
0
- %w(nickname email fullname postcode country language timezone gender dob)
0
+ Persona.mappings.keys
0
   end
0
   
0
+ # Returns the personas attribute for the given SReg name or AX Type URI
0
+ def property(type)
0
+ prop = Persona.mappings.detect { |i| i[1].include?(type) }
0
+ prop ? self[prop[0]].to_s : ""
0
+ end
0
+
0
   protected
0
   
0
   def check_deletable!
0
     raise NotDeletable unless deletable
0
   end
0
+
0
+ private
0
+
0
+ # Mappings for SReg names and AX Type URIs to attributes
0
+ def self.mappings
0
+ { 'nickname' => ['nickname', 'http://axschema.org/namePerson/friendly'],
0
+ 'email' => ['email', 'http://axschema.org/contact/email'],
0
+ 'fullname' => ['fullname', 'http://axschema.org/namePerson'],
0
+ 'postcode' => ['postcode', 'http://axschema.org/contact/postalCode/home'],
0
+ 'country' => ['country', 'http://axschema.org/contact/country/home'],
0
+ 'language' => ['language', 'http://axschema.org/pref/language'],
0
+ 'timezone' => ['timezone', 'http://axschema.org/pref/timezone'],
0
+ 'gender' => ['gender', 'http://axschema.org/person/gender'],
0
+ 'dob' => ['dob', 'http://axschema.org/birthDate'] }
0
+ end
0
+
0
 end
...
3
4
5
6
 
7
...
3
4
5
 
6
7
0
@@ -3,6 +3,6 @@
0
   
0
   validates_presence_of :site
0
   validates_presence_of :property
0
- validates_uniqueness_of :property, :scope => :site_id
0
+ validates_uniqueness_of :property, :scope => [:site_id, :type_identifier]
0
 end
...
5
6
7
8
 
9
10
11
 
 
12
13
14
15
 
 
16
17
18
19
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24
25
...
5
6
7
 
8
9
 
 
10
11
12
13
 
 
14
15
16
17
18
 
 
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
0
@@ -5,21 +5,46 @@
0
   
0
   validates_presence_of :url, :persona, :account
0
   validates_uniqueness_of :url, :scope => :account_id
0
- attr_accessible :url, :persona_id, :properties
0
+ attr_accessible :url, :persona_id, :properties, :ax, :sreg
0
   
0
- # Sets the release policies by first deleting the old ones
0
- # and then appending a new one for every given property key.
0
+ # Sets the release policies by first deleting the old ones and
0
+ # then appending a new one for every given sreg and ax property.
0
   def properties=(props)
0
     release_policies.destroy_all
0
- props.each_pair do |key, value|
0
- release_policies.build(:property => key)
0
+ props.each_pair do |property, details|
0
+ release_policies.build(:property => property, :type_identifier => details['type']) if details['value']
0
     end
0
   end
0
   
0
- # Returns a hash with all released properties
0
- def properties
0
+ def ax=(props)
0
+ props.each_pair do |property, details|
0
+ release_policies.build(:property => property, :type_identifier => details['type']) if details['value']
0
+ end
0
+ end
0
+
0
+ def sreg=(props)
0
+ props.each_key do |property|
0
+ release_policies.build(:property => property, :type_identifier => property)
0
+ end
0
+ end
0
+
0
+ # Returns a hash with all released SReg properties
0
+ def sreg_properties
0
     props = {}
0
- release_policies.each { |rp| props[rp.property] = persona[rp.property].to_s }
0
+ release_policies.each { |rp| props[rp.property] = persona.property(rp.property) if rp.property == rp.type_identifier }
0
+ props
0
+ end
0
+
0
+ # Returns a hash with all released AX properties
0
+ def ax_properties
0
+ props = {}
0
+ release_policies.each do |rp|
0
+ type = rp.type_identifier
0
+ unless rp.property == type
0
+ props["type.#{rp.property}"] = type
0
+ props["value.#{rp.property}"] = persona.property(type)
0
+ end
0
+ end
0
     props
0
   end
0
   
...
8
9
10
 
11
12
13
...
15
16
17
 
18
19
20
...
22
23
24
 
25
26
27
...
8
9
10
11
12
13
14
...
16
17
18
19
20
21
22
...
24
25
26
27
28
29
30
0
@@ -8,6 +8,7 @@
0
       xml.Type OpenID::OPENID_2_0_TYPE
0
       xml.Type OpenID::SReg::NS_URI_1_1
0
       xml.Type OpenID::SReg::NS_URI_1_0
0
+ xml.Type OpenID::AX::AXMessage::NS_URI
0
       xml.URI endpoint_url
0
       xml.LocalID identity_url(:account => @account, :protocol => scheme)
0
     end
0
@@ -15,6 +16,7 @@
0
       xml.Type OpenID::OPENID_1_1_TYPE
0
       xml.Type OpenID::SReg::NS_URI_1_1
0
       xml.Type OpenID::SReg::NS_URI_1_0
0
+ xml.Type OpenID::AX::AXMessage::NS_URI
0
       xml.URI endpoint_url
0
       xml.tag!('openid:Delegate', identity_url(:account => @account, :protocol => scheme))
0
     end
0
@@ -22,6 +24,7 @@
0
       xml.Type OpenID::OPENID_1_0_TYPE
0
       xml.Type OpenID::SReg::NS_URI_1_1
0
       xml.Type OpenID::SReg::NS_URI_1_0
0
+ xml.Type OpenID::AX::AXMessage::NS_URI
0
       xml.URI endpoint_url
0
       xml.tag!('openid:Delegate', identity_url(:account => @account, :protocol => scheme))
0
     end
...
1
2
3
4
5
6
7
...
11
12
13
14
 
15
16
 
 
 
 
17
18
19
...
 
 
 
1
2
3
4
...
8
9
10
 
11
12
13
14
15
16
17
18
19
20
0
@@ -1,6 +1,3 @@
0
-<% if flash[:sreg_results] %><div class='alert'><%= flash[:sreg_results] %></div><% end %>
0
-<% if flash[:pape_results] %><div class='alert'><%= flash[:pape_results] %></div><% end %>
0
-
0
 <% form_tag consumer_start_path do %>
0
   <div class="row">
0
     <%= label_tag :openid_identifier, 'Identifier:', :class => 'check' %>
0
0
@@ -11,9 +8,13 @@
0
     <%= check_box_tag :immediate %>
0
     <%= label_tag :immediate, 'Use immediate mode', :class => 'check' %>
0
   </div>
0
- <div class="row">
0
+ <div class="row">
0
     <%= check_box_tag :use_sreg %>
0
     <%= label_tag :use_sreg, 'Request registration data', :class => 'check' %>
0
+ </div>
0
+ <div class="row">
0
+ <%= check_box_tag :use_ax %>
0
+ <%= label_tag :use_ax, 'Request attribute exchange data', :class => 'check' %>
0
   </div>
0
   <div class="row">
0
     <%= check_box_tag :use_pape %>
...
36
37
38
39
40
 
 
41
42
43
...
36
37
38
 
 
39
40
41
42
43
0
@@ -36,8 +36,8 @@
0
     </div>
0
     <div id="main">
0
       <div class="wrap">
0
- <% if flash[:notice] %><p class="notice"><%=h flash[:notice] %></p><% end %>
0
- <% if flash[:error] %><p class="error"><%=h flash[:error] %></p><% end %>
0
+ <% if flash[:notice] %><div class="notice"><%=simple_format h(flash[:notice]) %></div><% end %>
0
+ <% if flash[:error] %><div class="error"><%=simple_format h(flash[:error]) %></div><% end %>
0
         <%= yield %>
0
       </div>
0
     </div>
...
13
14
15
16
17
18
 
 
 
19
20
21
...
13
14
15
 
 
 
16
17
18
19
20
21
0
@@ -13,9 +13,9 @@
0
     </div>
0
     <div id="main">
0
       <div class="wrap">
0
- <h2>OpenID consumer testsuite</h2>
0
- <% if flash[:notice] %><p class="notice"><%=h flash[:notice] %></p><% end %>
0
- <% if flash[:error] %><p class="error"><%=h flash[:error] %></p><% end %>
0
+ <h2>OpenID consumer testsuite</h2>
0
+ <% if flash[:notice] %><div class="notice"><%=simple_format h flash[:notice] %></div><% end %>
0
+ <% if flash[:error] %><div class="error"><%=simple_format h flash[:error] %></div><% end %>
0
         <%= yield %>
0
       </div>
0
     </div>
...
4
5
6
7
8
 
9
10
11
12
13
...
19
20
21
22
 
23
24
25
26
 
27
28
29
 
30
31
32
33
34
35
...
35
36
37
38
 
39
40
41
42
43
 
 
 
 
44
45
 
 
 
 
 
 
 
 
 
 
 
 
46
47
48
49
50
 
51
52
53
...
4
5
6
 
 
7
8
9
10
11
12
...
18
19
20
 
21
22
23
24
 
25
26
27
 
28
29
30
31
32
33
34
...
34
35
36
 
37
38
 
 
 
 
39
40
41
42
43
 
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 
60
61
62
63
0
@@ -4,8 +4,7 @@
0
 <% form_tag decide_path, :method => :get do %>
0
 
0
   <h3>Choose a persona</h3>
0
- <p><%=h extract_host(@site.url) %> requests your registration data
0
- (<%= required_sreg_fields.to_sentence(:skip_last_comma => true) %>).<br />
0
+ <p><%=h extract_host(@site.url) %> requests your data.<br />
0
   Please select a persona to choose this data from.</p>
0
 
0
   <div class="row">
0
0
0
@@ -19,14 +18,14 @@
0
     <%= link_to "create new persona", new_account_persona_path(:return => decide_path) %>
0
   </div>
0
   
0
-<% end if sreg_request _request %>
0
+<% end if sreg_request || ax_fetch_request %>
0
 
0
 <% form_for @site, :url => complete_path do |f| %>
0
 
0
- <% if sreg_request _request %>
0
+ <% if sreg_request || ax_fetch_request %>
0
     <h3><%=h @site.persona.title %> <span class="note"><%= link_to "edit persona", edit_account_persona_path(@site.persona, :return => decide_path(:persona_id => @site.persona.id)) %></span></h3>
0
     <p>Please choose the data that you would like to pass on.
0
- <%= link_to "#{h extract_host(@site.url)} privacy policy", sreg_request.policy_url unless sreg_request.policy_url.blank? %></p>
0
+ <%= link_to "#{h extract_host(@site.url)} privacy policy", sreg_request.policy_url unless !sreg_request || sreg_request.policy_url.blank? %></p>
0
     
0
     <table cellspacing="0">
0
    <tr>
0
0
0
0
@@ -35,19 +34,30 @@
0
         <th>requirement</th>
0
         <th>release</th>
0
       </tr>
0
- <% (required_sreg_fields + optional_sreg_fields).each do |property| %>
0
+ <% (sreg_request.required + sreg_request.optional).each do |property| %>
0
       <tr>
0
- <td><%= label_tag "site_properties_#{property}", property_label_text(property) %></td>
0
- <td><%= label_tag "site_properties_#{property}", @site.persona[property] %></td>
0
- <td><%= label_tag "site_properties_#{property}", sreg_request_for_field(property) %></td>
0
- <td><%= check_box_tag "site[properties][#{property}]", @site.persona[property], false, :id => "site_properties_#{property}" %></td>
0
+ <td><%= label_tag "site_sreg_#{property}", property_label_text(property) %></td>
0
+ <td><%= label_tag "site_sreg_#{property}", @site.persona.property(property) %></td>
0
+ <td><%= label_tag "site_sreg_#{property}", sreg_request_for_field(property) %></td>
0
+ <td><%= check_box_tag "site[sreg][#{property}]", @site.persona.property(property), false, :id => "site_sreg_#{property}", :class => sreg_request_for_field(property) %></td>
0
       </tr>
0
- <% end %>
0
+ <% end if sreg_request %>
0
+ <% ax_fetch_request.attributes.each do |property| %>
0
+ <tr>
0
+ <td><%= label_tag "site_ax_#{property.ns_alias}", property_label_text(property.ns_alias) %></td>
0
+ <td><%= label_tag "site_ax_#{property.ns_alias}", @site.persona.property(property.type_uri) %></td>
0
+ <td><%= label_tag "site_ax_#{property.ns_alias}", ax_request_for_field(property) %></td>
0
+ <td>
0
+ <%= check_box_tag "site[ax][#{property.ns_alias}][value]", @site.persona.property(property.type_uri), false, :id => "site_ax_#{property.ns_alias}", :class => ax_request_for_field(property) %>
0
+ <%= hidden_field_tag "site[ax][#{property.ns_alias}][type]", property.type_uri, :id => "site_ax_type_#{property.ns_alias}" %>
0
+ </td>
0
+ </tr>
0
+ <% end if ax_fetch_request %>
0
     </table>
0
   <% end %>
0
   
0
   <div>
0
- <% if sreg_request _request %>
0
+ <% if sreg_request || ax_fetch_request %>
0
     <%= f.hidden_field :persona_id %>
0
     <%= f.hidden_field :url %>
0
     <%= submit_tag 'Always trust this site', :name => 'always', :class => 'space' %>
...
8
9
10
 
11
12
13
...
8
9
10
11
12
13
14
0
@@ -8,6 +8,7 @@
0
       xml.Type OpenID::OPENID_IDP_2_0_TYPE
0
       xml.Type OpenID::SReg::NS_URI_1_1
0
       xml.Type OpenID::SReg::NS_URI_1_0
0
+ xml.Type OpenID::AX::AXMessage::NS_URI
0
       xml.URI endpoint_url
0
     end
0
   end
...
19
20
21
22
 
23
24
25
26
27
 
 
28
29
30
31
 
 
 
 
 
32
33
34
...
19
20
21
 
22
23
24
25
26
 
27
28
29
30
 
 
31
32
33
34
35
36
37
38
0
@@ -19,16 +19,20 @@
0
   </h3>
0
   
0
   <table cellspacing="0">
0
- <tr>
0
+ <tr>
0
       <th>property</th>
0
       <th>value</th>
0
       <th>released?</th>
0
     </tr>
0
- <% Persona.properties.each do |property| %>
0
+ <% @site.release_policies.each do |release_policy| %>
0
+ <% property, type, value = release_policy.property, release_policy.type_identifier, @site.persona.property(release_policy.type_identifier) %>
0
     <tr>
0
       <td><%= label_tag "site_properties_#{property}", property_label_text(property) %></td>
0
- <td><%= label_tag "site_properties_#{property}", @site.persona[property] unless @site.persona[property].blank? %></td>
0
- <td><%= check_box_tag "site[properties][#{property}]", @site.persona[property], @site.release_policies.find_by_property(property), :id => "site_properties_#{property}" %></td>
0
+ <td><%= label_tag "site_properties_#{property}", value unless value.blank? %></td>
0
+ <td>
0
+ <%= check_box_tag "site[properties][#{property}][value]", value, true, :id => "site_properties_#{property}" %>
0
+ <%= hidden_field_tag "site[properties][#{property}][type]", type, :id => "site_properties_type_#{property}" %>
0
+ </td>
0
     </tr>
0
     <% end %>
0
   </table>
...
56
57
58
59
 
60
61
62
...
56
57
58
 
59
60
61
62
0
@@ -56,7 +56,7 @@
0
 
0
 * let the user set a standard persona which is used as default for requests
0
 * let the user choose to display information on his identity page (hCard)
0
-* add support for {Attribute Exchange}[http://openid.net/specs/openid-attribute-exchange-1_0.html]
0
+* add support for {Attribute Exchange Store Requests}[http://openid.net/specs/openid-attribute-exchange-1_0.html]
0
 
0
 == Notes
0