diff --git a/extensions/guardian.rb b/extensions/guardian.rb new file mode 100644 index 00000000..2474b49b --- /dev/null +++ b/extensions/guardian.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true +module CustomWizardGuardian + def can_see_topic?(topic, hide_deleted = true) + wizard_user_can_create_topic_on_category?(topic) || super + end + + def can_edit_topic?(topic) + wizard_user_can_create_topic_on_category?(topic) || super + end + + def can_create_post?(parent) + result = parent.present? ? wizard_user_can_create_topic_on_category?(parent) : false + result || super + end + + private + + def wizard_user_can_create_topic_on_category?(topic) + wizard = creating_wizard(topic) + (wizard.present? && wizard.permitted? && wizard_can_create_topic_on_category?(wizard, topic)) + end + + def creating_wizard(topic) + wizard_id = topic.wizard_created.presence + wizard = CustomWizard::Builder.new(wizard_id, @user).build if wizard_id + return wizard.presence + end + + def wizard_can_create_topic_on_category?(wizard, topic) + return false unless topic.category.present? + + wizard_actions = wizard.actions + return false if wizard_actions.empty? + + create_topic_actions = wizard_actions.select do |action| + action['type'] === 'create_topic' + end + + submission_data = begin + submissions = CustomWizard::Submission.list(wizard) + submissions.find { |sub| sub.id == topic.wizard_submission }&.fields_and_meta + end + + categories = wizard_actions.map do |action| + category = CustomWizard::Mapper.new( + inputs: action['category'], + data: submission_data, + user: @user + ).perform + + category + end + + categories.flatten! + + return true if categories.include?(topic.category.id) + false + end +end diff --git a/lib/custom_wizard/action.rb b/lib/custom_wizard/action.rb index 9245a591..b2ce05bc7 100644 --- a/lib/custom_wizard/action.rb +++ b/lib/custom_wizard/action.rb @@ -514,7 +514,13 @@ class CustomWizard::Action def basic_topic_params params = { - skip_validations: true + skip_validations: true, + topic_opts: { + custom_fields: { + wizard_created: @wizard.id, + wizard_submission: @wizard.current_submission.id + } + } } params[:title] = CustomWizard::Mapper.new( diff --git a/lib/custom_wizard/guardian.rb b/lib/custom_wizard/guardian.rb deleted file mode 100644 index c453f509..00000000 --- a/lib/custom_wizard/guardian.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true -class CustomWizard::Guardian - def initialize(user) - @user = user - end - - def can_edit_topic?(topic) - creating_wizard = topic.wizard_created.presence - return false unless creating_wizard - - wizard_builder = CustomWizard::Builder.new(creating_wizard, @user) - wizard = wizard_builder.build - wizard_actions = wizard.actions - return false if wizard_actions.empty? - - create_topic_action = wizard_actions.find do |action| - action['type'] === 'create_topic' - end - - return wizard_can_create_topic_on_category?(action, topic) - end - - private - - def wizard_can_create_topic_on_category?(action, topic) - return false unless topic.category.present? - - category = CustomWizard::Mapper.new( - inputs: action['category'], - data: - ) - end -end diff --git a/plugin.rb b/plugin.rb index d412c76b..1592ac30 100644 --- a/plugin.rb +++ b/plugin.rb @@ -86,7 +86,6 @@ after_initialize do ../lib/custom_wizard/submission.rb ../lib/custom_wizard/template.rb ../lib/custom_wizard/wizard.rb - ../lib/custom_wizard/guardian.rb ../lib/custom_wizard/api/api.rb ../lib/custom_wizard/api/authorization.rb ../lib/custom_wizard/api/endpoint.rb @@ -109,6 +108,7 @@ after_initialize do ../serializers/custom_wizard/realtime_validation/similar_topics_serializer.rb ../extensions/extra_locales_controller.rb ../extensions/invites_controller.rb + ../extensions/guardian.rb ../extensions/users_controller.rb ../extensions/custom_field/preloader.rb ../extensions/custom_field/serializer.rb @@ -119,6 +119,14 @@ after_initialize do Liquid::Template.register_filter(::CustomWizard::LiquidFilter::FirstNonEmpty) + add_to_class(:topic, :wizard_created) do + custom_fields['wizard_created'] + end + + add_to_class(:topic, :wizard_submission) do + custom_fields['wizard_submission'] + end + add_class_method(:wizard, :user_requires_completion?) do |user| wizard_result = self.new(user).requires_completion? return wizard_result if wizard_result @@ -192,6 +200,7 @@ after_initialize do ::ExtraLocalesController.prepend ExtraLocalesControllerCustomWizard ::InvitesController.prepend InvitesControllerCustomWizard ::UsersController.prepend CustomWizardUsersController + ::Guardian.prepend CustomWizardGuardian full_path = "#{Rails.root}/plugins/discourse-custom-wizard/assets/stylesheets/wizard/wizard_custom.scss" if Stylesheet::Importer.respond_to?(:plugin_assets) diff --git a/spec/components/custom_wizard/guardian_spec.rb b/spec/components/custom_wizard/guardian_spec.rb deleted file mode 100644 index bb7578d2..00000000 --- a/spec/components/custom_wizard/guardian_spec.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -require_relative '../../plugin_helper' - -describe CustomWizard::Guardian do - -end diff --git a/spec/extensions/guardian_extension_spec.rb b/spec/extensions/guardian_extension_spec.rb new file mode 100644 index 00000000..09edd1d6 --- /dev/null +++ b/spec/extensions/guardian_extension_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true +require_relative '../plugin_helper' + +describe ::Guardian do + fab!(:user) { + Fabricate(:user, name: "Angus", username: 'angus', email: "angus@email.com") + } + fab!(:category) { Fabricate(:category, name: 'cat1', slug: 'cat-slug') } + let(:wizard_template) { + JSON.parse( + File.open( + "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/wizard.json" + ).read + ) + } + + before do + CustomWizard::Template.save(wizard_template, skip_jobs: true) + @template = CustomWizard::Template.find('super_mega_fun_wizard') + end + + context "the user has access to creating wizard" do + it "allows editing the topic first post" do + wizard = CustomWizard::Builder.new(@template[:id], user).build + + wizard.create_updater( + wizard.steps.first.id, + step_1_field_1: "Topic Title", + step_1_field_2: "topic body" + ).update + wizard.create_updater(wizard.steps.second.id, {}).update + wizard.create_updater(wizard.steps.last.id, + step_3_field_3: category.id + ).update + + topic = Topic.where( + title: "Topic Title", + category_id: category.id + ).first + + expect(user.guardian.send(:wizard_user_can_create_topic_on_category?, topic)).to be_truthy + end + end + + context "the user doesn't have access to creating wizard" do + it "restricts editing the topic first post" do + wizard = CustomWizard::Builder.new(@template[:id], user).build + CustomWizard::Wizard.any_instance.stubs(:permitted?).returns(false) + + wizard.create_updater( + wizard.steps.first.id, + step_1_field_1: "Topic Title", + step_1_field_2: "topic body" + ).update + wizard.create_updater(wizard.steps.second.id, {}).update + wizard.create_updater(wizard.steps.last.id, + step_3_field_3: category.id + ).update + + topic = Topic.where( + title: "Topic Title", + category_id: category.id + ).first + + expect(user.guardian.send(:wizard_user_can_create_topic_on_category?, topic)).to be_falsey + end + end +end