Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify ownership of payment_source when creating WalletPaymentSource #3007

Merged

Conversation

ericsaupe
Copy link
Contributor

@ericsaupe ericsaupe commented Dec 18, 2018

This merge request takes care of these things:

  1. It's currently possible for payment sources created by one user to be added to the wallet of another user. This potentially allows one user to use payments stored for other users.
  2. Cleans up data by restricting payment sources being added to a user's wallet if that payment source has already been added to the wallet.
  3. Matches namespacing and inheritance for the Spree::WalletPaymentSource class to be the same as the other models in spree_core inheriting from Spree::Base

@ericsaupe ericsaupe force-pushed the wallet-payment-source-protection branch from b66a8a6 to 749f9c5 Compare December 18, 2018 20:25

validates_presence_of :user
validates_presence_of :payment_source
validates_presence_of :user
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer validates :user, presence: true. Not a big deal though

validates_presence_of :payment_source
validates_presence_of :user
validates_presence_of :payment_source
validates :user_id, uniqueness: { scope: [:payment_source_type, :payment_source_id] }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be worth adding a custom message here. I found the default message on this is going to be User id has already been taken. That message doesn't really denote that the violation is due to the tuple key

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, can we please document why this change is needed in this PR?

validates_presence_of :user
validates_presence_of :payment_source
validates :user_id, uniqueness: { scope: [:payment_source_type, :payment_source_id] }
validate :check_for_payment_source_class
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing the reasoning for this is to mimic what happens in the Spree::Wallet#add method? I'm a fan prepending validation methods with validate so you know the purpose of that method is to validate and if called will add to the object errors. validate_payment_source_class

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@skukx agree but these validations were already there, they have just been indented due to the module change. I think that if we want to change them we need to open another PR and deprecate existing methods.

Copy link
Member

@kennyadsl kennyadsl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ericsaupe, I left some comments to improve PR documentation and also notice the build to fail on something that should be related to this, can you please take a look?

class Spree::WalletPaymentSource < ActiveRecord::Base
belongs_to :user, class_name: Spree::UserClassHandle.new, foreign_key: 'user_id', inverse_of: :wallet_payment_sources
belongs_to :payment_source, polymorphic: true, inverse_of: :wallet_payment_sources
module Spree
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please change the namespace/inheritance stuff into one or more other commits, so they are independently documented? Also, why are these change needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's to follow the format used in the other model files.

validates_presence_of :payment_source
validates_presence_of :user
validates_presence_of :payment_source
validates :user_id, uniqueness: { scope: [:payment_source_type, :payment_source_id] }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, can we please document why this change is needed in this PR?

Without this validation it's possible for a user to add the same
PaymentSource to their wallet multiple times causing dirty data
and additional code in places where the wallet is displayed to
remove duplicates.
This fixes the possibility of a User gaining access to a PaymentSource
that isn't theirs by validating the WalletPaymentSource user_id is the
same as the PaymentSource user_id if one is present.
@skukx
Copy link
Contributor

skukx commented Dec 19, 2018

To clarify some of these changes (each change should probably be documented in it's own commit):

validates :user_id, uniqueness: { scope: [:payment_source_type, :payment_source_id] }

This change is due to a unique tuple key on the database. Adding the validation mirrors what is enforced at the database layer and allows activerecord to handle it. What was a PG::UniqueViolation error becomes an ActiveRecord::RecordInvalid error.


For

validate :validate_payment_source_ownership

It is possible that a user's wallet can have a payment source added to it which does not belong to the user. This means a user could make transactions on a payment source that does not belong to them.

@ericsaupe ericsaupe force-pushed the wallet-payment-source-protection branch from 749f9c5 to f4df47b Compare December 19, 2018 23:46
With the changes made to validate users cannot add payment sources
from other users to their wallet. Some of our specs were using and
adding payment sources created for other users to the wallet of the
user being tested.
@ericsaupe ericsaupe force-pushed the wallet-payment-source-protection branch from f4df47b to 28c66c8 Compare January 10, 2019 22:58
Copy link
Member

@kennyadsl kennyadsl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericsaupe left a question, WDYT?

Copy link
Member

@spaghetticode spaghetticode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏 thank you @ericsaupe

Copy link
Member

@tvdeyen tvdeyen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very good change. The error message could be improved, though.

@@ -488,6 +488,9 @@ en:
attributes:
payment_source:
has_to_be_payment_source_class: has to be a Spree::PaymentSource
not_owned_by_user: does not belong to user
user_id:
payment_source_already_exists: already has the Spree::PaymentSource in their wallet
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a very human friendly error message. Could we use

"already has this payment source in their wallet"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming @ericsaupe took inspiration from the message above. I think we could fix both in this PR.

Copy link
Contributor

@jacobherrington jacobherrington left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am happy with this! 👍 Good work @ericsaupe!

@kennyadsl kennyadsl merged commit b5b2d06 into solidusio:master May 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants