active_entry 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15c793e52a2f7f0b43f1752bb61303f2fae758c763264fe3e73561ca3c272b8b
4
- data.tar.gz: 49ba592be85bb9f3f1642d748e4cbc235b4f49461dca4483773fb1de85252028
3
+ metadata.gz: 1e6ea0fd23af731840ed3e6f003c7b6beff6a14b2922bbb96444a5bfbeec58ae
4
+ data.tar.gz: b4a47cede63aa58e6f1675ab704fce6b7a7e4c4b46fc791330c4e770158bc6db
5
5
  SHA512:
6
- metadata.gz: 1e009ca5bbd3b9c2d4153f96cf4dd864dd83196c317c276a7d2a71bde273325c6a59f2340e28ca6cadc83c4430da0fefa1f07846ffdd0d9e42409c2b91eab73e
7
- data.tar.gz: 9e62985d0726b6323126b3929d7a3b9ad2d1d6d51e8488da8a6f7061b8c2d9efb94f284b260d69d344f0a8f140afa5b1428a4fb9c20d632a037542ca1d28da34
6
+ metadata.gz: c1dba6e952921afc6260b4a7e54878f2db97235f5d5c531dc769a34daf8bb65682f8d377670265000697e8715495f9a152a2be25aa05211a5916109e0db18e69
7
+ data.tar.gz: 5e813dd7d89ec9eb0514b470fcc3b1a7ffb256ea5d20f3f53e75bfc029a072dbff813a9413127cf83818e3d2d173f22240c7d91f0c3c2da335d069f0edd8b1e8
data/README.md CHANGED
@@ -53,8 +53,10 @@ end
53
53
 
54
54
  Active Entry expects boolean return values from `authenticated?` and `authorized?`. `true` signals successful authentication/authorization, everything else not.
55
55
 
56
+ ### Rescuing from errors
57
+
56
58
  If the user is signed in, he is authenticated and authorized if he is an admin, otherwise an `ActiveEntry::NotAuthenticatedError` or `ActiveEntry::NotAuthorizedError` will be raised.
57
- Now you just have to catch this error and react accordingly. Rails has the convinient `rescue_from` for that.
59
+ Now you just have to catch this error and react accordingly. Rails has the convenient `rescue_from` for that.
58
60
 
59
61
  ```ruby
60
62
  class ApplicationController < ActionController::Base
@@ -79,9 +81,38 @@ end
79
81
 
80
82
  In this example above, the user will be redirected with a flash message. But you can do whatever you want. For example logging.
81
83
 
82
- Active Entry also has a few helper methods which help you to distinguish between RESTful controller actions.
84
+ ### Scoped decision makers
85
+
86
+ Instead of putting all authentication/authorization logic into `authenticated?` and `authorized?` you can create scoped decision makers:
87
+
88
+ ```ruby
89
+ class DashboardController < ApplicationController
90
+ before_action :authenticate!, :authorize!
91
+
92
+ def index_authenticated?
93
+ # Do your authentication for the index action only
94
+ end
95
+ def index_authorized?
96
+ # Do your authorization for the index action only
97
+ end
98
+ def index
99
+ # Actual action
100
+ end
101
+ end
102
+ ```
103
+
104
+ This puts authentication/authorization logic a lot closer to the actual action that is performed and you don't get lost in endlessly long `authenticated?` or `authorized?` decision maker methods.
105
+
106
+ **Note:** The scoped authentication/authorization decision maker methods take precendence over the general ones. That means if you have an `index_authenticated?` for your index action defined, the general `authenticated?` gets ignored.
107
+
108
+ ### Controller helper methods
109
+
110
+ Active Entry also has a few helper methods which help you to distinguish between controller actions. You can check if a specific action got called, by adding `_action?` to the action name in your `authenticated?` or `authorized?`.
111
+ For an action `show` this would be `show_action?`.
112
+
113
+ **Note:** A `NoMethodError` gets raised if you try to call `_action?` if the actual action hasn't been implemented. For example `missing_implementation_action?` raises an error as long as `#missing_implementation` hasn't been implemented as action.
83
114
 
84
- The following methods are available:
115
+ The are some more helpers that check for more than one RESTful action:
85
116
 
86
117
  * `read_action?` - If the called action just read. Actions: `index`, `show`
87
118
  * `write_action?` - If the called action writes something. Actions: `new`, `create`, `edit`, `update`, `destroy`
@@ -89,15 +120,32 @@ The following methods are available:
89
120
  * `create_action?` - If something will be created. Actions: `new`, `create`
90
121
  * `update_action?` - If something will be updated. Actions: `edit`, `update`
91
122
  * `destroy_action?` - If something will be destroyed. Action: `destroy`
123
+ * `delete_action?` - Alias for `destroy_action?`. Action: `destroy`
92
124
 
93
125
  So you can for example do:
94
126
 
95
127
  ```ruby
96
- def authorized?
97
- return true if read_action? # Everybody is authorized to call read actions
128
+ class ApplicationController < ActionController::Base
129
+ # ...
130
+
131
+ def show
132
+ end
133
+
134
+ def custom
135
+ end
136
+
137
+ private
98
138
 
99
- if write_action?
100
- return true if admin_signed_in? # Just admins are allowed to call write actions
139
+ def authorized?
140
+ return true if read_action? # Everybody is authorized to call read actions
141
+
142
+ if write_action?
143
+ return true if admin_signed_in? # Just admins are allowed to call write actions
144
+ end
145
+
146
+ if custom_action? # For custom/non-RESTful actions
147
+ return true
148
+ end
101
149
  end
102
150
  end
103
151
  ```
data/lib/active_entry.rb CHANGED
@@ -6,18 +6,29 @@ require "active_entry/railtie" if defined? Rails::Railtie
6
6
  module ActiveEntry
7
7
  # Authenticates the user
8
8
  def authenticate!
9
+ general_decision_maker_method_name = :authenticated?
10
+ scoped_decision_maker_method_name = [action_name, :authenticated?].join("_").to_sym
11
+
12
+ general_decision_maker_defined = respond_to? general_decision_maker_method_name, true
13
+ scoped_decision_maker_defined = respond_to? scoped_decision_maker_method_name, true
14
+
15
+ # Check if a scoped decision maker method is defined and use it over
16
+ # general decision maker method.
17
+ decision_maker_to_use = scoped_decision_maker_defined ? scoped_decision_maker_method_name : general_decision_maker_method_name
18
+
9
19
  # Raise an error if the #authenticate? action isn't defined.
10
20
  #
11
21
  # This ensures that you actually do authentication in your controller.
12
- raise ActiveEntry::AuthenticationNotPerformedError unless defined?(authenticated?)
22
+ if !scoped_decision_maker_defined && !general_decision_maker_defined
23
+ raise ActiveEntry::AuthenticationNotPerformedError
24
+ end
13
25
 
14
26
  error = {}
15
- is_authenticated = nil
16
27
 
17
- if method(:authenticated?).arity > 0
18
- is_authenticated = authenticated?(error)
28
+ if method(decision_maker_to_use).arity > 0
29
+ is_authenticated = send decision_maker_to_use, error
19
30
  else
20
- is_authenticated = authenticated?
31
+ is_authenticated = send decision_maker_to_use
21
32
  end
22
33
 
23
34
  # If the authenticated? method returns not true
@@ -30,18 +41,29 @@ module ActiveEntry
30
41
 
31
42
  # Authorizes the user.
32
43
  def authorize!
44
+ general_decision_maker_method_name = :authorized?
45
+ scoped_decision_maker_method_name = [action_name, :authorized?].join("_").to_sym
46
+
47
+ general_decision_maker_defined = respond_to? general_decision_maker_method_name, true
48
+ scoped_decision_maker_defined = respond_to? scoped_decision_maker_method_name, true
49
+
50
+ # Check if a scoped decision maker method is defined and use it over
51
+ # general decision maker method.
52
+ decision_maker_to_use = scoped_decision_maker_defined ? scoped_decision_maker_method_name : general_decision_maker_method_name
53
+
33
54
  # Raise an error if the #authorize? action isn't defined.
34
55
  #
35
56
  # This ensures that you actually do authorization in your controller.
36
- raise ActiveEntry::AuthorizationNotPerformedError unless defined?(authorized?)
57
+ if !scoped_decision_maker_defined && !general_decision_maker_defined
58
+ raise ActiveEntry::AuthorizationNotPerformedError
59
+ end
37
60
 
38
61
  error = {}
39
- is_authorized = nil
40
62
 
41
- if method(:authorized?).arity > 0
42
- is_authorized = authorized?(error)
63
+ if method(decision_maker_to_use).arity > 0
64
+ is_authorized = send(decision_maker_to_use, error)
43
65
  else
44
- is_authorized = authorized?
66
+ is_authorized = send(decision_maker_to_use)
45
67
  end
46
68
 
47
69
  # If the authorized? method does not return true
@@ -3,6 +3,20 @@
3
3
  # Helper methods for your controller
4
4
  # to identify RESTful actions.
5
5
  module ActiveEntry
6
+ def method_missing method_name, *args
7
+ method_name_str = method_name.to_s
8
+
9
+ if methods.include?(:action_name) && method_name_str.include?("_action?")
10
+ method_name_str.slice! "_action?"
11
+
12
+ if methods.include? method_name_str.to_sym
13
+ return method_name_str == action_name
14
+ end
15
+ end
16
+
17
+ super
18
+ end
19
+
6
20
  # @return [Boolean]
7
21
  # True if the called action
8
22
  # is a only-read action.
@@ -31,20 +45,6 @@ module ActiveEntry
31
45
  action_name == 'destroy'
32
46
  end
33
47
 
34
- # @return [Boolean]
35
- # True if the called action
36
- # is the index action.
37
- def index_action?
38
- action_name == 'index'
39
- end
40
-
41
- # @return [Boolean]
42
- # True if the called action
43
- # is the show action.
44
- def show_action?
45
- action_name == 'show'
46
- end
47
-
48
48
  # @note
49
49
  # Also true for the pseudo
50
50
  # update action `new`.
@@ -78,6 +78,5 @@ module ActiveEntry
78
78
  def destroy_action?
79
79
  action_name == 'destroy'
80
80
  end
81
-
82
81
  alias delete_action? destroy_action?
83
82
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveEntry
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_entry
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TFM Agency GmbH
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-03-02 00:00:00.000000000 Z
12
+ date: 2021-03-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -67,6 +67,20 @@ dependencies:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: ffaker
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
70
84
  description: An easy and flexible access control system. No need for policies, abilities,
71
85
  etc. Do authentication and authorization directly in your controller.
72
86
  email: