egoist 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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: []