Permalink
Browse files

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...
1 parent ffa1b57 commit d5fcb375ac84363e0c485f18db5a55c2f425655e @herestomwiththeweather herestomwiththeweather committed May 20, 2011
@@ -50,10 +50,6 @@ def logged_in?
!!current_person
end
- def authorized?
- logged_in?
- end
-
def login_required
unless current_person
store_location
@@ -96,6 +92,10 @@ def current_user
current_person
end
+ def current_ability
+ @current_ability ||= Ability.new(current_person, current_token)
+ end
+
def set_person_locale
if logged_in?
I18n.locale = current_person.language
@@ -79,6 +79,9 @@ def create
respond_to do |format|
if @exchange.save
+ if !current_token.nil? && current_token.action_id == 'single_payment'
+ current_token.invalidate!
+ end
flash[:notice] = t('success_credit_transfer_succeeded')
format.html { redirect_to person_path(@person) and return }
format.xml { render :xml => @exchange, :status => :created, :location => [@person, @exchange] }
@@ -66,6 +66,9 @@ def create
@transact.metadata = @transact.create_req(params[:memo])
if can?(:create, @transact) && @transact.save
+ if !current_token.nil? && current_token.action_id == 'single_payment'
+ current_token.invalidate!
+ end
if @transact.redirect_url.blank?
flash[:notice] = t('notice_transfer_succeeded')
respond_to do |format|
View
@@ -1,6 +1,6 @@
class Ability
include CanCan::Ability
- def initialize(person)
+ def initialize(person, access_token = nil)
can [:read, :create], Group
can [:new_req,:create_req], Group
can [:new_offer,:create_offer], Group
@@ -80,8 +80,12 @@ def initialize(person)
unless membership
false
else
- account = person.account(exchange.group)
- account && (account.authorized? exchange.amount)
+ unless (access_token.nil? || access_token.authorized_for?(exchange.amount))
+ false
+ else
+ account = person.account(exchange.group)
+ account && (account.authorized? exchange.amount)
+ end
end
end
end
@@ -48,6 +48,7 @@ def credentials
def create_request_token(params={})
if params[:scope]
scope_uri = URI.parse(params[:scope])
+ # XXX ignoring host:port and assuming it's our host:port
filepath = RAILS_ROOT + '/public' + scope_uri.path
if File.exist?(filepath)
# valid asset is required
@@ -34,14 +34,22 @@ def scope_hash
end
def asset
- scope_hash['asset']
+ scope_hash['asset'][0]
end
def amount
- scope_hash['amount']
+ scope_hash['amount'][0]
+ end
+
+ def authorized_for?(requested_amount)
+ ['single_payment','recurring_payment'].include?(action_id) && requested_amount <= amount.to_f && !invalidated?
end
# XXX assuming just one scope for now
+ def action_id
+ action['_id']
+ end
+
def action_name
action['name']
end
@@ -6,7 +6,7 @@
<%= hidden_field_tag "oauth_callback", params[:oauth_callback] %>
<%- end -%>
<p>
- <%= check_box_tag 'authorize' %> authorize <span id="scope-action"><%= @token.action_name %></span> <img src="<%= @token.action_icon_uri %>"> in <%= @token.asset %>
+ <%= check_box_tag 'authorize' %> authorize <span id="scope-action"><%= @token.action_name %></span> <img src="<%= @token.action_icon_uri %>"> of <%= @token.amount %> <%= @token.asset %>
</p>
<p>
<%= submit_tag %>
@@ -2,6 +2,8 @@
require 'cancan/matchers'
describe Group do
+ fixtures :client_applications, :people, :oauth_tokens, :groups
+
before(:each) do
@p = people(:quentin)
@p2 = people(:aaron)
@@ -10,6 +12,7 @@
:description => "value for description",
:mode => Group::PUBLIC,
:unit => "value for unit",
+ :asset => "infinities",
:owner => @p,
:adhoc_currency => true
}
@@ -146,6 +149,77 @@
@ability.should_not be_able_to(:create,@e)
end
+ describe 'delegated payments with oauth' do
+ before(:each) do
+ @token = RequestToken.new :client_application => client_applications(:one), :group => @g, :callback_url => "http://example.com/callback"
+ end
+
+ it "should not allow a payment with wrong scope type" do
+ # _id = "read_payments"
+ @token.scope = "http://localhost/scopes/list_payments.json?asset=#{@g.asset}"
+ @token.save
+ @token.authorize!(@p2)
+
+ @token.provided_oauth_verifier = @token.verifier
+ @access_token = @token.exchange!
+
+ @scoped_ability = Ability.new(@p2,@access_token)
+ @e.customer = @p2
+ @scoped_ability.should_not be_able_to(:create,@e)
+ end
+
+ it "should allow a payment with the right scope type" do
+ # _id = "single_payment"
+ @token.scope = "http://localhost/scopes/single_payment.json?amount=10&asset=#{@g.asset}"
+ @token.save
+ @token.authorize!(@p2)
+
+ @token.provided_oauth_verifier = @token.verifier
+ @access_token = @token.exchange!
+
+ @scoped_ability = Ability.new(@p2,@access_token)
+ @e.customer = @p2
+ @scoped_ability.should be_able_to(:create,@e)
+ end
+
+ it "should not allow a single payment that exceeds the authorized amount" do
+ # _id = "single_payment"
+ @token.scope = "http://localhost/scopes/single_payment.json?amount=0.5&asset=#{@g.asset}"
+ @token.save
+ @token.authorize!(@p2)
+
+ @token.provided_oauth_verifier = @token.verifier
+ @access_token = @token.exchange!
+
+ @scoped_ability = Ability.new(@p2,@access_token)
+ @e.customer = @p2
+ @scoped_ability.should_not be_able_to(:create,@e)
+ end
+
+ it "should not allow a single payment to be made more than once" do
+ # _id = "single_payment"
+ @token.scope = "http://localhost/scopes/single_payment.json?amount=1&asset=#{@g.asset}"
+ @token.save
+ @token.authorize!(@p2)
+
+ @token.provided_oauth_verifier = @token.verifier
+ @access_token = @token.exchange!
+
+ @scoped_ability = Ability.new(@p2,@access_token)
+ @e.customer = @p2
+
+ # first check, pay, invalidate
+ if @scoped_ability.can? :create, @e
+ @e.save
+ # when access token present, invalidate on successful payment
+ if @access_token.action_id == 'single_payment'
+ @access_token.invalidate!
+ end
+ end
+ @scoped_ability.should_not be_able_to(:create,@e)
+ end
+ end
+
describe 'account balances' do
before(:each) do
@membership.roles = ['individual']
@@ -3,7 +3,6 @@
describe RequestToken do
fixtures :client_applications, :people, :oauth_tokens, :groups
before(:each) do
- @token = RequestToken.create :client_application => client_applications(:one)
@token = RequestToken.create :client_application => client_applications(:one), :group => groups(:one), :scope => "http://localhost/scopes/list_payments.json?asset=hours"
end

0 comments on commit d5fcb37

Please sign in to comment.