diff --git a/enterprise/app/models/concerns/enterprise/account/limit_validation.rb b/enterprise/app/models/concerns/enterprise/account/limit_validation.rb new file mode 100644 index 000000000..08777cd23 --- /dev/null +++ b/enterprise/app/models/concerns/enterprise/account/limit_validation.rb @@ -0,0 +1,22 @@ +module Enterprise::Account::LimitValidation + extend ActiveSupport::Concern + + LIMIT_SCHEMA = { + 'type' => 'object', + 'properties' => { + 'inboxes' => { 'type': 'number' }, + 'agents' => { 'type': 'number' }, + 'captain_responses' => { 'type': 'number' }, + 'captain_documents' => { 'type': 'number' } + }, + 'required' => [], + 'additionalProperties' => false + }.freeze + + def validate_limit_keys + errors.add(:limits, ': Invalid data') unless self[:limits].is_a? Hash + self[:limits] = {} if self[:limits].blank? + + errors.add(:limits, ': Invalid data') unless JSONSchemer.schema(LIMIT_SCHEMA).valid?(self[:limits]) + end +end diff --git a/enterprise/app/models/enterprise/account/plan_usage_and_limits.rb b/enterprise/app/models/enterprise/account/plan_usage_and_limits.rb index 53dddd67c..efab03d08 100644 --- a/enterprise/app/models/enterprise/account/plan_usage_and_limits.rb +++ b/enterprise/app/models/enterprise/account/plan_usage_and_limits.rb @@ -1,4 +1,6 @@ module Enterprise::Account::PlanUsageAndLimits + include Enterprise::Account::LimitValidation + CAPTAIN_RESPONSES = 'captain_responses'.freeze CAPTAIN_DOCUMENTS = 'captain_documents'.freeze CAPTAIN_RESPONSES_USAGE = 'captain_responses_usage'.freeze @@ -17,7 +19,6 @@ module Enterprise::Account::PlanUsageAndLimits def increment_response_usage increment_sql = <<~SQL.squish - custom_attributes = jsonb_set( custom_attributes, '{#{CAPTAIN_RESPONSES_USAGE}}', @@ -25,8 +26,8 @@ module Enterprise::Account::PlanUsageAndLimits true ) SQL - - updated = self.class.where(id: id).update_all(increment_sql) + # Skipping validations is safe: no validations on custom_attributes, + updated = self.class.where(id: id).update_all(increment_sql) # rubocop:disable Rails/SkipsModelValidations reload if updated.positive? end @@ -117,23 +118,4 @@ module Enterprise::Account::PlanUsageAndLimits ChatwootApp.max_limit end - - def validate_limit_keys - errors.add(:limits, ': Invalid data') unless self[:limits].is_a? Hash - self[:limits] = {} if self[:limits].blank? - - limit_schema = { - 'type' => 'object', - 'properties' => { - 'inboxes' => { 'type': 'number' }, - 'agents' => { 'type': 'number' }, - 'captain_responses' => { 'type': 'number' }, - 'captain_documents' => { 'type': 'number' } - }, - 'required' => [], - 'additionalProperties' => false - } - - errors.add(:limits, ': Invalid data') unless JSONSchemer.schema(limit_schema).valid?(self[:limits]) - end end