egoist 0.5.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a6b402250800b2baaa5bacd32efadb63c68a3b9364fae92523b9eb3e13bd84ef
4
+ data.tar.gz: 609c7e240a70f6b33e98f1ed79c183e2a29fe466f94d49289562c905b2cb827a
5
+ SHA512:
6
+ metadata.gz: db2aea02ff0afb797b5dc3b978553191e816df2e7a81019981fb04cbcc5a1530727de6bbe725c621b6c749d72d7b46f23d37aa49121ce8ecc7698fe3efffb632
7
+ data.tar.gz: 677256afb6d61ba83ee3ce1f1f2cd6aebaa43b1328b1840f03a77f226d030b32d6bcac9a36c2368177f826e88eaa4fa65a643353eb8b009c74b3c1d6e4df1019
data/.version ADDED
@@ -0,0 +1 @@
1
+ 0.5.0
@@ -0,0 +1,51 @@
1
+ klass =
2
+ if defined? Rails
3
+ ActiveController::Base
4
+ elsif defined? Lux
5
+ Lux::Controller
6
+ end
7
+
8
+ if klass
9
+ klass.class_eval do
10
+ def authorize *args, &block
11
+ opts = {}
12
+
13
+ @_is_policy_authorized = true
14
+
15
+ raise ArgumentErorr, 'authorize argument[s] not provided' unless args[0]
16
+
17
+ # authorize true
18
+ return if args[0].is_a? TrueClass
19
+
20
+ if !args[1]
21
+ # authorize :admin?
22
+ opts[:action] = args.first
23
+ elsif args[2]
24
+ # authorize @model, write?, CustomClass
25
+ # authorize @model, write?, class: CustomClass
26
+ opts[:model] = args.first
27
+ opts[:action] = args[1]
28
+ opts[:class] = args[2].is_a?(Hash) ? args[2][:class] : args[2]
29
+ else
30
+ # authorize @model, write?
31
+ opts[:model] = args.first
32
+ opts[:action] = args[1]
33
+ end
34
+
35
+ # covert all authorize actions to bang actions (fail unless true)
36
+ action = opts.delete(:action).to_s.sub('?', '!')
37
+
38
+ # do it
39
+ Policy(opts).send(action, &block)
40
+ end
41
+
42
+ def is_authorized?
43
+ @_is_policy_authorized == true
44
+ end
45
+
46
+ def is_authorized!
47
+ raise ::Policy::Error.new('Request is not authorized!') unless is_authorized?
48
+ true
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,21 @@
1
+ class Policy
2
+ module ModelAdapter
3
+ def self.can user, model
4
+ klass = '%sPolicy' % model.class
5
+ klass = Object.const_defined?(klass) ? klass.constantize : ::ModelPolicy
6
+ Policy(model: model || self, user: user, class: klass)
7
+ end
8
+ end
9
+ end
10
+
11
+ if defined? Rails
12
+ ActiveModel::Base.include Policy::ModelAdapter
13
+ elsif defined? Sequel
14
+ class Sequel::Model
15
+ module InstanceMethods
16
+ def can user=nil
17
+ Policy::ModelAdapter.can user, self
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,81 @@
1
+ class Policy
2
+ class << self
3
+ def can(model=nil, user=nil)
4
+ if model.is_a?(Hash)
5
+ user, model = model[:user], model[:model]
6
+ end
7
+
8
+ new(user: user, model: model).can
9
+ end
10
+ end
11
+
12
+ ###
13
+
14
+ attr_reader :model, :user, :action
15
+
16
+ def initialize model:, user: nil
17
+ @model = model
18
+ @user = user || current_user
19
+ end
20
+
21
+ # pass block if you want to handle errors yourself
22
+ # return true if false if block is passed
23
+ def can? action, *args, &block
24
+ @action = action
25
+ .to_s
26
+ .gsub(/[^\w+]/, '')
27
+ .concat('?')
28
+ .to_sym
29
+
30
+ # pre check
31
+ raise RuntimeError, 'Method name not allowed' if %i(can).index(@action)
32
+ raise NoMethodError, %[Policy check "#{@action}" not found in #{self.class}] unless respond_to?(@action)
33
+
34
+ call *args, &block
35
+ end
36
+
37
+ def can
38
+ Proxy.new self
39
+ end
40
+
41
+ private
42
+
43
+ # call has to be isolated because specific of error handling
44
+ def call *args, &block
45
+ raise Error, 'User is not defined, no access' unless @user
46
+
47
+ return true if before(@action)
48
+ return true if send(@action, *args)
49
+
50
+ raise Error, 'Access disabled in policy'
51
+ rescue Policy::Error => error
52
+ message = error.message
53
+ message += " - #{self.class}##{@action}"
54
+
55
+ if block
56
+ block.call(message)
57
+ false
58
+ else
59
+ raise Policy::Error, message
60
+ end
61
+ end
62
+
63
+ def before action
64
+ false
65
+ end
66
+
67
+ def error message
68
+ raise Policy::Error.new(message)
69
+ end
70
+
71
+ # get current user from globals if globals defined
72
+ def current_user
73
+ if defined?(User) && User.respond_to?(:current)
74
+ User.current
75
+ elsif defined?(Current) && Current.respond_to?(:user)
76
+ Current.user
77
+ else
78
+ raise RuntimeError.new('Current user not found in Policy#current_user')
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,4 @@
1
+ class Policy
2
+ class Error < StandardError
3
+ end
4
+ end
@@ -0,0 +1,16 @@
1
+ # Policy(:application) -> ApplicationPolicy.can(model: nil, user: current_user)
2
+ # Policy(@post) -> PostPolict.can(model: @post, user: current_user)
3
+ # Policy(@post, @user) -> PostPolict.can(model: @post, user: @user)
4
+ # Policy(model: @post, user: @user) -> PostPolict.can(model: @post, user: @user)
5
+ def Policy model, user=nil
6
+ if model.is_a?(Hash)
7
+ user, model = model[:user], model[:model]
8
+ end
9
+
10
+ raise ArgumentError, 'Model not defined' unless model
11
+
12
+ klass = model.is_a?(Symbol) ? model : model.class
13
+ klass = ('%s_policy' % klass).classify.constantize
14
+
15
+ klass.new(user: user, model: model).can
16
+ end
@@ -0,0 +1,28 @@
1
+ class Policy
2
+ class Proxy
3
+ def initialize policy
4
+ @policy = policy
5
+ end
6
+
7
+ def method_missing name, *args, &block
8
+ name = name.to_s.sub(/(.)$/, '')
9
+ action = $1
10
+
11
+ @policy.can?(name, *args)
12
+ @policy.model || true
13
+ rescue Policy::Error => error
14
+ if block_given?
15
+ yield
16
+ return nil
17
+ end
18
+
19
+ if action == '!'
20
+ raise error
21
+ elsif action == '?'
22
+ nil
23
+ else
24
+ raise ArgumentError.new('Bad policy method %s' % name)
25
+ end
26
+ end
27
+ end
28
+ end
data/lib/egoist.rb ADDED
@@ -0,0 +1,7 @@
1
+ require_relative 'egoist/base'
2
+ require_relative 'egoist/error'
3
+ require_relative 'egoist/proxy'
4
+ require_relative 'egoist/global'
5
+
6
+ require_relative 'adapters/controller'
7
+ require_relative 'adapters/model'
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: egoist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Dino Reic
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-04 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Clean, simple explicit and strait-forward policy definitions.
14
+ email: reic.dino@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - "./.version"
20
+ - "./lib/adapters/controller.rb"
21
+ - "./lib/adapters/model.rb"
22
+ - "./lib/egoist.rb"
23
+ - "./lib/egoist/base.rb"
24
+ - "./lib/egoist/error.rb"
25
+ - "./lib/egoist/global.rb"
26
+ - "./lib/egoist/proxy.rb"
27
+ homepage: https://github.com/dux/egoist
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.0.6
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Ruby access policy library
50
+ test_files: []