generic_auth 0.1.1
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.
- data/lib/generic_auth/auth_error.rb +4 -0
- data/lib/generic_auth/engine.rb +139 -0
- data/lib/generic_auth/guard.rb +14 -0
- data/lib/generic_auth/guest.rb +7 -0
- data/lib/generic_auth/rules.rb +43 -0
- data/lib/generic_auth/version.rb +3 -0
- data/lib/generic_auth.rb +9 -0
- metadata +123 -0
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
# roles[:person][:module_class_method] = [context_1, context_2, ...]
|
3
|
+
module GenericAuth
|
4
|
+
class Engine
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@roles = {}
|
9
|
+
@user = Guest.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def user= user=nil
|
13
|
+
user = GenericAuth::Guest.new if user.nil?
|
14
|
+
raise ArgumentError, 'User must respond_to? roles' unless user.respond_to?(:roles)
|
15
|
+
@user = user
|
16
|
+
end
|
17
|
+
|
18
|
+
def user
|
19
|
+
@user
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_role role
|
23
|
+
require_no_role role
|
24
|
+
|
25
|
+
@roles[role] = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear_roles
|
29
|
+
@roles = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove_role role
|
33
|
+
require_role_symbol role
|
34
|
+
|
35
|
+
@roles.delete(role) if @roles[role]
|
36
|
+
end
|
37
|
+
|
38
|
+
def roles
|
39
|
+
@roles.keys
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_activity role, activity, contexts = []
|
43
|
+
require_activity_symbol activity
|
44
|
+
require_defined_role role
|
45
|
+
|
46
|
+
@roles[role][activity] = contexts
|
47
|
+
end
|
48
|
+
|
49
|
+
def remove_activity role, activity
|
50
|
+
require_defined_role role
|
51
|
+
require_activity_symbol activity
|
52
|
+
|
53
|
+
@roles[role].delete(activity) if @roles[role][activity]
|
54
|
+
end
|
55
|
+
|
56
|
+
def clear_activities role
|
57
|
+
require_defined_role role
|
58
|
+
@roles[role] = {} if @roles[role]
|
59
|
+
end
|
60
|
+
|
61
|
+
def activities role
|
62
|
+
require_role_symbol role
|
63
|
+
@roles[role].keys
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_context role, activity, &block
|
67
|
+
require_defined_activity role, activity
|
68
|
+
raise ArgumentError, 'Invalid callback, callback must respond_to? call' unless block.respond_to?(:call)
|
69
|
+
|
70
|
+
@roles[role][activity] << block
|
71
|
+
end
|
72
|
+
|
73
|
+
def remove_context role, activity, index
|
74
|
+
require_defined_activity role, activity
|
75
|
+
|
76
|
+
@roles[role][activity].delete_at(index) if @roles[role][activity]
|
77
|
+
end
|
78
|
+
|
79
|
+
def clear_contexts role, activity
|
80
|
+
require_role_symbol role
|
81
|
+
require_activity_symbol activity
|
82
|
+
@roles[role][activity] = [] if @roles[role] && @roles[role][activity]
|
83
|
+
end
|
84
|
+
|
85
|
+
def contexts role, activity
|
86
|
+
require_defined_role role
|
87
|
+
require_activity_symbol activity
|
88
|
+
@roles[role][activity]
|
89
|
+
end
|
90
|
+
|
91
|
+
def permitted? role, activity, object, *args
|
92
|
+
require_defined_role role
|
93
|
+
return false unless @roles[role][activity]
|
94
|
+
return true if @roles[role][activity].empty?
|
95
|
+
@roles[role][activity].all? do |context|
|
96
|
+
context.call(object, *args)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def wrap_class(klass)
|
101
|
+
wrapped = klass.to_s.camelize.constantize
|
102
|
+
raise 'Class must respond_to? generic_auth_on with an array of methods(activites) to authorize' unless wrapped.respond_to?(:generic_auth_on)
|
103
|
+
activities = wrapped.send(:generic_auth_on)
|
104
|
+
activities.each do |activity|
|
105
|
+
old = wrapped.instance_method(activity)
|
106
|
+
wrapped.send(:define_method, activity) do |*args|
|
107
|
+
GenericAuth::Guard.authorize activity, self, *args
|
108
|
+
old.bind(self).(*args)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
def require_role_symbol role
|
115
|
+
raise ArgumentError, 'Role must be a symbol' unless role.is_a?(Symbol)
|
116
|
+
end
|
117
|
+
|
118
|
+
def require_activity_symbol activity
|
119
|
+
raise ArgumentError, 'Activity must be a symbol' unless activity.is_a?(Symbol)
|
120
|
+
end
|
121
|
+
|
122
|
+
def require_no_role role
|
123
|
+
require_role_symbol role
|
124
|
+
raise ArgumentError, 'Role is already defined' unless @roles[role].nil?
|
125
|
+
end
|
126
|
+
|
127
|
+
def require_defined_role role
|
128
|
+
require_role_symbol role
|
129
|
+
raise ArgumentError, "The #{role} role is not defined" if @roles[role].nil?
|
130
|
+
end
|
131
|
+
|
132
|
+
def require_defined_activity role, activity
|
133
|
+
require_defined_role role
|
134
|
+
require_activity_symbol activity
|
135
|
+
raise ArgumentError, "Role #{role} has no permission for activity #{activity}" if @roles[role][activity].nil?
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module GenericAuth
|
2
|
+
class Guard
|
3
|
+
def self.authorize activity, object, *args
|
4
|
+
permitted = false
|
5
|
+
Engine.instance.user.roles.each do |role|
|
6
|
+
if Engine.instance.permitted? role, activity, object, *args
|
7
|
+
permitted = true
|
8
|
+
break
|
9
|
+
end
|
10
|
+
end
|
11
|
+
raise GenericAuth::AuthError, "User not authorized for activity #{activity}" unless permitted
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module GenericAuth
|
2
|
+
class Rules
|
3
|
+
|
4
|
+
@role = nil
|
5
|
+
@wrapped = []
|
6
|
+
|
7
|
+
def self.define &block
|
8
|
+
instance_eval(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.role role, &block
|
12
|
+
Engine.instance.add_role(role)
|
13
|
+
@role = role
|
14
|
+
yield
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.permitted_to activities, options = {}, &block
|
18
|
+
activities = [activities] unless activities.is_a?(Array)
|
19
|
+
activities.each do |activity|
|
20
|
+
Engine.instance.add_activity(@role, activity)
|
21
|
+
@activity = activity
|
22
|
+
instance_eval(&block) if block_given?
|
23
|
+
unless @wrapped.include?(options[:on])
|
24
|
+
Engine.instance.wrap_class(options[:on])
|
25
|
+
@wrapped << options[:on]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@activity = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.context &block
|
32
|
+
raise 'Context must be declared inside an activity' if @activity.nil?
|
33
|
+
Engine.instance.add_context @role, @activity, &block if block_given?
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.includes role
|
37
|
+
activities = Engine.instance.activities(role)
|
38
|
+
activities.each do |activity|
|
39
|
+
Engine.instance.add_activity(@role, activity)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/generic_auth.rb
ADDED
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: generic_auth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chris McLeod
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: simplecov
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: ! "This gem works on the most basic ruby classes. Its only dependency
|
79
|
+
is activesupport for some\n string and inflector functionality.
|
80
|
+
\ GenericAuth is very easy to use, simply create a rules file and your class methods\n
|
81
|
+
\ are automatically wrapped to invoke authorization methods before
|
82
|
+
they are run. You must set the user which must\n respond to
|
83
|
+
a roles method. Your authorized classes must also specify which methods should
|
84
|
+
be authorized (generic_auth_on method) \n as an array of symbols
|
85
|
+
(see specs). Other than that, its automatic"
|
86
|
+
email:
|
87
|
+
- chris12295@gmail.com
|
88
|
+
executables: []
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- lib/generic_auth.rb
|
93
|
+
- lib/generic_auth/auth_error.rb
|
94
|
+
- lib/generic_auth/engine.rb
|
95
|
+
- lib/generic_auth/guard.rb
|
96
|
+
- lib/generic_auth/guest.rb
|
97
|
+
- lib/generic_auth/rules.rb
|
98
|
+
- lib/generic_auth/version.rb
|
99
|
+
homepage: https://github.com/chrismcleod/generic_auth
|
100
|
+
licenses: []
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ! '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubyforge_project: ! '[none]'
|
119
|
+
rubygems_version: 1.8.23
|
120
|
+
signing_key:
|
121
|
+
specification_version: 3
|
122
|
+
summary: Generic authorization for any class and framework
|
123
|
+
test_files: []
|