permissable-coughdrop 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +1 -0
  4. data/lib/permissable.rb +157 -0
  5. metadata +89 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 19ade6f481f6b8b941fae5303f9421b74d233138
4
+ data.tar.gz: ecbc28394f26105e1e2f81e7068eca3ba4195ea2
5
+ SHA512:
6
+ metadata.gz: 7e6da68d2af0b8b917a97f7e31a114273263bf5b6ab5894b8a6fad1dfd4bc0d76f5c4fc928635c8db894b6403442c34a724133de2dae153caf4272fdd81f781e
7
+ data.tar.gz: d7adf8bea302e6b82d81157cf22108bee45fe5a272eeca0e1c6acea178cab9e3179437fd2a71da22bcc25165f652db10f303fd36a30bdc111d373ffeedafc36e
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 CoughDrop
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to use,
8
+ copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
9
+ Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ Permissions helper gem, used by multiple CoughDrop libraries
@@ -0,0 +1,157 @@
1
+ require 'json'
2
+
3
+ module Permissable
4
+ ALL_SCOPES = ['full']
5
+ def self.add_scope(str)
6
+ ALL_SCOPES.push(str)
7
+ end
8
+
9
+ def self.set_redis(redis, cache_token)
10
+ @permissions_redis = redis
11
+ @cache_token = cache_token
12
+ end
13
+
14
+ class FakeRedis
15
+ def setex(*args)
16
+ puts "REDIS NOT CONFIGURED, required by Permissable"
17
+ false
18
+ end
19
+
20
+ def get(*args)
21
+ puts "REDIS NOT CONFIGURED, required by Permissable"
22
+ nil
23
+ end
24
+
25
+ def del(*args)
26
+ puts "REDIS NOT CONFIGURED, required by Permissable"
27
+ false
28
+ end
29
+ end
30
+
31
+ def self.permissions_redis
32
+ @permissions_redis ||= FakeRedis.new
33
+ @permissions_redis
34
+ end
35
+
36
+ def self.cache_token
37
+ # used to quickly invalidate the entire cache
38
+ @cache_token ||= 'permissable_redis_cache_token'
39
+ @cache_token
40
+ end
41
+
42
+ module InstanceMethods
43
+ def cache_key(prefix=nil)
44
+ id = self.id || 'nil'
45
+ updated = (self.updated_at || Time.now).to_f
46
+ key = "#{self.class.to_s}#{id}-#{updated}:#{Permissable.cache_token}"
47
+ if prefix
48
+ key = prefix + "/" + key
49
+ end
50
+ key
51
+ end
52
+
53
+ def set_cached(prefix, data, expires=nil)
54
+ expires ||= 1800 # 30 minutes
55
+ Permissable.permissions_redis.setex(self.cache_key(prefix), expires, data.to_json)
56
+ end
57
+
58
+ def get_cached(prefix)
59
+ cache_string = Permissable.permissions_redis.get(self.cache_key(prefix))
60
+ cache = nil
61
+ if cache_string
62
+ cache = JSON.parse(cache_string) rescue nil
63
+ end
64
+ cache
65
+ end
66
+
67
+ def clear_cached(prefix)
68
+ Permissable.permissions_redis.del(self.cache_key(prefix))
69
+ end
70
+
71
+ def allows?(user, action, relevant_scopes=nil)
72
+ relevant_scopes ||= self.class.default_permission_scopes
73
+ relevant_scopes += ['*']
74
+ if self.class.allow_cached_permissions
75
+ # check for an existing result keyed off the record's id and updated_at
76
+ permissions = permissions_for(user, relevant_scopes)
77
+ action.instance_variable_set('@scope_rejected', permissions[action] == false)
78
+
79
+ return permissions[action] == true
80
+ end
81
+
82
+ scope_rejected = false
83
+ self.class.permissions_lookup.each do |actions, block, allowed_scopes|
84
+ next unless actions.include?(action.to_s)
85
+ next if block.arity == 1 && !user
86
+ res = instance_exec(user, &block)
87
+ if res == true
88
+ if (allowed_scopes & relevant_scopes).length > 0
89
+ return true
90
+ else
91
+ scope_rejected = true
92
+ end
93
+ end
94
+ end
95
+ action.instance_variable_set('@scope_rejected', !!scope_rejected)
96
+ return false
97
+ end
98
+
99
+ def permissions_for(user, relevant_scopes=nil)
100
+ relevant_scopes ||= self.class.default_permission_scopes
101
+ relevant_scopes += ['*']
102
+ if self.class.allow_cached_permissions
103
+ cache_key = (user && user.cache_key) || "nobody"
104
+ cache_key += "/scopes_#{relevant_scopes.join(',')}"
105
+ permissions = get_cached("permissions-for/#{cache_key}")
106
+ return permissions if permissions
107
+ end
108
+
109
+ granted_permissions = {
110
+ 'user_id' => (user && user.global_id)
111
+ }
112
+ granted_permissions.with_indifferent_access if granted_permissions.respond_to?(:with_indifferent_access)
113
+
114
+ self.class.permissions_lookup.each do |actions, block, allowed_scopes|
115
+ already_granted = granted_permissions.keys
116
+ next if block.arity == 1 && !user
117
+ next if actions - already_granted == []
118
+ if instance_exec(user, &block)
119
+ actions.each do |action|
120
+ if (allowed_scopes & relevant_scopes).length > 0
121
+ granted_permissions[action] = true
122
+ else
123
+ granted_permissions[action] ||= false
124
+ end
125
+ end
126
+ end
127
+ end
128
+ # cache the result with a 30-minute expiration keyed off the id and updated_at
129
+ set_cached("permissions-for/#{cache_key}", granted_permissions) if self.class.allow_cached_permissions
130
+ granted_permissions
131
+ end
132
+
133
+ def self.included(base)
134
+ base.define_singleton_method(:included) do |klass|
135
+ klass.cattr_accessor :permissions_lookup
136
+ klass.cattr_accessor :allow_cached_permissions
137
+ klass.cattr_accessor :default_permission_scopes
138
+ klass.default_permission_scopes = ['full']
139
+ klass.permissions_lookup = []
140
+ end
141
+ end
142
+ end
143
+
144
+ module ClassMethods
145
+ def cache_permissions
146
+ self.allow_cached_permissions = true
147
+ end
148
+
149
+ def add_permissions(*actions, &block)
150
+ scopes = ['full']
151
+ if actions[-1].is_a?(Array)
152
+ scopes += actions.pop
153
+ end
154
+ self.permissions_lookup << [actions.map(&:to_s), block, scopes.sort.uniq]
155
+ end
156
+ end
157
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: permissable-coughdrop
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Brian Whitmer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-10-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ruby-debug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Permissions helper gem, used by multiple CoughDrop libraries
56
+ email: brian.whitmer@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files:
60
+ - LICENSE
61
+ files:
62
+ - LICENSE
63
+ - README.md
64
+ - lib/permissable.rb
65
+ homepage: http://github.com/CoughDrop/permissable
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.5.2
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Permissable
89
+ test_files: []