Class: Funcify::Afn
- Inherits:
-
Object
- Object
- Funcify::Afn
- Extended by:
- Dry::Monads::Result::Mixin
- Defined in:
- lib/funcify/afn.rb
Constant Summary collapse
- PRIVILEGE =
:privilege- RESOURCE =
:resource
Class Method Summary collapse
- .action_test ⇒ Object
- .activity_match ⇒ Object
-
.activity_policy ⇒ Object
The Activity-based access control policy —————————————- Policy runs 4 tests: + the ctx includes a :resource key + the ctx includes an :action key + the ctx includes an :activities + and finally, the significant test, the service/resource/action match an activity.
- .activity_tests ⇒ Object
- .activity_token_matcher ⇒ Object
-
.all_authorisor ⇒ Object
alias of #authorise, which works with fmapping; hence all policy checks MUST be Success.
-
.any_finally_fn ⇒ Object
any results Success(), then Success, otherwise call enforcer.
-
.authorise ⇒ Object
Authorise Fns.
- .error_raiser ⇒ Object
- .finally_fn ⇒ Object
-
.for_system ⇒ Object
Helper Fns.
-
.has_activity ⇒ Object
s: system r: r a: action activitys: user’s activity enum.
- .has_priviled ⇒ Object
- .has_privileged_access ⇒ Object
- .has_resource ⇒ Object
- .key_present_test ⇒ Object
-
.nil_enforcer ⇒ Object
Enforcement Fns.
-
.or_authorisor ⇒ Object
Similar to all_authorisor, except at least one of the policies MUST be success.
- .policy_match ⇒ Object
- .privilege_activity_policy_tests ⇒ Object
-
.privilege_policy ⇒ Object
The Privelged access control policy —————————————- Policy runs 4 tests: + the ctx includes a :privilege key + the ctx includes an :action key + the ctx includes an :activities + and finally, the significant test, the service/resource/action match an activity.
- .privilege_tests ⇒ Object
- .resource_activity_policy_tests ⇒ Object
- .resource_test ⇒ Object
-
.slack_token_policy ⇒ Object
Slack Policy ———— Slack Policy looks for :token in the ctx, and ensures that token is configured in Account.
- .slack_token_tests(token) ⇒ Object
- .system_test ⇒ Object
- .token_match ⇒ Object
- .valid_slack_token ⇒ Object
-
.validity_policy ⇒ Object
Valid JWT test ————–.
Class Method Details
.action_test ⇒ Object
259 260 261 |
# File 'lib/funcify/afn.rb', line 259 def action_test -> req, token { token_match.(req).(Fn.at.(4).(token)) }.curry end |
.activity_match ⇒ Object
202 203 204 205 206 |
# File 'lib/funcify/afn.rb', line 202 def activity_match -> tests, r, a, activities { Fn.find.(policy_match.(tests, r, a)).(activities) }.curry end |
.activity_policy ⇒ Object
The Activity-based access control policy
Policy runs 4 tests: + the ctx includes a :resource key + the ctx includes an :action key + the ctx includes an :activities + and finally, the significant test, the service/resource/action match an activity
123 124 125 126 127 |
# File 'lib/funcify/afn.rb', line 123 def activity_policy -> activities, filter_fn, ctx { Fn.either.( Fn.tests.(Fn.all?, activity_tests), Fn.success, Fn.failure ).(ctx.merge(activities: filter_fn.(activities))) }.curry end |
.activity_tests ⇒ Object
129 130 131 132 133 134 135 136 |
# File 'lib/funcify/afn.rb', line 129 def activity_tests [ key_present_test.(:resource), key_present_test.(:action), key_present_test.(:activities), has_activity.(resource_activity_policy_tests) ] end |
.activity_token_matcher ⇒ Object
217 218 219 220 221 |
# File 'lib/funcify/afn.rb', line 217 def activity_token_matcher -> tests, r, a, tokens { Fn.tests.(Fn.all?, tests.(r, a)).(tokens) }.curry end |
.all_authorisor ⇒ Object
alias of #authorise, which works with fmapping; hence all policy checks MUST be Success
37 38 39 40 41 42 43 |
# File 'lib/funcify/afn.rb', line 37 def -> enforcer, policies, ctx { Fn.compose.( finally_fn.(enforcer), Fn.fmap_compose.(policies) ).(Success(ctx)) }.curry end |
.any_finally_fn ⇒ Object
any results Success(), then Success, otherwise call enforcer
59 60 61 62 63 |
# File 'lib/funcify/afn.rb', line 59 def any_finally_fn -> enforcer, results { Fn.either.(Fn.any?.(Fn.maybe_value_ok?), Fn.success).(-> x { enforcer.(x) }).(results) }.curry end |
.authorise ⇒ Object
Authorise Fns
Example > Afn.authorise.(Afn.auth_error_raise_enforcer.(PolicyEnforcement::AuthorisationFailed))
.([Afn.activity_policy.(system_policy)])
.(activity_ctx(:create))
> Success(nil) | raises a PolicyEnforcement::AuthorisationFailed
Use partial evaluation by establishing the enforcer and policies (which returns a partially applied authorise fn) passing this to the services to be protected, which that evaluate the fn by providing the ctx.
28 29 30 31 32 33 34 |
# File 'lib/funcify/afn.rb', line 28 def -> enforcer, policies, ctx { Fn.compose.( finally_fn.(enforcer), Fn.fmap_compose.(policies) ).(Success(ctx)) }.curry end |
.error_raiser ⇒ Object
71 72 73 |
# File 'lib/funcify/afn.rb', line 71 def error_raiser -> exception, ctx { raise exception unless ctx.success? }.curry end |
.finally_fn ⇒ Object
54 55 56 |
# File 'lib/funcify/afn.rb', line 54 def finally_fn -> enforcer, v { Fn.either.(Fn.maybe_value_ok?).(Fn.identity).(-> x { enforcer.(x) } ).(v) }.curry end |
.for_system ⇒ Object
Helper Fns
171 172 173 174 175 |
# File 'lib/funcify/afn.rb', line 171 def for_system -> system, activities { Fn.remove.(-> a { !a.include?(system.to_s)}).(activities) }.curry end |
.has_activity ⇒ Object
s: system r: r a: action activitys: user’s activity enum
189 190 191 192 193 |
# File 'lib/funcify/afn.rb', line 189 def has_activity -> tests, ctx { activity_match.(tests, ctx[:resource], ctx[:action]).(ctx[:activities]) }.curry end |
.has_priviled ⇒ Object
251 252 253 |
# File 'lib/funcify/afn.rb', line 251 def has_priviled -> req, token { Fn.at.(2,token) == PRIVILEGE }.curry end |
.has_privileged_access ⇒ Object
195 196 197 198 199 |
# File 'lib/funcify/afn.rb', line 195 def has_privileged_access -> tests, ctx { activity_match.(tests, ctx[:privilege], ctx[:action]).(ctx[:activities]) }.curry end |
.has_resource ⇒ Object
247 248 249 |
# File 'lib/funcify/afn.rb', line 247 def has_resource -> req, token { Fn.at.(2,token) == RESOURCE }.curry end |
.key_present_test ⇒ Object
177 178 179 |
# File 'lib/funcify/afn.rb', line 177 def key_present_test -> k, ctx { ctx.has_key? k }.curry end |
.nil_enforcer ⇒ Object
Enforcement Fns
67 68 69 |
# File 'lib/funcify/afn.rb', line 67 def nil_enforcer Fn.identity end |
.or_authorisor ⇒ Object
Similar to all_authorisor, except at least one of the policies MUST be success
46 47 48 49 50 51 52 |
# File 'lib/funcify/afn.rb', line 46 def -> enforcer, policies, ctx { Fn.compose.( any_finally_fn.(enforcer), Fn.map.(-> policy { policy.(ctx) } ) ).(policies) }.curry end |
.policy_match ⇒ Object
208 209 210 211 212 213 214 215 |
# File 'lib/funcify/afn.rb', line 208 def policy_match -> tests, r, a, activity { Fn.compose.( activity_token_matcher.(tests, r,a), Fn.coherse.(:to_sym), Fn.split.(":") ).(activity) }.curry end |
.privilege_activity_policy_tests ⇒ Object
223 224 225 226 227 228 229 230 231 |
# File 'lib/funcify/afn.rb', line 223 def privilege_activity_policy_tests -> r, a { [ has_priviled.(r), resource_test.(r), action_test.(a) ] } end |
.privilege_policy ⇒ Object
The Privelged access control policy
Policy runs 4 tests: + the ctx includes a :privilege key + the ctx includes an :action key + the ctx includes an :activities + and finally, the significant test, the service/resource/action match an activity
151 152 153 154 155 |
# File 'lib/funcify/afn.rb', line 151 def privilege_policy -> activities, filter_fn, ctx { Fn.either.(Fn.tests.(Fn.all?, privilege_tests), Fn.success, Fn.failure ).(ctx.merge(activities: filter_fn.(activities))) }.curry end |
.privilege_tests ⇒ Object
157 158 159 160 161 162 163 164 |
# File 'lib/funcify/afn.rb', line 157 def privilege_tests [ key_present_test.(:privilege), key_present_test.(:action), key_present_test.(:activities), has_privileged_access.(privilege_activity_policy_tests) ] end |
.resource_activity_policy_tests ⇒ Object
233 234 235 236 237 238 239 240 241 |
# File 'lib/funcify/afn.rb', line 233 def resource_activity_policy_tests -> r, a { [ has_resource.(r), resource_test.(r), action_test.(a) ] } end |
.resource_test ⇒ Object
255 256 257 |
# File 'lib/funcify/afn.rb', line 255 def resource_test -> req, token { token_match.(req).(Fn.at.(3).(token)) }.curry end |
.slack_token_policy ⇒ Object
Slack Policy
Slack Policy looks for :token in the ctx, and ensures that token is configured in Account.
99 100 101 |
# File 'lib/funcify/afn.rb', line 99 def slack_token_policy -> expected_token, ctx { Fn.either.(Fn.tests.(Fn.all?, slack_token_tests(expected_token)), Fn.success, Fn.failure ).(ctx) }.curry end |
.slack_token_tests(token) ⇒ Object
103 104 105 106 107 108 |
# File 'lib/funcify/afn.rb', line 103 def slack_token_tests(token) [ key_present_test.(:token), valid_slack_token.(token) ] end |
.system_test ⇒ Object
243 244 245 |
# File 'lib/funcify/afn.rb', line 243 def system_test -> req, token { token_match.(req).(Fn.at.(1).(token)) }.curry end |
.token_match ⇒ Object
263 264 265 266 267 268 |
# File 'lib/funcify/afn.rb', line 263 def token_match -> req, token { # req.nil? || req.size == 0 || token == :* || token == req token == :* || token == req }.curry end |
.valid_slack_token ⇒ Object
181 182 183 |
# File 'lib/funcify/afn.rb', line 181 def valid_slack_token -> t, ctx { ctx[:token] == t }.curry end |