id_please 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -11,6 +11,9 @@ begin
11
11
  gem.homepage = "http://github.com/tastyhat/id_please"
12
12
  gem.authors = ["James Stuart"]
13
13
  gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ gem.add_development_dependency "thoughtbot-factory_girl", ">= 0"
15
+ gem.add_development_dependency "ruby-debug", ">= 0"
16
+ gem.add_dependency "searchlogic"
14
17
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
18
  end
16
19
  Jeweler::GemcutterTasks.new
@@ -21,7 +24,7 @@ end
21
24
  require 'rake/testtask'
22
25
  Rake::TestTask.new(:test) do |test|
23
26
  test.libs << 'lib' << 'test'
24
- test.pattern = 'test/**/test_*.rb'
27
+ test.pattern = 'test/**/*_test.rb'
25
28
  test.verbose = true
26
29
  end
27
30
 
@@ -29,7 +32,7 @@ begin
29
32
  require 'rcov/rcovtask'
30
33
  Rcov::RcovTask.new do |test|
31
34
  test.libs << 'test'
32
- test.pattern = 'test/**/test_*.rb'
35
+ test.pattern = 'test/**/*_test.rb'
33
36
  test.verbose = true
34
37
  end
35
38
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.3.0
data/id_please.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{id_please}
8
- s.version = "0.1.0"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["James Stuart"]
12
- s.date = %q{2010-01-22}
12
+ s.date = %q{2010-01-28}
13
13
  s.description = %q{Access control gem}
14
14
  s.email = %q{tastyhat@jamesstuart.org}
15
15
  s.extra_rdoc_files = [
@@ -31,9 +31,7 @@ Gem::Specification.new do |s|
31
31
  "lib/id_please/model_extensions/for_group.rb",
32
32
  "lib/id_please/model_extensions/for_object.rb",
33
33
  "lib/id_please/model_extensions/for_subject.rb",
34
- "lib/id_please/model_extensions/for_user.rb",
35
- "test/helper.rb",
36
- "test/test_id_please.rb"
34
+ "lib/id_please/model_extensions/for_user.rb"
37
35
  ]
38
36
  s.homepage = %q{http://github.com/tastyhat/id_please}
39
37
  s.rdoc_options = ["--charset=UTF-8"]
@@ -41,8 +39,11 @@ Gem::Specification.new do |s|
41
39
  s.rubygems_version = %q{1.3.5}
42
40
  s.summary = %q{Access control gem for rails}
43
41
  s.test_files = [
44
- "test/helper.rb",
45
- "test/test_id_please.rb"
42
+ "test/id_please_test.rb",
43
+ "test/roles_test.rb",
44
+ "test/support/models.rb",
45
+ "test/support/schema.rb",
46
+ "test/test_helper.rb"
46
47
  ]
47
48
 
48
49
  if s.respond_to? :specification_version then
@@ -51,11 +52,20 @@ Gem::Specification.new do |s|
51
52
 
52
53
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
53
54
  s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
55
+ s.add_development_dependency(%q<thoughtbot-factory_girl>, [">= 0"])
56
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
57
+ s.add_runtime_dependency(%q<searchlogic>, [">= 0"])
54
58
  else
55
59
  s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
60
+ s.add_dependency(%q<thoughtbot-factory_girl>, [">= 0"])
61
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
62
+ s.add_dependency(%q<searchlogic>, [">= 0"])
56
63
  end
57
64
  else
58
65
  s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
66
+ s.add_dependency(%q<thoughtbot-factory_girl>, [">= 0"])
67
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
68
+ s.add_dependency(%q<searchlogic>, [">= 0"])
59
69
  end
60
70
  end
61
71
 
@@ -1,10 +1,14 @@
1
1
  module IdPlease
2
2
  @@config = {
3
3
  :default_role_class_name => 'Role',
4
- :default_user_class_name => 'User',
4
+ :default_subject_class_name => 'User',
5
5
  :default_group_class_name => 'Group',
6
6
  :default_assignment_class_name => 'Assignment',
7
- :default_user_method => :current_user
7
+ :default_group_role => 'member',
8
+ :default_subject_method => :current_user,
9
+ :default_association_name => :assigned_roles,
10
+ :groups_enabled => true,
11
+ :nested_groups => true
8
12
  }
9
13
 
10
14
  mattr_reader :config
@@ -0,0 +1,26 @@
1
+ module IdPlease
2
+ module ModelExtensions
3
+ module ForGroup
4
+ def children(*args)
5
+ options = args.extract_options!
6
+ all_children = _auth_assign_class.role_name_eq(_auth_group_role).role_authorizable_eq(self).all(:include => :subject).collect(&:subject)
7
+
8
+ if _auth_nested_groups == true && options[:nested] != false
9
+ all_children.select { |child| child._auth_is_group == true }.each do |child|
10
+ all_children << child.children
11
+ end
12
+ end
13
+
14
+ all_children.flatten.uniq
15
+ end
16
+
17
+ def has_role!(role_name, object = nil)
18
+ if object && object.kind_of?(self.class) && role_name.to_s == _auth_group_role && self.children.include?(object)
19
+ raise "Attempt to make circular membership loop"
20
+ else
21
+ super
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,123 @@
1
+ module IdPlease
2
+ module ModelExtensions
3
+ module ForObject
4
+ ##
5
+ # Role check.
6
+ #
7
+ # @return [Boolean] Returns true if +subject+ has a role +role_name+ on this object.
8
+ #
9
+ # @param [Symbol,String] role_name Role name
10
+ # @param [Subject] subject Subject to add role for
11
+ # @see Acl9::ModelExtensions::Subject#has_role?
12
+ def accepts_role?(role_name, subject, options = {})
13
+ subject.has_role?(role_name, self, options)
14
+ end
15
+
16
+
17
+
18
+ ##
19
+ # Add role on the object to specified subject.
20
+ #
21
+ # @param [Symbol,String] role_name Role name
22
+ # @param [Subject] subject Subject to add role for
23
+ # @see Acl9::ModelExtensions::Subject#has_role!
24
+ def accepts_role!(role_name, subject)
25
+ subject.has_role!(role_name, self)
26
+ end
27
+
28
+
29
+ def list_subjects_all_roles(*args)
30
+ options = args.extract_options!
31
+
32
+ find_subjects(nil, options)
33
+
34
+ end
35
+
36
+ def list_subjects_for(role_name, *args)
37
+ options = args.extract_options!
38
+
39
+ find_subjects(role_name, options)
40
+ end
41
+
42
+
43
+
44
+ def method_missing(method_sym, *arguments, &block)
45
+ # the first argument is a Symbol, so you need to_s it if you want to pattern match
46
+ if method_sym.to_s =~ /^list_(.+)$/
47
+ list_subjects_for($1.singularize, *arguments)
48
+ else
49
+ super
50
+ end
51
+ end
52
+
53
+
54
+ ##
55
+ # Free specified subject of a role on this object.
56
+ #
57
+ # @param [Symbol,String] role_name Role name
58
+ # @param [Subject] subject Subject to remove role from
59
+ # @see Acl9::ModelExtensions::Subject#has_no_role!
60
+ def accepts_no_role!(role_name, subject)
61
+ subject.has_no_role!(role_name, self)
62
+ end
63
+
64
+ # ##
65
+ # # Are there any roles for the specified +subject+ on this object?
66
+ # #
67
+ # # @param [Subject] subject Subject to query roles
68
+ # # @return [Boolean] Returns true if +subject+ has any roles on this object.
69
+ # # @see Acl9::ModelExtensions::Subject#has_roles_for?
70
+ # def accepts_roles_by?(subject)
71
+ # subject.has_roles_for? self
72
+ # end
73
+ #
74
+ # alias :accepts_role_by? :accepts_roles_by?
75
+ #
76
+ # ##
77
+ # # Which roles does +subject+ have on this object?
78
+ # #
79
+ # # @return [Array<Role>] Role instances, associated both with +subject+ and +object+
80
+ # # @param [Subject] subject Subject to query roles
81
+ # # @see Acl9::ModelExtensions::Subject#roles_for
82
+ # def accepted_roles_by(subject)
83
+ # subject.roles_for self
84
+ # end
85
+
86
+ private
87
+ def get_role(role_name, object)
88
+ _auth_role_class.authorizable_eq(object).name_eq(role_name.to_s).first
89
+ end
90
+
91
+ def find_subjects(role_name = nil, options = {})
92
+ base_subjects = if role_name
93
+ self._auth_assign_class.role_name_eq(role_name.to_s).role_authorizable_eq(self).all(:include => :subject).collect(&:subject).uniq
94
+ else
95
+ self._auth_assign_class.role_authorizable_eq(self).all(:include => :subject).collect(&:subject).uniq
96
+ end
97
+
98
+
99
+ if options[:check_groups] == false
100
+ base_subjects
101
+ else
102
+ to_find = base_subjects.dup
103
+ to_find.select { |subj| subj._auth_is_group }.each do |subj|
104
+ base_subjects << subj.children
105
+ end
106
+
107
+ base_subjects.flatten.uniq
108
+ end
109
+ end
110
+
111
+ protected
112
+
113
+ def _auth_role_class
114
+ self.class._auth_role_class_name.constantize
115
+ end
116
+
117
+ def _auth_assign_class
118
+ self.class._auth_assign_class_name.constantize
119
+ end
120
+
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,181 @@
1
+ module IdPlease
2
+ module ModelExtensions
3
+ module ForSubject
4
+ def in_group!(group)
5
+ raise "Groups must be enabled for this model" unless _auth_groups_enabled
6
+ raise "Object passed in not a group" unless group.kind_of?(_auth_group_class)
7
+
8
+ self.has_role!(_auth_group_role, group)
9
+ end
10
+
11
+ def in_group?(group)
12
+ raise "Groups must be enabled for this model" unless _auth_groups_enabled
13
+ raise "Object passed in not a group" unless group.kind_of?(_auth_group_class)
14
+
15
+ self.has_role?(_auth_group_role, group)
16
+ end
17
+
18
+ def not_in_group!(group)
19
+ raise "Groups must be enabled for this model" unless _auth_groups_enabled
20
+ raise "Object passed in not a group" unless group.kind_of?(_auth_group_class)
21
+
22
+ self.has_no_role!(_auth_group_role, group)
23
+ end
24
+
25
+ def not_in_any_group!
26
+ raise "Groups must be enabled for this model" unless _auth_groups_enabled
27
+
28
+ all_groups.each { |group| self.not_in_group!(group) }
29
+ end
30
+
31
+
32
+ def groups(*args)
33
+ raise "Groups must be enabled for this model" unless _auth_groups_enabled
34
+
35
+ options = args.extract_options!
36
+ all_groups = direct_parent_groups(self)
37
+
38
+ if _auth_nested_groups && options[:nested] != false
39
+ infinite_loop_counter = 25
40
+ to_find = all_groups.dup
41
+
42
+ until to_find.empty? || (infinite_loop_counter -=1) <= 0
43
+ to_find = direct_parent_groups(*to_find)
44
+ all_groups += to_find
45
+ end
46
+
47
+ all_groups.uniq
48
+ else
49
+ all_groups
50
+ end
51
+
52
+ end
53
+
54
+
55
+
56
+ def has_role?(role_name, object = nil, option_hash = {})
57
+ subjects_to_check = option_hash[:check_groups] == false ? [self] : self_and_groups
58
+
59
+ !Role.authorizable_eq(object).name_eq(role_name.to_s).assignments_subject_eq(*subjects_to_check).empty?
60
+ end
61
+
62
+ def has_role!(role_name, object = nil)
63
+ role = get_role(role_name, object)
64
+
65
+ if role.nil?
66
+ role_attrs = case object
67
+ when Class
68
+ { :authorizable_type => object.to_s }
69
+ when nil
70
+ {}
71
+ else
72
+ { :authorizable => object }
73
+ end.merge(:name => role_name.to_s)
74
+
75
+ role = self._auth_assigned_roles.create!(role_attrs)
76
+ else
77
+ unless assigned_to_role?(role)
78
+ self._auth_assigned_roles << role
79
+ end
80
+ end
81
+
82
+ role
83
+ end
84
+
85
+ def has_roles_for?(object)
86
+ !get_assigned_roles_for(object).empty?
87
+ end
88
+
89
+ alias :has_role_for? :has_roles_for?
90
+
91
+ def roles_for(object)
92
+ get_assigned_roles_for(object)
93
+ end
94
+
95
+ def has_no_role!(role_name, object = nil)
96
+ role = get_role(role_name, object)
97
+
98
+ remove_from_role(role)
99
+ end
100
+
101
+ def has_no_roles_for!(object = nil)
102
+ roles_for(object).each { |role| remove_from_role(role) }
103
+ end
104
+
105
+
106
+
107
+ ##
108
+ # Unassign all roles from +self+.
109
+ def has_no_roles!
110
+ roles = self._auth_assigned_roles.clone
111
+ roles.each do |role|
112
+ remove_from_role(role)
113
+ end
114
+ end
115
+
116
+ private
117
+
118
+ def direct_parent_groups(*subjects)
119
+ _auth_role_class.assignments_subject_eq(*subjects).name_eq(_auth_group_role).authorizable_type_eq(_auth_group_class_name).all(:include => :authorizable).collect(&:authorizable)
120
+ end
121
+
122
+ def self_and_groups
123
+ if _auth_groups_enabled
124
+ groups << self
125
+ else
126
+ [self]
127
+ end
128
+ end
129
+
130
+ def remove_from_role(role)
131
+ if role
132
+ self._auth_assigned_roles.delete(role)
133
+
134
+ role.destroy if self._auth_assign_class.role_id_eq(role).empty?
135
+ end
136
+ end
137
+
138
+ def get_role(role_name, object)
139
+ _auth_role_class.authorizable_eq(object).name_eq(role_name.to_s).first
140
+ end
141
+
142
+ def assigned_to_role?(role)
143
+ !!_auth_assign_class.subject_eq(self).role_id_eq(role).first
144
+ end
145
+
146
+ def get_assigned_roles_for(object)
147
+ _auth_role_class.authorizable_eq(object).assignments_subject_eq(self)
148
+ end
149
+
150
+ protected
151
+
152
+
153
+
154
+ def _auth_role_class
155
+ self.class._auth_role_class_name.constantize
156
+ end
157
+
158
+ def _auth_subject_class
159
+ self.class._auth_subject_class_name.constantize
160
+ end
161
+
162
+ def _auth_group_class
163
+ self.class._auth_group_class_name.constantize
164
+ end
165
+
166
+ def _auth_assign_class
167
+ self.class._auth_assign_class_name.constantize
168
+ end
169
+
170
+ def _auth_role_assoc
171
+ self.class._auth_role_assoc_name
172
+ end
173
+
174
+ def _auth_assigned_roles
175
+ send(self._auth_role_assoc)
176
+ end
177
+
178
+
179
+ end
180
+ end
181
+ end
@@ -1,5 +1,3 @@
1
- require File.join(File.dirname(__FILE__), 'model_extensions', 'for_subject')
2
- require File.join(File.dirname(__FILE__), 'model_extensions', 'for_object')
3
1
 
4
2
  module IdPlease
5
3
  module ModelExtensions #:nodoc:
@@ -8,132 +6,232 @@ module IdPlease
8
6
  end
9
7
 
10
8
  module ClassMethods
11
- # Add #has_role? and other role methods to the class.
12
- # Makes a class a auth. subject class.
13
- #
14
- # @param [Hash] options the options for tuning
15
- # @option options [String] :role_class_name (Acl9::config[:default_role_class_name])
16
- # Class name of the role class (e.g. 'AccountRole')
17
- # @option options [String] :join_table_name (Acl9::config[:default_join_table_name])
18
- # Join table name (e.g. 'accounts_account_roles')
19
- # @option options [String] :association_name (Acl9::config[:default_association_name])
20
- # Association name (e.g. ':roles')
21
- # @example
22
- # class User < ActiveRecord::Base
23
- # acts_as_authorization_subject
24
- # end
25
- #
26
- # user = User.new
27
- # user.roles #=> returns Role objects, associated with the user
28
- # user.has_role!(...)
29
- # user.has_no_role!(...)
30
- #
31
- # # other functions from Acl9::ModelExtensions::Subject are made available
32
- #
33
- # @see Acl9::ModelExtensions::Subject
34
- #
35
9
  def acts_as_authorization_subject(options = {})
36
- assoc = options[:association_name] || Acl9::config[:default_association_name]
37
- role = options[:role_class_name] || Acl9::config[:default_role_class_name]
38
- join_table = options[:join_table_name] || Acl9::config[:default_join_table_name] ||
39
- join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(role))
10
+ assoc = options[:association_name] || IdPlease.config[:default_association_name]
11
+ role = options[:role_class_name] || IdPlease.config[:default_role_class_name]
12
+ role_assoc = role.downcase.underscore.to_sym
13
+
14
+ group = options[:group_class_name] || IdPlease.config[:default_group_class_name]
15
+
16
+ assign = options[:assignment_class_name] || IdPlease.config[:default_assignment_class_name]
17
+ assign_table = assign.constantize.table_name
18
+
19
+ #TODO
20
+ groups_enabled = options.has_key?(:groups_enabled) ? options[:groups_enabled] : IdPlease.config[:groups_enabled]
21
+ nested_groups = options.has_key?(:nested_groups) ? options[:nested_groups] : IdPlease.config[:nested_groups]
22
+ group_role = options[:group_role] || IdPlease.config[:default_group_role]
23
+
24
+ has_many assign_table.to_sym, :class_name => assign, :as => :subject, :dependent => :destroy
25
+ has_many assoc, :through => assign_table.to_sym, :source => role_assoc
40
26
 
41
- has_and_belongs_to_many assoc, :class_name => role, :join_table => join_table
42
27
 
43
28
  cattr_accessor :_auth_role_class_name, :_auth_subject_class_name,
44
- :_auth_role_assoc_name
29
+ :_auth_groups_enabled, :_auth_nested_groups,
30
+ :_auth_group_class_name, :_auth_assign_class_name,
31
+ :_auth_role_assoc_name, :_auth_group_role,
32
+ :_auth_is_group
45
33
 
46
34
  self._auth_role_class_name = role
47
35
  self._auth_subject_class_name = self.to_s
36
+ self._auth_assign_class_name = assign
37
+ self._auth_group_class_name = group
48
38
  self._auth_role_assoc_name = assoc
39
+ self._auth_group_role = group_role
40
+ self._auth_groups_enabled = groups_enabled
41
+ self._auth_nested_groups = nested_groups
42
+ self._auth_is_group = false
43
+
49
44
 
50
- include Acl9::ModelExtensions::ForSubject
45
+ include IdPlease::ModelExtensions::ForSubject
51
46
  end
47
+
48
+ def acts_as_authorization_group(options = {})
49
+ assoc = options[:association_name] || IdPlease.config[:default_association_name]
50
+ role = options[:role_class_name] || IdPlease.config[:default_role_class_name]
51
+ role_assoc = role.downcase.underscore.to_sym
52
+
53
+ subject = options[:subject_class_name] || IdPlease.config[:default_subject_class_name]
52
54
 
53
- # Add role query and set methods to the class (making it an auth object class).
54
- #
55
- # @param [Hash] options the options for tuning
56
- # @option options [String] :subject_class_name (Acl9::config[:default_subject_class_name])
57
- # Subject class name (e.g. 'User', or 'Account)
58
- # @option options [String] :role_class_name (Acl9::config[:default_role_class_name])
59
- # Role class name (e.g. 'AccountRole')
60
- # @example
61
- # class Product < ActiveRecord::Base
62
- # acts_as_authorization_object
63
- # end
64
- #
65
- # product = Product.new
66
- # product.accepted_roles #=> returns Role objects, associated with the product
67
- # product.users #=> returns User objects, associated with the product
68
- # product.accepts_role!(...)
69
- # product.accepts_no_role!(...)
70
- # # other functions from Acl9::ModelExtensions::Object are made available
71
- #
72
- # @see Acl9::ModelExtensions::Object
73
- #
74
- def acts_as_authorization_object(options = {})
75
- subject = options[:subject_class_name] || Acl9::config[:default_subject_class_name]
76
- subj_table = subject.constantize.table_name
77
- subj_col = subject.underscore
55
+ assign = options[:assignment_class_name] || IdPlease.config[:default_assignment_class_name]
56
+ assign_table = assign.constantize.table_name
57
+
58
+ #TODO
59
+
60
+ groups_enabled = options.has_key?(:groups_enabled) ? options[:groups_enabled] : IdPlease.config[:groups_enabled]
61
+ nested_groups = options.has_key?(:nested_groups) ? options[:nested_groups] : IdPlease.config[:nested_groups]
62
+ raise "Do not use acts_as_authorization_group if groups are disabled." unless groups_enabled
78
63
 
79
- role = options[:role_class_name] || Acl9::config[:default_role_class_name]
80
- role_table = role.constantize.table_name
81
64
 
82
- sql_tables = <<-EOS
83
- FROM #{subj_table}
84
- INNER JOIN #{role_table}_#{subj_table} ON #{subj_col}_id = #{subj_table}.id
85
- INNER JOIN #{role_table} ON #{role_table}.id = #{role.underscore}_id
86
- EOS
65
+ group_role = options[:group_role] || IdPlease.config[:default_group_role]
87
66
 
88
- sql_where = <<-'EOS'
89
- WHERE authorizable_type = '#{self.class.base_class.to_s}'
90
- AND authorizable_id = #{column_for_attribute(self.class.primary_key).text? ? "'#{id}'": id}
91
- EOS
67
+ has_many assign_table.to_sym, :class_name => assign, :as => :subject, :dependent => :destroy
68
+ has_many assoc, :through => :assignments, :class_name => role, :source => role_assoc
92
69
 
93
- has_many :accepted_roles, :as => :authorizable, :class_name => role, :dependent => :destroy
94
70
 
95
- has_many :"#{subj_table}",
96
- :finder_sql => ("SELECT DISTINCT #{subj_table}.*" + sql_tables + sql_where),
97
- :counter_sql => ("SELECT COUNT(DISTINCT #{subj_table}.id)" + sql_tables + sql_where),
98
- :readonly => true
71
+ cattr_accessor :_auth_role_class_name, :_auth_subject_class_name,
72
+ :_auth_groups_enabled, :_auth_nested_groups,
73
+ :_auth_group_class_name, :_auth_assign_class_name,
74
+ :_auth_role_assoc_name, :_auth_group_role,
75
+ :_auth_is_group
76
+
77
+ self._auth_role_class_name = role
78
+ self._auth_subject_class_name = subject
79
+ self._auth_assign_class_name = assign
80
+ self._auth_group_class_name = self.to_s
81
+ self._auth_role_assoc_name = assoc
82
+ self._auth_groups_enabled = groups_enabled
83
+ self._auth_nested_groups = nested_groups
84
+ self._auth_group_role = group_role
85
+ self._auth_is_group = true
86
+
87
+ include IdPlease::ModelExtensions::ForSubject
88
+ include IdPlease::ModelExtensions::ForGroup
89
+ include IdPlease::ModelExtensions::ForObject
90
+ end
91
+
92
+
99
93
 
100
- include Acl9::ModelExtensions::ForObject
94
+ def acts_as_authorization_object(options = {})
95
+ subject = options[:subject_class_name] || IdPlease.config[:default_subject_class_name]
96
+ subj_table = subject.constantize.table_name
97
+
98
+ role = options[:role_class_name] || IdPlease.config[:default_role_class_name]
99
+ role_table = role.constantize.table_name
100
+
101
+ assign = options[:assignment_class_name] || IdPlease.config[:default_assignment_class_name]
102
+
103
+ groups_enabled = options[:groups_enabled] || IdPlease.config[:groups_enabled]
104
+ nested_groups = options[:nested_groups] || IdPlease.config[:nested_groups]
105
+ group_role = options[:group_role] || IdPlease.config[:group_role]
106
+
107
+
108
+ has_many role_table.to_sym, :dependent => :destroy, :as => :authorizable
109
+
110
+
111
+ cattr_accessor :_auth_role_class_name, :_auth_groups_enabled,
112
+ :_auth_nested_groups, :_auth_assign_class_name,
113
+ :_auth_group_role
114
+
115
+
116
+
117
+ self._auth_role_class_name = role
118
+ self._auth_assign_class_name = assign
119
+ self._auth_group_role = group_role
120
+ self._auth_groups_enabled = groups_enabled
121
+ self._auth_nested_groups = nested_groups
122
+
123
+
124
+ include IdPlease::ModelExtensions::ForObject
101
125
  end
102
126
 
103
- # Make a class an auth role class.
104
- #
105
- # You'll probably never create or use objects of this class directly.
106
- # Various auth. subject and object methods will do that for you
107
- # internally.
108
- #
109
- # @param [Hash] options the options for tuning
110
- # @option options [String] :subject_class_name (Acl9::config[:default_subject_class_name])
111
- # Subject class name (e.g. 'User', or 'Account)
112
- # @option options [String] :join_table_name (Acl9::config[:default_join_table_name])
113
- # Join table name (e.g. 'accounts_account_roles')
114
- #
115
- # @example
116
- # class Role < ActiveRecord::Base
117
- # acts_as_authorization_role
118
- # end
119
- #
120
- # @see Acl9::ModelExtensions::Subject#has_role!
121
- # @see Acl9::ModelExtensions::Subject#has_role?
122
- # @see Acl9::ModelExtensions::Subject#has_no_role!
123
- # @see Acl9::ModelExtensions::Object#accepts_role!
124
- # @see Acl9::ModelExtensions::Object#accepts_role?
125
- # @see Acl9::ModelExtensions::Object#accepts_no_role!
126
127
  def acts_as_authorization_role(options = {})
127
- subject = options[:subject_class_name] || Acl9::config[:default_subject_class_name]
128
- join_table = options[:join_table_name] || Acl9::config[:default_join_table_name] ||
129
- join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(subject))
128
+ validates_presence_of :name
129
+ validates_uniqueness_of :name, :scope => [:authorizable_type, :authorizable_id]
130
+
131
+ subject = options[:subject_class_name] || IdPlease.config[:default_subject_class_name]
132
+
133
+ assign = options[:assignment_class_name] || IdPlease.config[:default_assignment_class_name]
134
+ assign_table = assign.constantize.table_name
135
+
136
+ groups_enabled = options[:groups_enabled] || IdPlease.config[:groups_enabled]
130
137
 
131
- has_and_belongs_to_many subject.demodulize.tableize.to_sym,
132
- :class_name => subject,
133
- :join_table => join_table
138
+ nested_groups = options[:nested_groups] || IdPlease.config[:nested_groups]
139
+ group_role = options[:group_role] || IdPlease.config[:group_role]
134
140
 
141
+ role_table = self.table_name
142
+
143
+ has_many assign_table.to_sym, :dependent => :destroy
135
144
  belongs_to :authorizable, :polymorphic => true
145
+
146
+
147
+ self.named_scope :authorizable_eq, lambda { |*objs|
148
+ obj_hash = {}
149
+ cond_sql = []
150
+ cond_parameters = []
151
+
152
+ if objs.include?(nil) || objs.empty?
153
+ cond_sql << "#{role_table}.authorizable_type IS NULL AND #{role_table}.authorizable_id IS NULL"
154
+ end
155
+
156
+ objs.compact!
157
+
158
+ unless objs.nil? || objs.length == 0
159
+ obj_hash = {}
160
+
161
+ objs.each { |obj|
162
+ obj_hash.has_key?(obj.class) ? obj_hash[obj.class] << obj.id : obj_hash[obj.class] = [obj.id]
163
+ }
164
+
165
+
166
+ obj_hash.each_pair { |class_name, ids|
167
+ cond_sql << "#{role_table}.authorizable_type = '#{class_name}' AND #{role_table}.authorizable_id IN(?)"
168
+ cond_parameters << ids
169
+ }
170
+
171
+ end
172
+
173
+ {:conditions => [cond_sql.join(" OR "), *cond_parameters].compact}
174
+ }
175
+
176
+
177
+ include IdPlease::ModelExtensions::ForRole
178
+
179
+
180
+ cattr_accessor :_auth_role_class_name, :_auth_groups_enabled,
181
+ :_auth_nested_groups, :_auth_assign_class_name
182
+
183
+ self._auth_role_class_name = self.to_s
184
+ self._auth_assign_class_name = assign
185
+
186
+ self._auth_groups_enabled = groups_enabled
187
+ self._auth_nested_groups = nested_groups
188
+
189
+
190
+
136
191
  end
192
+
193
+
194
+ def acts_as_authorization_assignment(options = {})
195
+ role = options[:role_class_name] || IdPlease.config[:default_role_class_name]
196
+ role_assoc = role.downcase.underscore.to_sym
197
+
198
+ assignment_table = self.table_name
199
+
200
+ belongs_to :subject, :polymorphic => true
201
+ #TODO :fix:
202
+ belongs_to role_assoc
203
+
204
+
205
+ self.named_scope :subject_eq, lambda { |*objs|
206
+ obj_hash = {}
207
+ cond_sql = []
208
+ cond_parameters = []
209
+
210
+ if objs.include?(nil) || objs.empty?
211
+ cond_sql << "#{assignment_table}.subject_type IS NULL AND #{assignment_table}.subject_id IS NULL"
212
+ end
213
+
214
+ objs.compact!
215
+
216
+ unless objs.nil? || objs.length == 0
217
+ obj_hash = {}
218
+
219
+ objs.each { |obj|
220
+ obj_hash.has_key?(obj.class) ? obj_hash[obj.class] << obj.id : obj_hash[obj.class] = [obj.id]
221
+ }
222
+
223
+
224
+ obj_hash.each_pair { |class_name, ids|
225
+ cond_sql << "#{assignment_table}.subject_type = '#{class_name}' AND #{assignment_table}.subject_id IN(?)"
226
+ cond_parameters << ids
227
+ }
228
+
229
+ end
230
+ {:conditions => [cond_sql.join(" OR "), *cond_parameters].compact}
231
+
232
+ }
233
+ end
234
+
137
235
  end
138
236
  end
139
237
  end
data/lib/id_please.rb CHANGED
@@ -2,6 +2,11 @@ require 'id_please/config'
2
2
 
3
3
  if defined? ActiveRecord::Base
4
4
  require 'id_please/model_extensions'
5
+ require 'id_please/model_extensions/for_subject'
6
+ require 'id_please/model_extensions/for_subject_with_group'
7
+ require 'id_please/model_extensions/for_object'
8
+ require 'id_please/model_extensions/for_group'
9
+ require 'id_please/model_extensions/for_role'
5
10
  ActiveRecord::Base.send(:include, IdPlease::ModelExtensions)
6
11
  end
7
12
 
File without changes
@@ -0,0 +1,317 @@
1
+ require 'test_helper'
2
+ require 'support/models'
3
+ load 'support/schema.rb'
4
+
5
+ class ActiveSupport::TestCase
6
+ def self.should_handle_basic_role_manipulation(subject_class)
7
+ context "for #{subject_class.to_s}: " do
8
+ setup do
9
+ Role.delete_all
10
+ [subject_class, Foo, Bar, Uuid].each { |c| c.delete_all }
11
+ @subject1 = subject_class.create!
12
+ @subject2 = subject_class.create!
13
+ @foo = Foo.create!
14
+ @bar = Bar.create!
15
+ @uuid = Uuid.create!(:uuid => "C41642EE-2780-0001-189F-17F3101B26E0")
16
+ end
17
+
18
+ should "not have any roles by default" do
19
+ %w(user manager admin owner).each do |role|
20
+ assert_false @subject1.has_role?(role)
21
+ assert_false @subject1.has_role?(role, @foo)
22
+ end
23
+ end
24
+
25
+ context "Given a global role" do
26
+ setup do
27
+ @subject1.has_role!(:admin)
28
+ end
29
+
30
+ should_change "create a role successfully", :by => 1 do
31
+ Role.count
32
+ end
33
+
34
+ should "not distinguish between symbols and strings" do
35
+ assert @subject1.has_role?("admin")
36
+ end
37
+
38
+ should "assign roles to a specific user" do
39
+ assert @subject1.has_role?(:admin)
40
+ assert_false @subject2.has_role?(:admin)
41
+ end
42
+
43
+ should "distinguish between names of roles" do
44
+ assert_false @subject1.has_role?(:manager)
45
+ end
46
+
47
+ should "not count a global role as an object role" do
48
+ assert_false @subject1.has_role?(:admin, @foo)
49
+ assert_false @subject1.has_roles_for?(@foo)
50
+ end
51
+
52
+ should "not let objects accept it" do
53
+ [@foo,@bar].each do |obj|
54
+ assert_false obj.accepts_role?(:admin, @subject1)
55
+ end
56
+ end
57
+
58
+ should "reading roles should not add another role" do
59
+ assert_no_difference "Role.count" do
60
+ @subject1.has_role!(:admin)
61
+ end
62
+ end
63
+
64
+ context "with two users" do
65
+ setup do
66
+ @subject2.has_role!(:admin)
67
+ end
68
+
69
+ should "remove assignments to roles through has_no_role!" do
70
+ @subject1.has_no_role!(:admin)
71
+ assert_false @subject1.has_role?(:admin)
72
+ end
73
+
74
+ should "only delete roles when they have no assignments" do
75
+ assert_no_difference 'Role.count' do
76
+ @subject1.has_no_role!(:admin)
77
+ end
78
+
79
+ assert_difference 'Role.count', -1 do
80
+ @subject2.has_no_role!(:admin)
81
+ end
82
+
83
+ assert_false @subject1.has_role?(:admin)
84
+ assert_false @subject2.has_role?(:admin)
85
+ end
86
+
87
+ end
88
+ end
89
+
90
+ context "Given an object role" do
91
+ setup do
92
+ @subject1.has_role!(:admin, @foo)
93
+ end
94
+
95
+ should_change "create a role successfully", :by => 1 do
96
+ Role.count
97
+ end
98
+
99
+ should "assign roles to a specific user" do
100
+ assert @subject1.has_role?(:admin, @foo)
101
+ assert @subject1.has_roles_for?(@foo)
102
+ assert @subject1.has_role_for?(@foo)
103
+
104
+ roles = @subject1.roles_for(@foo)
105
+ assert_equal 1, roles.length
106
+ assert_equal "admin", roles.first.name
107
+
108
+ assert_false @subject1.has_role?(:manager, @foo)
109
+ assert_false @subject2.has_role?(:admin, @foo)
110
+ assert_false @subject2.has_roles_for?(@foo)
111
+ end
112
+
113
+ should "let the object accept it" do
114
+ assert @foo.accepts_role?(:admin, @subject1)
115
+ assert_false @bar.accepts_role?(:admin, @subject1)
116
+
117
+ @bar.accepts_role!(:admin, @subject1)
118
+ assert @bar.accepts_role?(:admin, @subject1)
119
+
120
+ @bar.accepts_no_role!(:admin, @subject1)
121
+ assert_false @bar.accepts_role?(:admin, @subject1)
122
+ end
123
+
124
+ should "allow the object to list its roles" do
125
+ assert_equal 1, @foo.roles.size
126
+ end
127
+
128
+ should "not count an object role as an global role" do
129
+ assert_false @subject1.has_role?(:admin)
130
+ end
131
+
132
+ should "reuse roles" do
133
+ assert_no_difference 'Role.count' do
134
+ @subject2.has_role!(:admin, @foo)
135
+ end
136
+
137
+ assert_difference 'Role.count', 1 do
138
+ @subject2.has_role!(:manager, @foo)
139
+ end
140
+ end
141
+
142
+ context "with two users" do
143
+ setup do
144
+ @subject1.has_role!(:admin)
145
+ @subject2.has_role!(:admin, @foo)
146
+ @subject1.has_role!(:admin, @bar)
147
+ end
148
+
149
+ should "let objects be able to query their subjects" do
150
+ assert_same_elements @foo.list_subjects_for(:admin), [@subject1, @subject2]
151
+ assert_same_elements @foo.list_subjects_all_roles, [@subject1, @subject2]
152
+ end
153
+
154
+ should "dynamically build methods to query" do
155
+ assert_same_elements @foo.list_subjects_for(:admin), @foo.list_admins
156
+ end
157
+
158
+ should "remove assignments to object roles through has_no_role!" do
159
+ @subject1.has_no_role!(:admin, @foo)
160
+
161
+ assert @subject1.has_role?(:admin)
162
+ assert @subject1.has_role?(:admin, @bar)
163
+ assert_false @subject1.has_role?(:admin, @foo)
164
+ end
165
+
166
+ should "only delete roles when they have no assignments" do
167
+ assert_difference 'Role.count', 0 do
168
+ @subject2.has_no_role!(:admin, @foo)
169
+ end
170
+
171
+ assert_false @subject2.has_role?(:admin)
172
+
173
+ assert_difference 'Role.count', -1 do
174
+ @subject1.has_no_role!(:admin, @foo)
175
+ end
176
+
177
+ assert_false @subject1.has_role?(:admin, @foo)
178
+ end
179
+
180
+ should "delete all roles for a given object with has_no_roles_for!" do
181
+ assert_difference 'Role.count', 1 do
182
+ @subject1.has_role!(:manager, @bar)
183
+ end
184
+
185
+ assert_difference '@subject1.assigned_roles.size', -2 do
186
+ @subject1.has_no_roles_for!(@bar)
187
+ end
188
+
189
+ assert_false @subject1.has_roles_for?(@bar)
190
+ assert @subject1.has_role?(:admin)
191
+ assert @subject1.has_role?(:admin, @foo)
192
+ end
193
+
194
+ should "delete all roles with has_no_roles!" do
195
+ @subject1.has_no_roles!
196
+ assert_equal @subject1.assigned_roles.length, 0
197
+ end
198
+ end
199
+
200
+ end
201
+
202
+ end
203
+ end
204
+ end
205
+
206
+ class RolesTest < ActiveSupport::TestCase
207
+ context "role testing" do
208
+ should_handle_basic_role_manipulation(User)
209
+ should_handle_basic_role_manipulation(Group)
210
+ should_handle_basic_role_manipulation(UserNoGroup)
211
+
212
+ should "models without groups enabled raise errors when group commands are queried" do
213
+ @usernogroup = UserNoGroup.create!
214
+ assert_raises RuntimeError do
215
+ @usernogroup.groups
216
+ end
217
+ end
218
+
219
+ context "group testing: " do
220
+ setup do
221
+ @user1 = User.create!
222
+ @user2 = User.create!
223
+ @user3 = User.create!
224
+ @group1 = Group.create!
225
+ @group2 = Group.create!
226
+ @group3 = Group.create!
227
+ @group4 = Group.create!
228
+ @group5 = Group.create!
229
+
230
+
231
+ @foo = Foo.create!
232
+ @bar = Bar.create!
233
+ end
234
+
235
+ should "be able to assign users to a group" do
236
+ @user1.in_group!(@group1)
237
+ @user2.in_group!(@group1)
238
+ @user1.in_group!(@group2)
239
+
240
+ assert_same_elements @user1.groups, [@group1, @group2]
241
+ assert_same_elements @group1.children, [@user1, @user2]
242
+ assert_equal @group2.children, [@user1]
243
+
244
+ @user1.not_in_group!(@group1)
245
+
246
+ assert_same_elements @user1.groups, [@group2]
247
+ end
248
+
249
+ context "given test users and groups" do
250
+ setup do
251
+ @user1.in_group!(@group1)
252
+ @group1.in_group!(@group2)
253
+ @group2.in_group!(@group4)
254
+
255
+ @user1.in_group!(@group3)
256
+ @user2.in_group!(@group2)
257
+ end
258
+
259
+ should "avoid circularity" do
260
+ @group4.in_group!(@group5)
261
+
262
+ assert_raises RuntimeError do
263
+ @group5.in_group!(@group4)
264
+ end
265
+
266
+ assert_raises RuntimeError do
267
+ @group5.in_group!(@group1)
268
+ end
269
+ end
270
+
271
+ should "not follow meaningless member assignments" do
272
+ @group5.has_role!(:member, @user1)
273
+ assert_equal @group5.children, []
274
+ end
275
+
276
+ should "handle nested groups" do
277
+ assert_same_elements @user1.groups(:nested => false), [@group1, @group3]
278
+ assert_same_elements @user1.groups, [@group1, @group2, @group3, @group4]
279
+ assert_same_elements @user2.groups, [@group2, @group4]
280
+
281
+ assert_same_elements @group4.children, [@group2, @group1, @user1, @user2]
282
+ assert_same_elements @group2.children, [@group1, @user1, @user2]
283
+
284
+ assert @group4.accepts_role?(:member, @user1)
285
+ assert @group2.accepts_role?(:member, @user1)
286
+
287
+ assert_false @group4.accepts_role?(:member, @user1, :check_groups => false)
288
+ end
289
+
290
+ should "check roles based on groups" do
291
+
292
+ assert @user2.has_role?(:member, @group2)
293
+
294
+ @group2.has_role!(:owner, @foo)
295
+
296
+ assert @user2.has_role?(:owner, @foo)
297
+ assert_false @user2.has_role?(:owner, @foo, :check_groups => false)
298
+
299
+ assert @user1.has_role?(:owner, @foo)
300
+ assert_false @user1.has_role?(:owner, @foo, :check_groups => false)
301
+
302
+
303
+ assert_same_elements @foo.list_owners, [@group2, @group1, @user1, @user2]
304
+ assert_same_elements @foo.list_owners(:check_groups => false), [@group2]
305
+
306
+ assert @foo.accepts_role?(:owner, @user1)
307
+ assert_false @foo.accepts_role?(:owner, @user1, :check_groups => false)
308
+ end
309
+
310
+ end
311
+
312
+ end
313
+ end
314
+
315
+ end
316
+
317
+
@@ -0,0 +1,33 @@
1
+
2
+ class Assignment < ActiveRecord::Base
3
+ acts_as_authorization_assignment
4
+ end
5
+
6
+ class Role < ActiveRecord::Base
7
+ acts_as_authorization_role
8
+ end
9
+
10
+ class User < ActiveRecord::Base
11
+ acts_as_authorization_subject
12
+ end
13
+
14
+ class UserNoGroup < ActiveRecord::Base
15
+ acts_as_authorization_subject :groups_enabled => false, :nested_groups => false
16
+ end
17
+
18
+ class Group < ActiveRecord::Base
19
+ acts_as_authorization_group
20
+ end
21
+
22
+ class Foo < ActiveRecord::Base
23
+ acts_as_authorization_object
24
+ end
25
+
26
+ class Bar < ActiveRecord::Base
27
+ acts_as_authorization_object
28
+ end
29
+
30
+ class Uuid < ActiveRecord::Base
31
+ set_primary_key "uuid"
32
+ acts_as_authorization_object
33
+ end
@@ -0,0 +1,36 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table "assignments", :force => true do |t|
3
+ t.integer "subject_id", :null => false
4
+ t.string "subject_type", :limit => 20, :null => false
5
+ t.integer "role_id", :null => false
6
+ t.timestamps
7
+ end
8
+
9
+ create_table "users", :force => true do |t| end
10
+
11
+ create_table "user_no_groups", :force => true do |t| end
12
+
13
+ create_table "roles", :force => true do |t|
14
+ t.string "name", :limit => 50, :null => false
15
+ t.integer "authorizable_id"
16
+ t.string "authorizable_type", :limit => 30
17
+ t.timestamps
18
+ end
19
+
20
+ create_table "groups", :force => true do |t| end
21
+
22
+ create_table "foos", :force => true do |t|
23
+ t.timestamps
24
+ end
25
+
26
+ create_table "bars", :force => true do |t|
27
+ t.timestamps
28
+ end
29
+
30
+
31
+ create_table "uuids", :id => false, :force => true do |t|
32
+ t.string "uuid"
33
+ t.timestamps
34
+ end
35
+
36
+ end
@@ -0,0 +1,44 @@
1
+ require 'rubygems'
2
+
3
+ begin
4
+ require 'ruby-debug'
5
+ rescue LoadError
6
+ puts "ruby-debug not loaded"
7
+ end
8
+
9
+
10
+ require 'active_record'
11
+ require 'active_support'
12
+ require 'active_support/test_case'
13
+
14
+
15
+ gem 'sqlite3-ruby'
16
+ gem 'searchlogic'
17
+ require 'searchlogic'
18
+ require "shoulda"
19
+
20
+
21
+
22
+ ROOT = File.join(File.dirname(__FILE__), '..')
23
+ RAILS_ROOT = ROOT
24
+ RAILS_ENV = "test"
25
+
26
+
27
+ $LOAD_PATH << File.join(ROOT, 'lib')
28
+ $LOAD_PATH << File.join(ROOT, 'lib', 'id_please')
29
+
30
+ require File.join(ROOT, 'lib', 'id_please.rb')
31
+
32
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
33
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
34
+ ActiveRecord::Base.establish_connection(config['test'])
35
+
36
+
37
+
38
+
39
+ module Test::Unit::Assertions
40
+ def assert_false(object, message="")
41
+ assert_equal(false, object, message)
42
+ end
43
+ end
44
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: id_please
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Stuart
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-22 00:00:00 -05:00
12
+ date: 2010-01-28 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,6 +22,36 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "0"
24
24
  version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: thoughtbot-factory_girl
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: ruby-debug
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: searchlogic
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
25
55
  description: Access control gem
26
56
  email: tastyhat@jamesstuart.org
27
57
  executables: []
@@ -47,8 +77,6 @@ files:
47
77
  - lib/id_please/model_extensions/for_object.rb
48
78
  - lib/id_please/model_extensions/for_subject.rb
49
79
  - lib/id_please/model_extensions/for_user.rb
50
- - test/helper.rb
51
- - test/test_id_please.rb
52
80
  has_rdoc: true
53
81
  homepage: http://github.com/tastyhat/id_please
54
82
  licenses: []
@@ -78,5 +106,8 @@ signing_key:
78
106
  specification_version: 3
79
107
  summary: Access control gem for rails
80
108
  test_files:
81
- - test/helper.rb
82
- - test/test_id_please.rb
109
+ - test/id_please_test.rb
110
+ - test/roles_test.rb
111
+ - test/support/models.rb
112
+ - test/support/schema.rb
113
+ - test/test_helper.rb
data/test/helper.rb DELETED
@@ -1,12 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
- require 'active_record'
5
- require 'active_support'
6
-
7
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
- $LOAD_PATH.unshift(File.dirname(__FILE__))
9
- require 'id_please'
10
-
11
- class Test::Unit::TestCase
12
- end
@@ -1,7 +0,0 @@
1
- require 'helper'
2
-
3
- class TestIdPlease < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- # flunk "hey buddy, you should probably rename this file and start testing for real"
6
- end
7
- end