Skip to content
This repository
Browse code

groupy branch: specs and implementation of single payment oauth scope…

…. redefine current_ability so that it passes current_token to Ability constructor
  • Loading branch information...
commit d5fcb375ac84363e0c485f18db5a55c2f425655e 1 parent ffa1b57
Tom Brown authored
8  app/controllers/application_controller.rb
@@ -50,10 +50,6 @@ def logged_in?
50 50
       !!current_person
51 51
     end
52 52
 
53  
-    def authorized?
54  
-      logged_in?
55  
-    end
56  
-
57 53
     def login_required
58 54
       unless current_person
59 55
         store_location
@@ -96,6 +92,10 @@ def current_user
96 92
       current_person 
97 93
     end
98 94
 
  95
+    def current_ability
  96
+      @current_ability ||= Ability.new(current_person, current_token)
  97
+    end
  98
+
99 99
     def set_person_locale
100 100
       if logged_in?
101 101
         I18n.locale = current_person.language
3  app/controllers/exchanges_controller.rb
@@ -79,6 +79,9 @@ def create
79 79
 
80 80
     respond_to do |format|
81 81
       if @exchange.save
  82
+        if !current_token.nil? && current_token.action_id == 'single_payment'
  83
+          current_token.invalidate!
  84
+        end
82 85
         flash[:notice] = t('success_credit_transfer_succeeded')
83 86
         format.html { redirect_to person_path(@person) and return }
84 87
         format.xml { render :xml => @exchange, :status => :created, :location => [@person, @exchange] }
3  app/controllers/transacts_controller.rb
@@ -66,6 +66,9 @@ def create
66 66
     @transact.metadata = @transact.create_req(params[:memo])
67 67
 
68 68
     if can?(:create, @transact) && @transact.save
  69
+      if !current_token.nil? && current_token.action_id == 'single_payment'
  70
+        current_token.invalidate!
  71
+      end
69 72
       if @transact.redirect_url.blank?
70 73
         flash[:notice] = t('notice_transfer_succeeded')
71 74
         respond_to do |format|
10  app/models/ability.rb
... ...
@@ -1,6 +1,6 @@
1 1
 class Ability
2 2
   include CanCan::Ability
3  
-  def initialize(person)
  3
+  def initialize(person, access_token = nil)
4 4
     can [:read, :create], Group
5 5
     can [:new_req,:create_req], Group
6 6
     can [:new_offer,:create_offer], Group
@@ -80,8 +80,12 @@ def initialize(person)
80 80
         unless membership
81 81
           false
82 82
         else
83  
-          account = person.account(exchange.group)
84  
-          account && (account.authorized? exchange.amount)
  83
+          unless (access_token.nil? || access_token.authorized_for?(exchange.amount))
  84
+            false
  85
+          else
  86
+            account = person.account(exchange.group)
  87
+            account && (account.authorized? exchange.amount)
  88
+          end
85 89
         end
86 90
       end
87 91
     end
1  app/models/client_application.rb
@@ -48,6 +48,7 @@ def credentials
48 48
   def create_request_token(params={}) 
49 49
     if params[:scope]
50 50
       scope_uri = URI.parse(params[:scope])
  51
+      # XXX ignoring host:port and assuming it's our host:port
51 52
       filepath = RAILS_ROOT + '/public' + scope_uri.path
52 53
       if File.exist?(filepath)
53 54
         # valid asset is required
12  app/models/oauth_token.rb
@@ -34,14 +34,22 @@ def scope_hash
34 34
   end
35 35
     
36 36
   def asset
37  
-    scope_hash['asset']
  37
+    scope_hash['asset'][0]
38 38
   end
39 39
 
40 40
   def amount
41  
-    scope_hash['amount']
  41
+    scope_hash['amount'][0]
  42
+  end
  43
+
  44
+  def authorized_for?(requested_amount)
  45
+    ['single_payment','recurring_payment'].include?(action_id) && requested_amount <= amount.to_f && !invalidated?
42 46
   end
43 47
 
44 48
   # XXX assuming just one scope for now
  49
+  def action_id
  50
+    action['_id']
  51
+  end
  52
+
45 53
   def action_name
46 54
     action['name']
47 55
   end
2  app/views/oauth/authorize.html.erb
@@ -6,7 +6,7 @@
6 6
   <%= hidden_field_tag "oauth_callback", params[:oauth_callback] %>
7 7
 <%- end -%>
8 8
 <p>
9  
-  <%= check_box_tag 'authorize' %> authorize <span id="scope-action"><%= @token.action_name %></span> <img src="<%= @token.action_icon_uri %>"> in <%= @token.asset %>
  9
+  <%= check_box_tag 'authorize' %> authorize <span id="scope-action"><%= @token.action_name %></span> <img src="<%= @token.action_icon_uri %>"> of <%= @token.amount %> <%= @token.asset %>
10 10
 </p>
11 11
 <p>
12 12
   <%= submit_tag %>
74  spec/models/group_spec.rb
@@ -2,6 +2,8 @@
2 2
 require 'cancan/matchers'
3 3
 
4 4
 describe Group do
  5
+  fixtures :client_applications, :people, :oauth_tokens, :groups
  6
+
5 7
   before(:each) do
6 8
     @p = people(:quentin)
7 9
     @p2 = people(:aaron)
@@ -10,6 +12,7 @@
10 12
       :description => "value for description",
11 13
       :mode => Group::PUBLIC,
12 14
       :unit => "value for unit",
  15
+      :asset => "infinities",
13 16
       :owner => @p,
14 17
       :adhoc_currency => true
15 18
     }
@@ -146,6 +149,77 @@
146 149
         @ability.should_not be_able_to(:create,@e)
147 150
       end
148 151
 
  152
+      describe 'delegated payments with oauth' do
  153
+        before(:each) do
  154
+          @token = RequestToken.new :client_application => client_applications(:one), :group => @g, :callback_url => "http://example.com/callback"  
  155
+        end
  156
+
  157
+        it "should not allow a payment with wrong scope type" do
  158
+          # _id = "read_payments"
  159
+          @token.scope = "http://localhost/scopes/list_payments.json?asset=#{@g.asset}"
  160
+          @token.save
  161
+          @token.authorize!(@p2)
  162
+
  163
+          @token.provided_oauth_verifier = @token.verifier
  164
+          @access_token = @token.exchange!
  165
+
  166
+          @scoped_ability = Ability.new(@p2,@access_token)
  167
+          @e.customer = @p2
  168
+          @scoped_ability.should_not be_able_to(:create,@e)
  169
+        end
  170
+
  171
+        it "should allow a payment with the right scope type" do
  172
+          # _id = "single_payment"
  173
+          @token.scope = "http://localhost/scopes/single_payment.json?amount=10&asset=#{@g.asset}"
  174
+          @token.save
  175
+          @token.authorize!(@p2)
  176
+
  177
+          @token.provided_oauth_verifier = @token.verifier
  178
+          @access_token = @token.exchange!
  179
+
  180
+          @scoped_ability = Ability.new(@p2,@access_token)
  181
+          @e.customer = @p2
  182
+          @scoped_ability.should be_able_to(:create,@e)
  183
+        end
  184
+
  185
+        it "should not allow a single payment that exceeds the authorized amount" do
  186
+          # _id = "single_payment"
  187
+          @token.scope = "http://localhost/scopes/single_payment.json?amount=0.5&asset=#{@g.asset}"
  188
+          @token.save
  189
+          @token.authorize!(@p2)
  190
+
  191
+          @token.provided_oauth_verifier = @token.verifier
  192
+          @access_token = @token.exchange!
  193
+
  194
+          @scoped_ability = Ability.new(@p2,@access_token)
  195
+          @e.customer = @p2
  196
+          @scoped_ability.should_not be_able_to(:create,@e)
  197
+        end
  198
+
  199
+        it "should not allow a single payment to be made more than once" do
  200
+          # _id = "single_payment"
  201
+          @token.scope = "http://localhost/scopes/single_payment.json?amount=1&asset=#{@g.asset}"
  202
+          @token.save
  203
+          @token.authorize!(@p2)
  204
+
  205
+          @token.provided_oauth_verifier = @token.verifier
  206
+          @access_token = @token.exchange!
  207
+
  208
+          @scoped_ability = Ability.new(@p2,@access_token)
  209
+          @e.customer = @p2
  210
+
  211
+          # first check, pay, invalidate
  212
+          if @scoped_ability.can? :create, @e
  213
+            @e.save
  214
+            # when access token present, invalidate on successful payment
  215
+            if @access_token.action_id == 'single_payment'
  216
+              @access_token.invalidate!
  217
+            end
  218
+          end
  219
+          @scoped_ability.should_not be_able_to(:create,@e)
  220
+        end
  221
+      end
  222
+
149 223
       describe 'account balances' do
150 224
         before(:each) do
151 225
           @membership.roles = ['individual']
1  spec/models/oauth_token_spec.rb
@@ -3,7 +3,6 @@
3 3
 describe RequestToken do
4 4
   fixtures :client_applications, :people, :oauth_tokens, :groups
5 5
   before(:each) do
6  
-    @token = RequestToken.create :client_application => client_applications(:one)
7 6
     @token = RequestToken.create :client_application => client_applications(:one), :group => groups(:one), :scope => "http://localhost/scopes/list_payments.json?asset=hours"
8 7
   end
9 8
 

0 notes on commit d5fcb37

Please sign in to comment.
Something went wrong with that request. Please try again.