pragma-operation 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0e4b70a6dbf00fc017919c4a20a4fcab1314caf
4
- data.tar.gz: 10bd799eabb43d6f76a9d29f80a737df2c2902e0
3
+ metadata.gz: d1a35deac8b18a13c8f5e7cd9b4ee1372afb6321
4
+ data.tar.gz: 6f2abba3db47e143d06c407fe33a1416f44cffac
5
5
  SHA512:
6
- metadata.gz: ff8e629a189aa67af574569fbf2fa2db77e65e753d553f4d6ae2fc3d8b892693060a223a0f69a6112f8e9ba6ba0479fc44b77550616a9a97e7567f0565ca36a1
7
- data.tar.gz: 5db34e59a55d5251eb05d0f33283bb83f26027afe491c8150094076eee53af092f0d20fd0f345381f1dfa7c879643f2e9868611b4f6b0b6cbe0f827a94bd1418
6
+ metadata.gz: 1af71177cbec88e40273ebc84fd5118d2bf2d894df7823791850e50d12dcd5ca0e2ba649b6c4509ff71708bfdafb3bd13ba78064cdc78709f9a3e59267c1626d
7
+ data.tar.gz: fd674718c93267c02e48e6ce035ff0595a1cb6db79ed047938a762ae4e555ed35e9be6348ec02d5b0aed038fe428f64c738fc10edd7c62498b9c24bec37976bb
data/doc/03-policies.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Policies
2
2
 
3
3
  Operations integrate with [Pragma::Policy](https://github.com/pragmarb/pragma-policy). All you have
4
- to do is specify the policy class with `#policy`. This will give you access to `#authorize` and
5
- `#authorize!`:
4
+ to do is specify the policy class with `#policy`:
6
5
 
7
6
  ```ruby
8
7
  module API
@@ -92,3 +91,28 @@ module API
92
91
  end
93
92
  end
94
93
  ```
94
+
95
+ ## Authorizing collections
96
+
97
+ To authorize a collection, use `#authorize_collection`. This will call `.accessible_by` on the
98
+ policy class with the current user and the provided collection and return an authorized collection
99
+ containing only records accessible by the user.
100
+
101
+ ```ruby
102
+ module API
103
+ module V1
104
+ module Post
105
+ module Operation
106
+ class Index < Pragma::Operation::Base
107
+ policy API::V1::Post::Policy
108
+
109
+ def call
110
+ posts = authorize_collection Post.all
111
+ respond_with status: :ok, resource: posts
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ ```
@@ -0,0 +1,26 @@
1
+ # Decorators
2
+
3
+ Operations integrate with [Pragma::Decorator](https://github.com/pragmarb/pragma-decorator). All you
4
+ have to do is specify the policy class with `#decorator`. This will give you access to `#decorate`:
5
+
6
+ ```ruby
7
+ module API
8
+ module V1
9
+ module Post
10
+ module Operation
11
+ class Show < Pragma::Operation::Base
12
+ policy API::V1::Post::Policy
13
+
14
+ def call
15
+ post = Post.find(params[:id])
16
+ respond_with status: :ok, resource: decorate(post)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ ```
24
+
25
+ Note that `#decorate` works with both singular resources and collections, as it uses the decorator's
26
+ [`.represent`](http://trailblazer.to/gems/representable/3.0/api.html) method.
@@ -18,6 +18,13 @@ module Pragma
18
18
  @policy = klass
19
19
  end
20
20
 
21
+ # Returns the policy class.
22
+ #
23
+ # @return [Class]
24
+ def policy_klass
25
+ @policy
26
+ end
27
+
21
28
  # Builds the policy for the given user and resource, using the previous defined policy
22
29
  # class.
23
30
  #
@@ -28,7 +35,7 @@ module Pragma
28
35
  #
29
36
  # @see #policy
30
37
  def build_policy(user:, resource:)
31
- @policy.new(user: user, resource: resource)
38
+ policy_klass.new(user: user, resource: resource)
32
39
  end
33
40
  end
34
41
 
@@ -48,11 +55,15 @@ module Pragma
48
55
 
49
56
  # Authorizes this operation on the provided resource or policy.
50
57
  #
58
+ # If no policy was defined, simply returns true.
59
+ #
51
60
  # @param authorizable [Pragma::Policy::Base|Object] resource or policy
52
61
  #
53
62
  # @return [Boolean] whether the operation is authorized
54
63
  def authorize(authorizable)
55
- policy = if defined?(Pragma::Policy::Base) && authorizable.is_a?(Pragma::Policy::Base)
64
+ return true unless self.class.policy_klass
65
+
66
+ policy = if authorizable.is_a?(self.class.policy_klass)
56
67
  authorizable
57
68
  else
58
69
  build_policy(authorizable)
@@ -77,6 +88,22 @@ module Pragma
77
88
  }
78
89
  )
79
90
  end
91
+
92
+ # Scopes the provided collection.
93
+ #
94
+ # If no policy class is defined, simply returns the collection.
95
+ #
96
+ # @param collection [Enumerable]
97
+ #
98
+ # @return [Pragma::Decorator::Base|Enumerable]
99
+ def authorize_collection(collection)
100
+ return collection unless self.class.policy_klass
101
+
102
+ self.class.policy_klass.accessible_by(
103
+ user: current_user,
104
+ scope: collection
105
+ )
106
+ end
80
107
  end
81
108
  end
82
109
  end
@@ -9,6 +9,10 @@ module Pragma
9
9
  class Base
10
10
  include Interactor
11
11
 
12
+ include Authorization
13
+ include Validation
14
+ include Decoration
15
+
12
16
  STATUSES = {
13
17
  200 => :ok,
14
18
  201 => :created,
@@ -70,9 +74,6 @@ module Pragma
70
74
  class << self
71
75
  def inherited(child)
72
76
  child.class_eval do
73
- include Authorization
74
- include Validation
75
-
76
77
  before :setup_context
77
78
  around :handle_halt
78
79
  after :mark_result, :consolidate_status, :validate_status, :set_default_status
@@ -0,0 +1,70 @@
1
+ module Pragma
2
+ module Operation
3
+ # Provides integration with {https://github.com/pragmarb/pragma-decorator Pragma::Decorator}.
4
+ #
5
+ # @author Alessandro Desantis
6
+ module Decoration
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ base.include InstanceMethods
10
+ end
11
+
12
+ module ClassMethods # :nodoc:
13
+ # Sets the decorator to use for validating this operation.
14
+ #
15
+ # @param klass [Class] a subclass of +Pragma::Decorator::Base+
16
+ def decorator(klass)
17
+ @decorator = klass
18
+ end
19
+
20
+ # Returns the decorator class.
21
+ #
22
+ # @return [Class]
23
+ def decorator_klass
24
+ @decorator
25
+ end
26
+
27
+ # Builds the decorator for the given resource, using the previously defined decorator class.
28
+ #
29
+ # Works with both singular resources and collections.
30
+ #
31
+ # @param resource [Object]
32
+ #
33
+ # @return [Pragma::Decorator::Base]
34
+ #
35
+ # @see #decorator
36
+ def build_decorator(resource)
37
+ decorator_klass.represent(resource)
38
+ end
39
+ end
40
+
41
+ module InstanceMethods # :nodoc:
42
+ # Builds the decorator for the given resource, using the previously defined decorator class.
43
+ #
44
+ # This is just an instance-level alias of {.build_decorator}. You should use this from
45
+ # inside the operation.
46
+ #
47
+ # @param resource [Object]
48
+ #
49
+ # @return [Pragma::Decorator::Base]
50
+ #
51
+ # @see #decorate
52
+ def build_decorator(resource)
53
+ self.class.build_decorator(resource)
54
+ end
55
+
56
+ # If a decorator is defined, acts as an alias for {#build_decorator}. If not, simply returns
57
+ # the provided resource.
58
+ # @param decoratable [Object]
59
+ #
60
+ # @return [Pragma::Decorator::Base|Object]
61
+ #
62
+ # @see #build_decorator
63
+ def decorate(decoratable)
64
+ return decoratable unless self.class.decorator_klass
65
+ build_decorator(decoratable)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -18,6 +18,13 @@ module Pragma
18
18
  @contract = klass
19
19
  end
20
20
 
21
+ # Returns the contract class.
22
+ #
23
+ # @return [Class]
24
+ def contract_klass
25
+ @contract
26
+ end
27
+
21
28
  # Builds the contract for the given resource, using the previous defined contract class.
22
29
  #
23
30
  # @param resource [Object]
@@ -26,7 +33,7 @@ module Pragma
26
33
  #
27
34
  # @see #contract
28
35
  def build_contract(resource)
29
- @contract.new(resource)
36
+ contract_klass.new(resource)
30
37
  end
31
38
  end
32
39
 
@@ -53,7 +60,7 @@ module Pragma
53
60
  # @return [Boolean] whether the operation is valid
54
61
  def validate(validatable)
55
62
  # rubocop:disable Metrics/LineLength
56
- contract = if defined?(Pragma::Contract::Base) && validatable.is_a?(Pragma::Contract::Base)
63
+ contract = if validatable.is_a?(self.class.contract_klass)
57
64
  validatable
58
65
  else
59
66
  build_contract(validatable)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Pragma
3
3
  module Operation
4
- VERSION = '0.1.2'
4
+ VERSION = '1.0.0'
5
5
  end
6
6
  end
@@ -2,9 +2,10 @@
2
2
  require 'interactor'
3
3
 
4
4
  require 'pragma/operation/version'
5
- require 'pragma/operation/base'
6
5
  require 'pragma/operation/authorization'
7
6
  require 'pragma/operation/validation'
7
+ require 'pragma/operation/decoration'
8
+ require 'pragma/operation/base'
8
9
 
9
10
  module Pragma
10
11
  # Operations provide business logic encapsulation for your JSON API.
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency 'pragma-policy', '~> 0.1.0'
26
26
  spec.add_development_dependency 'pragma-contract', '~> 0.1.0'
27
+ spec.add_development_dependency 'pragma-decorator', '~> 0.1.0'
27
28
 
28
29
  spec.add_development_dependency "bundler"
29
30
  spec.add_development_dependency "rake"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pragma-operation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alessandro Desantis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-26 00:00:00.000000000 Z
11
+ date: 2016-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: interactor
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: pragma-decorator
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.1.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.1.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -156,9 +170,11 @@ files:
156
170
  - doc/01-basic-usage.md
157
171
  - doc/02-contracts.md
158
172
  - doc/03-policies.md
173
+ - doc/04-decorators.md
159
174
  - lib/pragma/operation.rb
160
175
  - lib/pragma/operation/authorization.rb
161
176
  - lib/pragma/operation/base.rb
177
+ - lib/pragma/operation/decoration.rb
162
178
  - lib/pragma/operation/validation.rb
163
179
  - lib/pragma/operation/version.rb
164
180
  - pragma-operation.gemspec