From f28f00e358b47a016e6198589593a707c2521bb3 Mon Sep 17 00:00:00 2001 From: alexyndr belik Date: Thu, 12 Nov 2020 14:19:32 +0200 Subject: [PATCH 1/3] ISSUE-264 | Add custom Policy macros --- lib/macro/pundit.rb | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 lib/macro/pundit.rb diff --git a/lib/macro/pundit.rb b/lib/macro/pundit.rb new file mode 100644 index 00000000..4780f434 --- /dev/null +++ b/lib/macro/pundit.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Policy + def self.Pundit(policy_class, user: nil, model: nil, action, name: :default) + Policy.step(Pundit.build(policy_class, user, model, action), name: name) + end + + module Pundit + def self.build(*args, &block) + Condition.new(*args, &block) + end + + class Condition + def initialize(policy_class, user, model, action) + @policy_class, @user, @model, @action = policy_class, user, model, action + end + + def call((options), *) + policy = build_policy + result!(policy.send(@action), policy) + end + + private + def build_policy + @policy_class.new(@user, @model) if @user && @model + @policy_class.new(options[:current_user], options[:model]) unless @user && @model + end + + def result!(success, policy) + data = { policy: policy } + data[:message] = "Breach" if !success + + Trailblazer::Operation::Result.new(success, data) + end + end + end +end From d2cc224de81552bab112da5887f8bfb688b6589d Mon Sep 17 00:00:00 2001 From: alexyndr belik Date: Thu, 12 Nov 2020 17:08:55 +0200 Subject: [PATCH 2/3] Fix rubocop --- config/credentials/development.yml.enc | 2 +- lib/macro/pundit.rb | 51 ++++++++++++++------------ 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/config/credentials/development.yml.enc b/config/credentials/development.yml.enc index 5ba4c45a..7a2eddaf 100644 --- a/config/credentials/development.yml.enc +++ b/config/credentials/development.yml.enc @@ -1 +1 @@ -qYaVjn7AHyHSmLShL6FUSc0gkDN/TnlTBcyxWC/aVqSw9Yomczems0sliw1sbV28P9OxJiYKf/lAc/tkdZXlsFPRmf3Ax1RXdVdpCX9aoegsgqaTfZM/ho/hXcgfV+tWuyg0ay/GVrYO/EeehSMCENtnBOLU/f8jLyWN8or/7hhQdDYQ6xKV+8eQRy/vTvNtfeHHoadvwpNFBBQV5yVznOZXv5PVoJBzmUtvGkHZkyjKoXXFPY0XvwHOI1BZHo37ogeQylXVhdFABdfQoCWQvJNUgB8kkPsBPx87--Fvpot/k3S0Abti7S--qv435P5TTlbWwzBcxrsnjQ== \ No newline at end of file +hk3xOYEGE+oGJgblVqmInjtqi4GfMW8AZaanzxUgBF5CIrgjEx5lff3+wxuAQTkJBarwUsdISKRJ9hxuxNVKy86F1Y5FR21GRIBmF/a6Mx3HGLDLd8qopPxiiECm/cLc2nNFBG56W0oDM1Oeoa/c/TWKvbpCZvvy0jcsT+pwqDewF36vhJAjF5+DsSIOoKhM6qJvUxVuzXMpp8Bi+fGwfPlrPw51TqtFCA8yOebymCvCt+sR+PYSAURNvoafKWHPHbOMWKJtFiR95CWX5O7LeEDrwSSHar/gUmx0V50CDw0/OMuUutX1dTHXb86P9kgQGfJNg5o=--6PcDleD9XIhgGIO2--ctaBkvJ7VlLBYwRbrENu0A== \ No newline at end of file diff --git a/lib/macro/pundit.rb b/lib/macro/pundit.rb index 4780f434..cef39922 100644 --- a/lib/macro/pundit.rb +++ b/lib/macro/pundit.rb @@ -1,36 +1,39 @@ # frozen_string_literal: true -module Policy - def self.Pundit(policy_class, user: nil, model: nil, action, name: :default) - Policy.step(Pundit.build(policy_class, user, model, action), name: name) - end - - module Pundit - def self.build(*args, &block) - Condition.new(*args, &block) +module Macro + module Policy + def self.Pundit(policy_class, action, user: nil, model: nil, name: :default) + Policy.step(Pundit.build(policy_class, action, user: user, model: model), name: name) end - class Condition - def initialize(policy_class, user, model, action) - @policy_class, @user, @model, @action = policy_class, user, model, action + module Pundit + def self.build(*args, &block) + Condition.new(*args, &block) end - def call((options), *) - policy = build_policy - result!(policy.send(@action), policy) - end + class Condition + def initialize(policy_class, action, user, model) + @policy_class, @user, @model, @action = policy_class, user, model, action + end - private - def build_policy - @policy_class.new(@user, @model) if @user && @model - @policy_class.new(options[:current_user], options[:model]) unless @user && @model - end + def call((options), *) + policy = build_policy(options) + result!(policy.send(@action), policy) + end + + private + + def build_policy(options) + @policy_class.new(@user, @model) if @user && @model + @policy_class.new(options[:current_user], options[:model]) unless @user && @model + end - def result!(success, policy) - data = { policy: policy } - data[:message] = "Breach" if !success + def result!(success, policy) + data = { policy: policy } + data[:message] = 'Breach' unless success - Trailblazer::Operation::Result.new(success, data) + Trailblazer::Operation::Result.new(success, data) + end end end end From e6f41112a07be8228141c719e4e972767ec4637b Mon Sep 17 00:00:00 2001 From: alexyndr belik Date: Fri, 20 Nov 2020 11:44:40 +0200 Subject: [PATCH 3/3] Add specs --- .reek.yml | 1 + lib/macro/pundit.rb | 6 +++--- spec/lib/macro/pundit_spec.rb | 38 +++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 spec/lib/macro/pundit_spec.rb diff --git a/.reek.yml b/.reek.yml index 8d9a345e..c9345720 100644 --- a/.reek.yml +++ b/.reek.yml @@ -48,6 +48,7 @@ detectors: - Service::JsonApi::ErrorDataStructureParser#plain_errors? - Service::JsonApi::UriQueryErrorSerializer#compose_nested_errors - Macro::Contract::BaseSchemaObject#build_schema + - Macro::Policy::Pundit::Condition#result! LongParameterList: max_params: 6 diff --git a/lib/macro/pundit.rb b/lib/macro/pundit.rb index cef39922..58e61849 100644 --- a/lib/macro/pundit.rb +++ b/lib/macro/pundit.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -module Macro +module Macro # :reek:MissingSafeMethod { exclude: [ result! ] } module Policy def self.Pundit(policy_class, action, user: nil, model: nil, name: :default) - Policy.step(Pundit.build(policy_class, action, user: user, model: model), name: name) + Trailblazer::Macro::Policy.step(Pundit.build(policy_class, action, user: user, model: model), name: name) end module Pundit @@ -12,7 +12,7 @@ def self.build(*args, &block) end class Condition - def initialize(policy_class, action, user, model) + def initialize(policy_class, action, user: nil, model: nil) @policy_class, @user, @model, @action = policy_class, user, model, action end diff --git a/spec/lib/macro/pundit_spec.rb b/spec/lib/macro/pundit_spec.rb new file mode 100644 index 00000000..4812e4f0 --- /dev/null +++ b/spec/lib/macro/pundit_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +RSpec.describe Macro do + describe '.Pundit' do + class Auth + def only_user? + @user == Module && @model.nil? + end + end + + # rubocop:disable RSpec/LeakyConstantDeclaration + OperationPolicyPundit = Class.new(Trailblazer::Operation) do + step Macro::Policy::Pundit(Auth, :only_user?) + step :process + + def process(options, **) + options[:process] = true + end + end + # rubocop:enable RSpec/LeakyConstantDeclaration + + context 'when successful' do + let(:result) { OperationPolicyPundit.call(params: {}, current_user: Module) } + + it 'process to be truthy' do + expect(result[:process]).to be true + end + end + + context 'when breach' do + let(:result) { OperationPolicyPundit.call(params: {}, current_user: nil) } + + it 'process to be falsey' do + expect(result[:process]).to be nil + end + end + end +end