From eadc40bdae1f580c3b718e2e23685c47e769aef6 Mon Sep 17 00:00:00 2001 From: angusmcleod Date: Wed, 18 Aug 2021 14:11:00 +0800 Subject: [PATCH] Add CustomWizard class protections and pro feature restrictions --- config/locales/server.en.yml | 1 + jobs/scheduled/update_pro_status.rb | 10 ++++------ lib/custom_wizard/action.rb | 10 ++++++++++ lib/custom_wizard/builder.rb | 21 +++++++++++++-------- lib/custom_wizard/pro/subscription.rb | 5 +++-- plugin.rb | 12 ++++++++++++ 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index c425baa5..86968fda 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -17,6 +17,7 @@ en: name_too_short: "'%{name}' is too short for a custom field name (min length is #{min_length})" name_already_taken: "'%{name}' is already taken as a custom field name" save_default: "Failed to save custom field '%{name}'" + pro_required: "PRO Actions require a PRO Subscription" field: too_short: "%{label} must be at least %{min} characters" diff --git a/jobs/scheduled/update_pro_status.rb b/jobs/scheduled/update_pro_status.rb index 962f3ba9..5f76f52b 100644 --- a/jobs/scheduled/update_pro_status.rb +++ b/jobs/scheduled/update_pro_status.rb @@ -1,11 +1,9 @@ # frozen_string_literal: true -module Jobs - class UpdateProSubscription < ::Jobs::Scheduled - every 1.days +class CustomWizard::UpdateProSubscription < ::Jobs::Scheduled + every 10.minutes - def execute(args) - CustomWizard::ProSubscription.update - end + def execute(args) + CustomWizard::ProSubscription.update end end \ No newline at end of file diff --git a/lib/custom_wizard/action.rb b/lib/custom_wizard/action.rb index 6a36af41..1cadbb5b 100644 --- a/lib/custom_wizard/action.rb +++ b/lib/custom_wizard/action.rb @@ -14,9 +14,15 @@ class CustomWizard::Action @submission = opts[:submission] @log = [] @result = CustomWizard::ActionResult.new + @pro = CustomWizard::Pro.new end def perform + if pro_actions.include?(action['type']) && !@pro.subscribed? + log_error(I18n.t("wizard.custom_field.error.pro_required")) + return + end + ActiveRecord::Base.transaction do self.send(action['type'].to_sym) end @@ -752,4 +758,8 @@ class CustomWizard::Action CustomWizard::Log.create(log) end + + def pro_actions + %w[send_message watch_categories send_to_api create_group create_category] + end end diff --git a/lib/custom_wizard/builder.rb b/lib/custom_wizard/builder.rb index 656a3820..78a960b9 100644 --- a/lib/custom_wizard/builder.rb +++ b/lib/custom_wizard/builder.rb @@ -22,13 +22,6 @@ class CustomWizard::Builder @sorted_handlers.sort_by! { |h| -h[:priority] } end - def mapper - CustomWizard::Mapper.new( - user: @wizard.user, - data: @wizard.current_submission&.fields_and_meta - ) - end - def build(build_opts = {}, params = {}) return nil if !SiteSetting.custom_wizard_enabled || !@wizard return @wizard if !@wizard.can_access? && !build_opts[:force] @@ -80,6 +73,15 @@ class CustomWizard::Builder @wizard end + private + + def mapper + CustomWizard::Mapper.new( + user: @wizard.user, + data: @wizard.current_submission&.fields_and_meta + ) + end + def append_field(step, step_template, field_template, build_opts) params = { id: field_template['id'], @@ -224,7 +226,10 @@ class CustomWizard::Builder end def check_condition(template) - return false unless @pro.subscribed? + unless @pro.subscribed? + CustomWizard::Log.create(I18n.t("wizard.custom_field.error.pro_required")) + return false + end if template['condition'].present? result = CustomWizard::Mapper.new( diff --git a/lib/custom_wizard/pro/subscription.rb b/lib/custom_wizard/pro/subscription.rb index 2e0c8542..ef0ac2b9 100644 --- a/lib/custom_wizard/pro/subscription.rb +++ b/lib/custom_wizard/pro/subscription.rb @@ -38,14 +38,15 @@ class CustomWizard::ProSubscription end def self.update - @subscribed = nil auth = CustomWizard::ProAuthentication.new subscription = self.new if auth.active? response = Excon.get( "https://#{SUBSCRIPTION_SERVER}/subscription-server/user-subscriptions/#{SUBSCRIPTION_TYPE}/#{CLIENT_NAME}", - headers: { "User-Api-Key" => auth.api_key } + headers: { + "User-Api-Key" => auth.api_key + } ) if response.status == 200 diff --git a/plugin.rb b/plugin.rb index c0379374..7c056b5d 100644 --- a/plugin.rb +++ b/plugin.rb @@ -126,6 +126,18 @@ after_initialize do Liquid::Template.register_filter(::CustomWizard::LiquidFilter::FirstNonEmpty) + class CustomWizard::UnpermittedOverride < StandardError; end + + CustomWizard.constants.each do |class_name| + klass = CustomWizard.const_get(class_name) + next if !klass.is_a?(Class) || klass.superclass.name.to_s.split("::").first == 'CustomWizard' + + klass.define_singleton_method(:prepend) { |klass| raise CustomWizard::UnpermittedOverride.new } + klass.define_singleton_method(:include) { |klass| raise CustomWizard::UnpermittedOverride.new } + klass.define_singleton_method(:define_method) { |name, &block| raise CustomWizard::UnpermittedOverride.new } + klass.define_singleton_method(:define_singleton_method) { |name, &block| raise CustomWizard::UnpermittedOverride.new } + end + add_class_method(:wizard, :user_requires_completion?) do |user| wizard_result = self.new(user).requires_completion? return wizard_result if wizard_result