mirror of
https://github.com/stripe/stripe-ruby.git
synced 2025-10-08 00:02:46 -04:00
Adds the magic `frozen_string_literal: true` comment to every file and enables a Rubocop rule to make sure that it's always going to be there going forward as well. See here for more background [1], but the basic idea is that unlike many other languages, static strings in code are mutable by default. This has since been acknowledged as not a particularly good idea, and the intention is to rectify the mistake when Ruby 3 comes out, where all string literals will be frozen. The `frozen_string_literal` magic comment was introduced in Ruby 2.3 as a way of easing the transition, and allows libraries and projects to freeze their literals in advance. I don't think this is breaking in any way: it's possible that users might've been pulling out one of are literals somehow and mutating it, but that would probably not have been useful for anything and would certainly not be recommended, so I'm quite comfortable pushing this change through as a minor version. As discussed in #641. [1] https://stackoverflow.com/a/37799399
141 lines
5.0 KiB
Ruby
141 lines
5.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Stripe
|
|
class Account < APIResource
|
|
extend Gem::Deprecate
|
|
extend Stripe::APIOperations::Create
|
|
extend Stripe::APIOperations::List
|
|
include Stripe::APIOperations::Delete
|
|
include Stripe::APIOperations::Save
|
|
extend Stripe::APIOperations::NestedResource
|
|
|
|
OBJECT_NAME = "account".freeze
|
|
|
|
save_nested_resource :external_account
|
|
nested_resource_class_methods :external_account,
|
|
operations: %i[create retrieve update delete list]
|
|
nested_resource_class_methods :login_link, operations: %i[create]
|
|
|
|
# This method is deprecated. Please use `#external_account=` instead.
|
|
save_nested_resource :bank_account
|
|
deprecate :bank_account=, "#external_account=", 2017, 8
|
|
|
|
def resource_url
|
|
if self["id"]
|
|
super
|
|
else
|
|
"/v1/account"
|
|
end
|
|
end
|
|
|
|
# @override To make id optional
|
|
def self.retrieve(id = ARGUMENT_NOT_PROVIDED, opts = {})
|
|
id = id.equal?(ARGUMENT_NOT_PROVIDED) ? nil : Util.check_string_argument!(id)
|
|
|
|
# Account used to be a singleton, where this method's signature was
|
|
# `(opts={})`. For the sake of not breaking folks who pass in an OAuth
|
|
# key in opts, let's lurkily string match for it.
|
|
if opts == {} && id.is_a?(String) && id.start_with?("sk_")
|
|
# `super` properly assumes a String opts is the apiKey and normalizes as expected.
|
|
opts = id
|
|
id = nil
|
|
end
|
|
super(id, opts)
|
|
end
|
|
|
|
def reject(params = {}, opts = {})
|
|
opts = Util.normalize_opts(opts)
|
|
resp, opts = request(:post, resource_url + "/reject", params, opts)
|
|
initialize_from(resp.data, opts)
|
|
end
|
|
|
|
# Somewhat unfortunately, we attempt to do a special encoding trick when
|
|
# serializing `additional_owners` under an account: when updating a value,
|
|
# we actually send the update parameters up as an integer-indexed hash
|
|
# rather than an array. So instead of this:
|
|
#
|
|
# field[]=item1&field[]=item2&field[]=item3
|
|
#
|
|
# We send this:
|
|
#
|
|
# field[0]=item1&field[1]=item2&field[2]=item3
|
|
#
|
|
# There are two major problems with this technique:
|
|
#
|
|
# * Entities are addressed by array index, which is not stable and can
|
|
# easily result in unexpected results between two different requests.
|
|
#
|
|
# * A replacement of the array's contents is ambiguous with setting a
|
|
# subset of the array. Because of this, the only way to shorten an
|
|
# array is to unset it completely by making sure it goes into the
|
|
# server as an empty string, then setting its contents again.
|
|
#
|
|
# We're trying to get this overturned on the server side, but for now,
|
|
# patch in a special allowance.
|
|
def serialize_params(options = {})
|
|
serialize_params_account(self, super)
|
|
end
|
|
|
|
def serialize_params_account(_obj, update_hash)
|
|
if (entity = @values[:legal_entity])
|
|
if (owners = entity[:additional_owners])
|
|
entity_update = update_hash[:legal_entity] ||= {}
|
|
entity_update[:additional_owners] =
|
|
serialize_additional_owners(entity, owners)
|
|
end
|
|
end
|
|
update_hash
|
|
end
|
|
|
|
def self.protected_fields
|
|
[:legal_entity]
|
|
end
|
|
|
|
def legal_entity
|
|
self["legal_entity"]
|
|
end
|
|
|
|
def legal_entity=(_)
|
|
raise NoMethodError, 'Overridding legal_entity can cause serious issues. Instead, set the individual fields of legal_entity like blah.legal_entity.first_name = \'Blah\''
|
|
end
|
|
|
|
def deauthorize(client_id = nil, opts = {})
|
|
params = {
|
|
client_id: client_id,
|
|
stripe_user_id: id,
|
|
}
|
|
OAuth.deauthorize(params, opts)
|
|
end
|
|
|
|
ARGUMENT_NOT_PROVIDED = Object.new
|
|
|
|
private
|
|
|
|
def serialize_additional_owners(legal_entity, additional_owners)
|
|
original_value = legal_entity.instance_variable_get(:@original_values)[:additional_owners]
|
|
if original_value && original_value.length > additional_owners.length
|
|
# url params provide no mechanism for deleting an item in an array,
|
|
# just overwriting the whole array or adding new items. So let's not
|
|
# allow deleting without a full overwrite until we have a solution.
|
|
raise ArgumentError, "You cannot delete an item from an array, you must instead set a new array"
|
|
end
|
|
|
|
update_hash = {}
|
|
additional_owners.each_with_index do |v, i|
|
|
# We will almost always see a StripeObject except in the case of a Hash
|
|
# that's been appended to an array of `additional_owners`. We may be
|
|
# able to normalize that ugliness by using an array proxy object with
|
|
# StripeObjects that can detect appends and replace a hash with a
|
|
# StripeObject.
|
|
update = v.is_a?(StripeObject) ? v.serialize_params : v
|
|
|
|
if update != {} && (!original_value ||
|
|
update != legal_entity.serialize_params_value(original_value[i], nil, false, true))
|
|
update_hash[i.to_s] = update
|
|
end
|
|
end
|
|
update_hash
|
|
end
|
|
end
|
|
end
|