annotation_security 1.0.1 → 1.0.2
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/CHANGELOG.md +14 -0
- data/HOW-TO.md +275 -0
- data/{MIT-LICENSE → LICENSE} +1 -1
- data/README.md +39 -0
- data/Rakefile +62 -55
- data/assets/app/helpers/annotation_security_helper.rb +8 -8
- data/assets/config/initializers/annotation_security.rb +11 -11
- data/assets/config/security/relations.rb +20 -20
- data/assets/vendor/plugins/annotation_security/init.rb +13 -13
- data/bin/annotation_security +7 -7
- data/lib/annotation_security/exceptions.rb +124 -124
- data/lib/annotation_security/exec.rb +188 -188
- data/lib/annotation_security/filters.rb +37 -37
- data/lib/annotation_security/includes/action_controller.rb +144 -143
- data/lib/annotation_security/includes/active_record.rb +27 -27
- data/lib/annotation_security/includes/helper.rb +215 -215
- data/lib/annotation_security/includes/resource.rb +84 -84
- data/lib/annotation_security/includes/role.rb +30 -30
- data/lib/annotation_security/includes/user.rb +26 -26
- data/lib/annotation_security/manager/policy_factory.rb +29 -29
- data/lib/annotation_security/manager/policy_manager.rb +79 -79
- data/lib/annotation_security/manager/relation_loader.rb +272 -272
- data/lib/annotation_security/manager/resource_manager.rb +36 -36
- data/lib/annotation_security/manager/right_loader.rb +87 -87
- data/lib/annotation_security/model_observer.rb +61 -61
- data/lib/annotation_security/policy/abstract_policy.rb +344 -344
- data/lib/annotation_security/policy/abstract_static_policy.rb +75 -75
- data/lib/annotation_security/policy/all_resources_policy.rb +20 -20
- data/lib/annotation_security/policy/rule.rb +340 -340
- data/lib/annotation_security/policy/rule_set.rb +138 -138
- data/lib/annotation_security/rails.rb +38 -38
- data/lib/annotation_security/user_wrapper.rb +73 -73
- data/lib/annotation_security/utils.rb +141 -141
- data/lib/annotation_security/version.rb +10 -0
- data/lib/annotation_security.rb +102 -97
- data/lib/extensions/action_controller.rb +32 -32
- data/lib/extensions/active_record.rb +34 -34
- data/lib/extensions/filter.rb +133 -133
- data/lib/extensions/object.rb +10 -10
- data/lib/security_context.rb +589 -551
- data/spec/annotation_security/exceptions_spec.rb +16 -16
- data/spec/annotation_security/includes/helper_spec.rb +82 -82
- data/spec/annotation_security/manager/policy_manager_spec.rb +15 -15
- data/spec/annotation_security/manager/resource_manager_spec.rb +17 -17
- data/spec/annotation_security/manager/right_loader_spec.rb +17 -17
- data/spec/annotation_security/policy/abstract_policy_spec.rb +16 -16
- data/spec/annotation_security/policy/all_resources_policy_spec.rb +24 -24
- data/spec/annotation_security/policy/rule_set_spec.rb +112 -112
- data/spec/annotation_security/policy/rule_spec.rb +77 -77
- data/spec/annotation_security/policy/test_policy_spec.rb +80 -80
- data/spec/annotation_security/security_context_spec.rb +78 -78
- data/spec/annotation_security/utils_spec.rb +73 -73
- data/spec/helper/test_controller.rb +65 -65
- data/spec/helper/test_helper.rb +5 -5
- data/spec/helper/test_relations.rb +6 -6
- data/spec/helper/test_resource.rb +38 -38
- data/spec/helper/test_role.rb +21 -21
- data/spec/helper/test_user.rb +31 -31
- data/spec/rails_stub.rb +37 -37
- metadata +94 -72
- data/CHANGELOG +0 -2
- data/HOW-TO +0 -261
- data/README +0 -39
@@ -1,125 +1,125 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/exceptions.rb
|
3
|
-
#
|
4
|
-
# Provides some Exceptions used within AnnotationSecurity
|
5
|
-
|
6
|
-
module AnnotationSecurity
|
7
|
-
|
8
|
-
# Superclass of all security related errors thrown by anno sec
|
9
|
-
class SecurityError < StandardError # :nodoc:
|
10
|
-
end
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
# Exception indicating that some rights were violated.
|
15
|
-
#
|
16
|
-
class SecurityViolationError < AnnotationSecurity::SecurityError
|
17
|
-
|
18
|
-
def self.access_denied(user,*args) # :nodoc:
|
19
|
-
new(user,*args)
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize(user=nil,*args) # :nodoc:
|
23
|
-
if user == nil || args.empty?
|
24
|
-
super "Access denied"
|
25
|
-
else
|
26
|
-
super load_args(user,args)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def load_args(user,args) # :nodoc:
|
31
|
-
@user = user
|
32
|
-
@action,@resclass,@res = AnnotationSecurity::Utils.parse_policy_arguments(args)
|
33
|
-
"You (#@user) are missing the right '#@action' for #@resclass" +
|
34
|
-
(@res.blank? ? '' : " '#@res'")
|
35
|
-
end
|
36
|
-
|
37
|
-
# user that violated the right
|
38
|
-
#
|
39
|
-
def user
|
40
|
-
@user
|
41
|
-
end
|
42
|
-
|
43
|
-
# the action that should have been performed on the resource object
|
44
|
-
#
|
45
|
-
def action
|
46
|
-
@action
|
47
|
-
end
|
48
|
-
|
49
|
-
# the resource type
|
50
|
-
#
|
51
|
-
def resource_class
|
52
|
-
@resclass
|
53
|
-
end
|
54
|
-
|
55
|
-
# the resource that was accessed
|
56
|
-
#
|
57
|
-
def resource
|
58
|
-
@res
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
module AnnotationSecurity
|
63
|
-
|
64
|
-
# = AnnotationSecurity::RuleError
|
65
|
-
#
|
66
|
-
# Will be raised if a right or relation is defined twice
|
67
|
-
# or has an invalid name.
|
68
|
-
#
|
69
|
-
class RuleError < SecurityError
|
70
|
-
def self.defined_twice(type,rule) # :nodoc:
|
71
|
-
new "The #{type} #{rule} is defined twice"
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.forbidden_name(type,rule) # :nodoc:
|
75
|
-
new "#{rule} is not allowed as #{type} name"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# = AnnotationSecurity::RuleExecutionError
|
80
|
-
#
|
81
|
-
# Will be raised if an error occured while evaluation a right or relation.
|
82
|
-
#
|
83
|
-
class RuleExecutionError < RuleError
|
84
|
-
|
85
|
-
def initialize(rule, proc=false, ex = nil) # :nodoc:
|
86
|
-
if ex
|
87
|
-
log_backtrace(proc,ex)
|
88
|
-
super("An error occured while evaluating #{rule}: \n" +
|
89
|
-
ex.class.name + ": " + ex.message)
|
90
|
-
else
|
91
|
-
super("An error occured while evaluating #{rule}")
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def set_backtrace(array) # :nodoc:
|
96
|
-
super((@bt || []) + array[1..-1])
|
97
|
-
end
|
98
|
-
|
99
|
-
private
|
100
|
-
|
101
|
-
# Select all lines of the backtrace above "rule.rb evaluate".
|
102
|
-
# so they can be appended to the backtrace
|
103
|
-
def log_backtrace(proc,ex)
|
104
|
-
return unless proc
|
105
|
-
backtrace = ex.backtrace
|
106
|
-
stop = backtrace.find { |l| l =~ /rule\.rb(.*)`evaluate'/ }
|
107
|
-
stop = backtrace.index(stop) || 5
|
108
|
-
backtrace = backtrace.first(stop)
|
109
|
-
@bt = backtrace.reject { |l| l =~ /annotation_security|active_support/ }
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
# = AnnotationSecurity::RuleNotFoundError
|
115
|
-
#
|
116
|
-
# Will be raised when attempting to acces a right or relation that was not
|
117
|
-
# defined.
|
118
|
-
#
|
119
|
-
class RuleNotFoundError < RuleError
|
120
|
-
def self.for_rule(rname,policy_class)
|
121
|
-
new("Unknown #{policy_class.static? ? 'static' : 'dynamic'} " +
|
122
|
-
"rule '#{rname}' for #{policy_class.name}")
|
123
|
-
end
|
124
|
-
end
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/exceptions.rb
|
3
|
+
#
|
4
|
+
# Provides some Exceptions used within AnnotationSecurity
|
5
|
+
|
6
|
+
module AnnotationSecurity
|
7
|
+
|
8
|
+
# Superclass of all security related errors thrown by anno sec
|
9
|
+
class SecurityError < StandardError # :nodoc:
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
# Exception indicating that some rights were violated.
|
15
|
+
#
|
16
|
+
class SecurityViolationError < AnnotationSecurity::SecurityError
|
17
|
+
|
18
|
+
def self.access_denied(user,*args) # :nodoc:
|
19
|
+
new(user,*args)
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(user=nil,*args) # :nodoc:
|
23
|
+
if user == nil || args.empty?
|
24
|
+
super "Access denied"
|
25
|
+
else
|
26
|
+
super load_args(user,args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def load_args(user,args) # :nodoc:
|
31
|
+
@user = user
|
32
|
+
@action,@resclass,@res = AnnotationSecurity::Utils.parse_policy_arguments(args)
|
33
|
+
"You (#@user) are missing the right '#@action' for #@resclass" +
|
34
|
+
(@res.blank? ? '' : " '#@res'")
|
35
|
+
end
|
36
|
+
|
37
|
+
# user that violated the right
|
38
|
+
#
|
39
|
+
def user
|
40
|
+
@user
|
41
|
+
end
|
42
|
+
|
43
|
+
# the action that should have been performed on the resource object
|
44
|
+
#
|
45
|
+
def action
|
46
|
+
@action
|
47
|
+
end
|
48
|
+
|
49
|
+
# the resource type
|
50
|
+
#
|
51
|
+
def resource_class
|
52
|
+
@resclass
|
53
|
+
end
|
54
|
+
|
55
|
+
# the resource that was accessed
|
56
|
+
#
|
57
|
+
def resource
|
58
|
+
@res
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module AnnotationSecurity
|
63
|
+
|
64
|
+
# = AnnotationSecurity::RuleError
|
65
|
+
#
|
66
|
+
# Will be raised if a right or relation is defined twice
|
67
|
+
# or has an invalid name.
|
68
|
+
#
|
69
|
+
class RuleError < SecurityError
|
70
|
+
def self.defined_twice(type,rule) # :nodoc:
|
71
|
+
new "The #{type} #{rule} is defined twice"
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.forbidden_name(type,rule) # :nodoc:
|
75
|
+
new "#{rule} is not allowed as #{type} name"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# = AnnotationSecurity::RuleExecutionError
|
80
|
+
#
|
81
|
+
# Will be raised if an error occured while evaluation a right or relation.
|
82
|
+
#
|
83
|
+
class RuleExecutionError < RuleError
|
84
|
+
|
85
|
+
def initialize(rule, proc=false, ex = nil) # :nodoc:
|
86
|
+
if ex
|
87
|
+
log_backtrace(proc,ex)
|
88
|
+
super("An error occured while evaluating #{rule}: \n" +
|
89
|
+
ex.class.name + ": " + ex.message)
|
90
|
+
else
|
91
|
+
super("An error occured while evaluating #{rule}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def set_backtrace(array) # :nodoc:
|
96
|
+
super((@bt || []) + array[1..-1])
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# Select all lines of the backtrace above "rule.rb evaluate".
|
102
|
+
# so they can be appended to the backtrace
|
103
|
+
def log_backtrace(proc,ex)
|
104
|
+
return unless proc
|
105
|
+
backtrace = ex.backtrace
|
106
|
+
stop = backtrace.find { |l| l =~ /rule\.rb(.*)`evaluate'/ }
|
107
|
+
stop = backtrace.index(stop) || 5
|
108
|
+
backtrace = backtrace.first(stop)
|
109
|
+
@bt = backtrace.reject { |l| l =~ /annotation_security|active_support/ }
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
# = AnnotationSecurity::RuleNotFoundError
|
115
|
+
#
|
116
|
+
# Will be raised when attempting to acces a right or relation that was not
|
117
|
+
# defined.
|
118
|
+
#
|
119
|
+
class RuleNotFoundError < RuleError
|
120
|
+
def self.for_rule(rname,policy_class)
|
121
|
+
new("Unknown #{policy_class.static? ? 'static' : 'dynamic'} " +
|
122
|
+
"rule '#{rname}' for #{policy_class.name}")
|
123
|
+
end
|
124
|
+
end
|
125
125
|
end
|
@@ -1,189 +1,189 @@
|
|
1
|
-
require 'optparse'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
# = lib/annotation_security/exec.rb
|
5
|
-
# This file is borrowed heavily from HAML
|
6
|
-
#
|
7
|
-
|
8
|
-
module AnnotationSecurity
|
9
|
-
module Exec # :nodoc:
|
10
|
-
|
11
|
-
# An abstract class that encapsulates the executable
|
12
|
-
# code for all executables.
|
13
|
-
class Generic # :nodoc:
|
14
|
-
|
15
|
-
# Parsed options
|
16
|
-
def options
|
17
|
-
@options ||= {}
|
18
|
-
end
|
19
|
-
|
20
|
-
# @param args [Array<String>] The command-line arguments
|
21
|
-
def initialize(args)
|
22
|
-
@args = args
|
23
|
-
end
|
24
|
-
|
25
|
-
# Parses the command-line arguments and runs the executable.
|
26
|
-
# Calls `Kernel#exit` at the end, so it never returns.
|
27
|
-
def parse!
|
28
|
-
begin
|
29
|
-
@opts = OptionParser.new(&method(:set_opts))
|
30
|
-
@opts.parse!(@args)
|
31
|
-
|
32
|
-
process_result
|
33
|
-
|
34
|
-
options
|
35
|
-
rescue Exception => e
|
36
|
-
raise e if e.is_a?(SystemExit) || options[:trace]
|
37
|
-
|
38
|
-
$stderr.puts e.message
|
39
|
-
exit 1
|
40
|
-
end
|
41
|
-
exit 0
|
42
|
-
end
|
43
|
-
|
44
|
-
# @return [String] A description of the executable
|
45
|
-
def to_s
|
46
|
-
@opts.to_s
|
47
|
-
end
|
48
|
-
|
49
|
-
protected
|
50
|
-
|
51
|
-
# Tells optparse how to parse the arguments
|
52
|
-
# available for all executables.
|
53
|
-
#
|
54
|
-
# This is meant to be overridden by subclasses
|
55
|
-
# so they can add their own options.
|
56
|
-
#
|
57
|
-
# @param opts [OptionParser]
|
58
|
-
def set_opts(opts)
|
59
|
-
opts.on("--force", "Force command execution, override assets without asking") do
|
60
|
-
options[:force] = true
|
61
|
-
end
|
62
|
-
|
63
|
-
opts.on("--trace", "Shows full stack trace in case of errors") do
|
64
|
-
options[:trace] = true
|
65
|
-
end
|
66
|
-
|
67
|
-
opts.on_tail("-?", "-h", "--help", "Show this message") do
|
68
|
-
puts opts
|
69
|
-
exit
|
70
|
-
end
|
71
|
-
|
72
|
-
opts.on_tail("-v", "--version", "Print version") do
|
73
|
-
puts("AnnotationSecurity 0.01")
|
74
|
-
exit
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Processes the options set by the command-line arguments.
|
79
|
-
#
|
80
|
-
# This is meant to be overridden by subclasses
|
81
|
-
# so they can run their respective programs.
|
82
|
-
def process_result; end
|
83
|
-
end
|
84
|
-
|
85
|
-
# An abstrac class that encapsulates the code
|
86
|
-
# specific to executables.
|
87
|
-
class RailsInstaller < Generic # :nodoc:
|
88
|
-
|
89
|
-
ASSET_FILES = %w{
|
90
|
-
config/initializers/annotation_security.rb
|
91
|
-
config/security/relations.rb
|
92
|
-
config/security/rights.yml
|
93
|
-
app/helpers/annotation_security_helper.rb
|
94
|
-
vendor/plugins/annotation_security/init.rb
|
95
|
-
}
|
96
|
-
|
97
|
-
# @param args [Array<String>] The command-line arguments
|
98
|
-
def initialize(args)
|
99
|
-
super
|
100
|
-
@name = "annosec"
|
101
|
-
end
|
102
|
-
|
103
|
-
protected
|
104
|
-
|
105
|
-
# Tells optparse how to parse the arguments.
|
106
|
-
#
|
107
|
-
# This is meant to be overridden by subclasses
|
108
|
-
# so they can add their own options.
|
109
|
-
#
|
110
|
-
# @param opts [OptionParser]
|
111
|
-
def set_opts(opts)
|
112
|
-
opts.banner = <<END
|
113
|
-
Usage: #{@name.downcase} [options]
|
114
|
-
|
115
|
-
Description:
|
116
|
-
Installs the AnnotationSecurity layer into a rails app
|
117
|
-
|
118
|
-
Options:
|
119
|
-
END
|
120
|
-
|
121
|
-
opts.on('--rails RAILS_DIR', "Install AnnotationSecurity layer from the Gem to a Rails project") do |dir|
|
122
|
-
options[:rails_dir] = dir
|
123
|
-
end
|
124
|
-
|
125
|
-
super
|
126
|
-
end
|
127
|
-
|
128
|
-
# Processes the options set by the command-line arguments.
|
129
|
-
# In particular, sets `@options[:for_engine][:filename]` to the input filename
|
130
|
-
# and requires the appropriate file.
|
131
|
-
#
|
132
|
-
# This is meant to be overridden by subclasses
|
133
|
-
# so they can run their respective programs.
|
134
|
-
def process_result
|
135
|
-
|
136
|
-
unless options[:rails_dir]
|
137
|
-
puts @opts
|
138
|
-
exit
|
139
|
-
end
|
140
|
-
|
141
|
-
options[:cur_dir] = File.dirname(__FILE__)
|
142
|
-
options[:assets_dir] = File.join(options[:cur_dir], '..', '..', 'assets')
|
143
|
-
|
144
|
-
assert_exists('config')
|
145
|
-
assert_exists('vendor')
|
146
|
-
assert_exists('app/helpers')
|
147
|
-
|
148
|
-
ASSET_FILES.each { |f| install_file(f) }
|
149
|
-
|
150
|
-
puts "AnnotationSecurity plugin added to #{options[:rails_dir]}"
|
151
|
-
exit
|
152
|
-
end
|
153
|
-
|
154
|
-
private
|
155
|
-
|
156
|
-
def assert_exists(dir)
|
157
|
-
dir = File.join(options[:rails_dir], dir)
|
158
|
-
unless File.exists?(dir)
|
159
|
-
if options[:force]
|
160
|
-
puts "Creating #{dir}"
|
161
|
-
FileUtils.mkdir_p dir
|
162
|
-
else
|
163
|
-
puts "Directory #{dir} does not exist"
|
164
|
-
exit
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
def install_file(f)
|
170
|
-
orign = File.join(options[:assets_dir], f)
|
171
|
-
dest = File.join(options[:rails_dir], f)
|
172
|
-
|
173
|
-
if File.exists?(dest) && !options[:force]
|
174
|
-
print "File #{dest} already exists, overwrite [y/N]? "
|
175
|
-
return if gets !~ /y/i
|
176
|
-
end
|
177
|
-
|
178
|
-
dir = File.dirname(dest)
|
179
|
-
unless File.exists?(dir)
|
180
|
-
puts "Creating #{dir}"
|
181
|
-
FileUtils.mkdir_p(dir)
|
182
|
-
end
|
183
|
-
|
184
|
-
FileUtils.install(orign, dest)
|
185
|
-
puts "Installed #{dest}"
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
1
|
+
require 'optparse'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
# = lib/annotation_security/exec.rb
|
5
|
+
# This file is borrowed heavily from HAML
|
6
|
+
#
|
7
|
+
|
8
|
+
module AnnotationSecurity
|
9
|
+
module Exec # :nodoc:
|
10
|
+
|
11
|
+
# An abstract class that encapsulates the executable
|
12
|
+
# code for all executables.
|
13
|
+
class Generic # :nodoc:
|
14
|
+
|
15
|
+
# Parsed options
|
16
|
+
def options
|
17
|
+
@options ||= {}
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param args [Array<String>] The command-line arguments
|
21
|
+
def initialize(args)
|
22
|
+
@args = args
|
23
|
+
end
|
24
|
+
|
25
|
+
# Parses the command-line arguments and runs the executable.
|
26
|
+
# Calls `Kernel#exit` at the end, so it never returns.
|
27
|
+
def parse!
|
28
|
+
begin
|
29
|
+
@opts = OptionParser.new(&method(:set_opts))
|
30
|
+
@opts.parse!(@args)
|
31
|
+
|
32
|
+
process_result
|
33
|
+
|
34
|
+
options
|
35
|
+
rescue Exception => e
|
36
|
+
raise e if e.is_a?(SystemExit) || options[:trace]
|
37
|
+
|
38
|
+
$stderr.puts e.message
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
exit 0
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [String] A description of the executable
|
45
|
+
def to_s
|
46
|
+
@opts.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
|
51
|
+
# Tells optparse how to parse the arguments
|
52
|
+
# available for all executables.
|
53
|
+
#
|
54
|
+
# This is meant to be overridden by subclasses
|
55
|
+
# so they can add their own options.
|
56
|
+
#
|
57
|
+
# @param opts [OptionParser]
|
58
|
+
def set_opts(opts)
|
59
|
+
opts.on("--force", "Force command execution, override assets without asking") do
|
60
|
+
options[:force] = true
|
61
|
+
end
|
62
|
+
|
63
|
+
opts.on("--trace", "Shows full stack trace in case of errors") do
|
64
|
+
options[:trace] = true
|
65
|
+
end
|
66
|
+
|
67
|
+
opts.on_tail("-?", "-h", "--help", "Show this message") do
|
68
|
+
puts opts
|
69
|
+
exit
|
70
|
+
end
|
71
|
+
|
72
|
+
opts.on_tail("-v", "--version", "Print version") do
|
73
|
+
puts("AnnotationSecurity 0.01")
|
74
|
+
exit
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Processes the options set by the command-line arguments.
|
79
|
+
#
|
80
|
+
# This is meant to be overridden by subclasses
|
81
|
+
# so they can run their respective programs.
|
82
|
+
def process_result; end
|
83
|
+
end
|
84
|
+
|
85
|
+
# An abstrac class that encapsulates the code
|
86
|
+
# specific to executables.
|
87
|
+
class RailsInstaller < Generic # :nodoc:
|
88
|
+
|
89
|
+
ASSET_FILES = %w{
|
90
|
+
config/initializers/annotation_security.rb
|
91
|
+
config/security/relations.rb
|
92
|
+
config/security/rights.yml
|
93
|
+
app/helpers/annotation_security_helper.rb
|
94
|
+
vendor/plugins/annotation_security/init.rb
|
95
|
+
}
|
96
|
+
|
97
|
+
# @param args [Array<String>] The command-line arguments
|
98
|
+
def initialize(args)
|
99
|
+
super
|
100
|
+
@name = "annosec"
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
# Tells optparse how to parse the arguments.
|
106
|
+
#
|
107
|
+
# This is meant to be overridden by subclasses
|
108
|
+
# so they can add their own options.
|
109
|
+
#
|
110
|
+
# @param opts [OptionParser]
|
111
|
+
def set_opts(opts)
|
112
|
+
opts.banner = <<END
|
113
|
+
Usage: #{@name.downcase} [options]
|
114
|
+
|
115
|
+
Description:
|
116
|
+
Installs the AnnotationSecurity layer into a rails app
|
117
|
+
|
118
|
+
Options:
|
119
|
+
END
|
120
|
+
|
121
|
+
opts.on('--rails RAILS_DIR', "Install AnnotationSecurity layer from the Gem to a Rails project") do |dir|
|
122
|
+
options[:rails_dir] = dir
|
123
|
+
end
|
124
|
+
|
125
|
+
super
|
126
|
+
end
|
127
|
+
|
128
|
+
# Processes the options set by the command-line arguments.
|
129
|
+
# In particular, sets `@options[:for_engine][:filename]` to the input filename
|
130
|
+
# and requires the appropriate file.
|
131
|
+
#
|
132
|
+
# This is meant to be overridden by subclasses
|
133
|
+
# so they can run their respective programs.
|
134
|
+
def process_result
|
135
|
+
|
136
|
+
unless options[:rails_dir]
|
137
|
+
puts @opts
|
138
|
+
exit
|
139
|
+
end
|
140
|
+
|
141
|
+
options[:cur_dir] = File.dirname(__FILE__)
|
142
|
+
options[:assets_dir] = File.join(options[:cur_dir], '..', '..', 'assets')
|
143
|
+
|
144
|
+
assert_exists('config')
|
145
|
+
assert_exists('vendor')
|
146
|
+
assert_exists('app/helpers')
|
147
|
+
|
148
|
+
ASSET_FILES.each { |f| install_file(f) }
|
149
|
+
|
150
|
+
puts "AnnotationSecurity plugin added to #{options[:rails_dir]}"
|
151
|
+
exit
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def assert_exists(dir)
|
157
|
+
dir = File.join(options[:rails_dir], dir)
|
158
|
+
unless File.exists?(dir)
|
159
|
+
if options[:force]
|
160
|
+
puts "Creating #{dir}"
|
161
|
+
FileUtils.mkdir_p dir
|
162
|
+
else
|
163
|
+
puts "Directory #{dir} does not exist"
|
164
|
+
exit
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def install_file(f)
|
170
|
+
orign = File.join(options[:assets_dir], f)
|
171
|
+
dest = File.join(options[:rails_dir], f)
|
172
|
+
|
173
|
+
if File.exists?(dest) && !options[:force]
|
174
|
+
print "File #{dest} already exists, overwrite [y/N]? "
|
175
|
+
return if gets !~ /y/i
|
176
|
+
end
|
177
|
+
|
178
|
+
dir = File.dirname(dest)
|
179
|
+
unless File.exists?(dir)
|
180
|
+
puts "Creating #{dir}"
|
181
|
+
FileUtils.mkdir_p(dir)
|
182
|
+
end
|
183
|
+
|
184
|
+
FileUtils.install(orign, dest)
|
185
|
+
puts "Installed #{dest}"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
189
|
end
|