validate payment pointer (#11702)

* Add validation for payment_pointer and clean its space before save

* Add test for payment_pointer

* fix payment pointer regexp

* fix test

* Remove space with strip

Co-authored-by: Jacob Herrington <jacobherringtondeveloper@gmail.com>

* Remove redundant test

* Refactor clean_payment_pointer to strip_payment_pointer
- Move callback from before_save to before_validation

* Refactor PAYMENT_POINTER_REGEXP

* style: remove last comment in regexp

* fix typo

Co-authored-by: Jacob Herrington <jacobherringtondeveloper@gmail.com>
This commit is contained in:
Chien-Wei Huang (Michael) 2020-12-05 01:00:25 +08:00 committed by GitHub
parent 4b2b9ebd47
commit f7a9f0d2b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 0 deletions

View file

@ -83,6 +83,14 @@ class User < ApplicationRecord
invalid_editor_version: "%<value>s must be either v1 or v2",
reserved_username: "username is reserved"
}.freeze
# follow the syntax in https://interledger.org/rfcs/0026-payment-pointers/#payment-pointer-syntax
PAYMENT_POINTER_REGEXP = %r{
\A # start
\$ # starts with a dollar sign
([a-zA-Z0-9\-.])+ # matches the hostname (ex ilp.uphold.com)
(/[\x20-\x7F]+)? # optional forward slash and identifier with printable ASCII characters
\z
}x.freeze
attr_accessor :scholar_email, :new_note, :note_for_current_role, :user_status, :pro, :merge_user_id,
:add_credits, :remove_credits, :add_org_credits, :remove_org_credits, :ip_address
@ -205,6 +213,7 @@ class User < ApplicationRecord
validates :inbox_type, inclusion: { in: INBOXES }
validates :name, length: { in: 1..100 }
validates :password, length: { in: 8..100 }, allow_nil: true
validates :payment_pointer, format: PAYMENT_POINTER_REGEXP, allow_nil: true
validates :rating_votes_count, presence: true
validates :reactions_count, presence: true
validates :sign_in_count, presence: true
@ -252,6 +261,7 @@ class User < ApplicationRecord
# make sure usernames are not empty, to be able to use the database unique index
before_validation :verify_email
before_validation :set_username
before_validation :strip_payment_pointer
before_create :set_default_language
before_destroy :unsubscribe_from_newsletters, prepend: true
before_destroy :destroy_follows, prepend: true
@ -669,4 +679,8 @@ class User < ApplicationRecord
errors.add(:password, "doesn't match password confirmation")
end
def strip_payment_pointer
self.payment_pointer = payment_pointer.strip if payment_pointer
end
end

View file

@ -187,6 +187,11 @@ RSpec.describe User, type: :model do
it { is_expected.not_to allow_value("AcMe_1%").for(:username) }
it { is_expected.to allow_value("AcMe_1").for(:username) }
it { is_expected.not_to allow_value("$example.com/value\x1F").for(:payment_pointer) }
it { is_expected.not_to allow_value("example.com/value").for(:payment_pointer) }
it { is_expected.to allow_value(" $example.com/value ").for(:payment_pointer) }
it { is_expected.to allow_value(nil).for(:payment_pointer) }
it { is_expected.to validate_inclusion_of(:inbox_type).in_array(%w[open private]) }
it { is_expected.to validate_length_of(:email).is_at_most(50).allow_nil }

View file

@ -53,4 +53,17 @@ RSpec.describe "User edits their extensions", type: :system, js: true do
expect(page).to have_text("Feed url is not a valid RSS/Atom feed")
end
end
describe "PaymentPointer" do
before do
visit user_settings_path(:extensions)
end
it "fails if the payment pointer is invalid" do
fill_in "user[payment_pointer]", with: "invalid_example/value"
click_on "Save Web Monetization Settings"
expect(page).to have_text("Payment pointer is invalid")
end
end
end