erp_tech_svcs 3.0.10 → 3.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/app/models/attribute_type.rb +1 -1
  2. data/app/models/capability.rb +54 -2
  3. data/app/models/capability_accessor.rb +4 -0
  4. data/app/models/extensions/party.rb +1 -0
  5. data/app/models/file_asset.rb +15 -5
  6. data/app/models/group.rb +149 -0
  7. data/app/models/scope_type.rb +5 -0
  8. data/app/models/security_role.rb +46 -0
  9. data/app/models/user.rb +99 -5
  10. data/db/data_migrations/20110109173616_create_capability_scope_types.rb +14 -0
  11. data/db/data_migrations/20121116155018_create_group_relationship_and_role_types.rb +19 -0
  12. data/db/data_migrations/20121130212146_note_capabilities.rb +23 -0
  13. data/db/migrate/20080805000010_base_tech_services.rb +44 -31
  14. data/db/migrate/20121116151510_create_groups.rb +18 -0
  15. data/db/migrate/20121126171612_upgrade_security.rb +53 -0
  16. data/db/migrate/20121126173506_upgrade_security2.rb +274 -0
  17. data/lib/erp_tech_svcs/engine.rb +7 -7
  18. data/lib/erp_tech_svcs/extensions/active_record/base.rb +17 -0
  19. data/lib/erp_tech_svcs/extensions/active_record/has_capability_accessors.rb +131 -0
  20. data/lib/erp_tech_svcs/extensions/active_record/has_file_assets.rb +9 -1
  21. data/lib/erp_tech_svcs/extensions/active_record/has_security_roles.rb +89 -0
  22. data/lib/erp_tech_svcs/extensions/active_record/protected_with_capabilities.rb +203 -0
  23. data/lib/erp_tech_svcs/extensions.rb +4 -2
  24. data/lib/erp_tech_svcs/file_support/manager.rb +1 -1
  25. data/lib/erp_tech_svcs/file_support/s3_manager.rb +3 -3
  26. data/lib/erp_tech_svcs/utils/compass_access_negotiator.rb +29 -24
  27. data/lib/erp_tech_svcs/version.rb +1 -1
  28. data/spec/lib/erp_tech_svcs/extensions/active_record/has_roles_spec.rb +4 -5
  29. data/spec/models/role_spec.rb +2 -2
  30. data/spec/models/secured_model_spec.rb +1 -1
  31. data/spec/models/user_spec.rb +2 -2
  32. metadata +137 -129
  33. data/app/models/capable_model.rb +0 -4
  34. data/app/models/role.rb +0 -17
  35. data/app/models/secured_model.rb +0 -15
  36. data/db/data_migrations/20120109173616_create_download_capability_type.rb +0 -13
  37. data/lib/erp_tech_svcs/extensions/active_record/has_capabilities.rb +0 -152
  38. data/lib/erp_tech_svcs/extensions/active_record/has_roles.rb +0 -130
@@ -1,7 +1,7 @@
1
1
  class AttributeType < ActiveRecord::Base
2
2
  has_many :attribute_values, :dependent => :destroy
3
3
 
4
- validates_uniqueness_of :internal_identifier
4
+ validates_uniqueness_of :internal_identifier, :case_sensitive => false
5
5
  validates :description, :presence => true
6
6
 
7
7
  before_save :update_iid
@@ -1,8 +1,60 @@
1
1
  class Capability < ActiveRecord::Base
2
- has_roles
3
2
 
3
+ belongs_to :scope_type
4
4
  belongs_to :capability_type
5
- has_and_belongs_to_many :capable_models
5
+ belongs_to :capability_resource, :polymorphic => true
6
+ has_many :capability_accessors, :dependent => :destroy
6
7
 
7
8
  alias :type :capability_type
9
+
10
+ after_create :update_description
11
+
12
+ def update_description
13
+ if description.blank?
14
+ desc = "#{capability_type.description} #{capability_resource_type}"
15
+ case scope_type
16
+ when ScopeType.find_by_internal_identifier('class')
17
+ self.description = "#{desc}"
18
+ when ScopeType.find_by_internal_identifier('instance')
19
+ self.description = "#{desc} Instance"
20
+ when ScopeType.find_by_internal_identifier('query')
21
+ self.description = "#{desc} Scope"
22
+ end
23
+ self.save
24
+ end
25
+ end
26
+
27
+ def roles_not
28
+ SecurityRole.joins("LEFT JOIN capability_accessors ON capability_accessors.capability_id = #{self.id}
29
+ AND capability_accessors.capability_accessor_record_type = 'SecurityRole'
30
+ AND capability_accessors.capability_accessor_record_id = security_roles.id").
31
+ where("capability_accessors.id IS NULL")
32
+ end
33
+
34
+ def roles
35
+ SecurityRole.joins(:capability_accessors).where(:capability_accessors => {:capability_id => self.id })
36
+ end
37
+
38
+ def users_not
39
+ User.joins("LEFT JOIN capability_accessors ON capability_accessors.capability_id = #{self.id}
40
+ AND capability_accessors.capability_accessor_record_type = 'User'
41
+ AND capability_accessors.capability_accessor_record_id = users.id").
42
+ where("capability_accessors.id IS NULL")
43
+ end
44
+
45
+ def users
46
+ User.joins(:capability_accessors).where(:capability_accessors => {:capability_id => self.id })
47
+ end
48
+
49
+ def groups_not
50
+ Group.joins("LEFT JOIN capability_accessors ON capability_accessors.capability_id = #{self.id}
51
+ AND capability_accessors.capability_accessor_record_type = 'Group'
52
+ AND capability_accessors.capability_accessor_record_id = groups.id").
53
+ where("capability_accessors.id IS NULL")
54
+ end
55
+
56
+ def groups
57
+ Group.joins(:capability_accessors).where(:capability_accessors => {:capability_id => self.id })
58
+ end
59
+
8
60
  end
@@ -0,0 +1,4 @@
1
+ class CapabilityAccessor < ActiveRecord::Base
2
+ belongs_to :capability_accessor_record, :polymorphic => true
3
+ belongs_to :capability
4
+ end
@@ -1,3 +1,4 @@
1
1
  Party.class_eval do
2
+ has_security_roles
2
3
  has_one :user, :dependent => :destroy
3
4
  end
@@ -43,7 +43,7 @@ class FileAsset < ActiveRecord::Base
43
43
  belongs_to :file_asset_holder, :polymorphic => true
44
44
  instantiates_with_sti
45
45
 
46
- has_capabilities
46
+ protected_with_capabilities
47
47
 
48
48
  #paperclip
49
49
  has_attached_file :data,
@@ -64,7 +64,7 @@ class FileAsset < ActiveRecord::Base
64
64
  validates_attachment_size :data, :less_than => ErpTechSvcs::Config.max_file_size_in_mb.megabytes
65
65
 
66
66
  validates :name, :presence => {:message => 'Name can not be blank'}
67
- validates_uniqueness_of :name, :scope => [:directory]
67
+ validates_uniqueness_of :name, :scope => [:directory], :case_sensitive => false
68
68
  validates_each :directory, :name do |record, attr, value|
69
69
  record.errors.add attr, 'may not contain consequtive dots' if value =~ /\.\./
70
70
  end
@@ -108,7 +108,7 @@ class FileAsset < ActiveRecord::Base
108
108
  end
109
109
  end
110
110
 
111
- def initialize(attributes = {}, options)
111
+ def initialize(attributes = {}, options={})
112
112
  attributes ||= {}
113
113
 
114
114
  base_path = attributes.delete(:base_path)
@@ -127,6 +127,10 @@ class FileAsset < ActiveRecord::Base
127
127
  super attributes.merge(:directory => directory, :name => name, :data => data)
128
128
  end
129
129
 
130
+ def is_secured?
131
+ self.protected_with_capability?('download')
132
+ end
133
+
130
134
  # compass file download url
131
135
  def url
132
136
  "/download/#{self.name}?#{self.directory}"
@@ -139,7 +143,7 @@ class FileAsset < ActiveRecord::Base
139
143
  if ErpTechSvcs::Config.file_storage == :s3
140
144
  file_path = File.join(self.directory,self.name).sub(%r{^/},'')
141
145
  options = {}
142
- options[:expires] = ErpTechSvcs::Config.s3_url_expires_in_seconds if self.has_capabilities?
146
+ options[:expires] = ErpTechSvcs::Config.s3_url_expires_in_seconds if self.is_secured?
143
147
  return file_support.bucket.objects[file_path].url_for(:read, options).to_s
144
148
  else
145
149
  return File.join(Rails.root, self.directory, self.name)
@@ -187,7 +191,7 @@ class FileAsset < ActiveRecord::Base
187
191
 
188
192
  def get_contents
189
193
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)
190
- file_support.get_contents(File.join(self.directory,self.data_file_name))
194
+ file_support.get_contents(File.join(file_support.root, self.directory, self.data_file_name))
191
195
  end
192
196
 
193
197
  def move(new_parent_path)
@@ -256,6 +260,12 @@ class HtmlFile < TextFile
256
260
  self.valid_extensions = %w(.html .HTML)
257
261
  end
258
262
 
263
+ class XmlFile < TextFile
264
+ self.file_type = :xml
265
+ self.content_type = 'text/plain'
266
+ self.valid_extensions = %w(.xml .XML)
267
+ end
268
+
259
269
  class Pdf < TextFile
260
270
  self.file_type = :pdf
261
271
  self.content_type = 'application/pdf'
@@ -0,0 +1,149 @@
1
+ # Security Group
2
+ class Group < ActiveRecord::Base
3
+ has_capability_accessors
4
+
5
+ after_create :create_party
6
+ after_save :save_party
7
+ after_destroy :destroy_party_relationships, :destroy_party
8
+
9
+ has_one :party, :as => :business_party
10
+
11
+ validates_uniqueness_of :description, :case_sensitive => false
12
+
13
+ def self.add(description)
14
+ Group.create(:description => description)
15
+ end
16
+
17
+ # roles this group does NOT have
18
+ def roles_not
19
+ party.roles_not
20
+ end
21
+
22
+ # roles this group has
23
+ def roles
24
+ party.security_roles
25
+ end
26
+
27
+ def has_role?(role)
28
+ role = role.is_a?(SecurityRole) ? role : SecurityRole.find_by_internal_identifier(role.to_s)
29
+ all_roles.include?(role)
30
+ end
31
+
32
+ def add_role(role)
33
+ party.add_role(role)
34
+ end
35
+
36
+ def remove_role(role)
37
+ party.remove_role(role)
38
+ end
39
+
40
+ def remove_all_roles
41
+ party.remove_all_roles
42
+ end
43
+
44
+ def create_party
45
+ pty = Party.new
46
+ pty.description = self.description
47
+ pty.business_party = self
48
+
49
+ pty.save
50
+ self.save
51
+ end
52
+
53
+ def save_party
54
+ self.party.description = self.description
55
+ self.party.save
56
+ end
57
+
58
+ def destroy_party
59
+ if self.party
60
+ self.party.destroy
61
+ end
62
+ end
63
+
64
+ def destroy_party_relationships
65
+ party_relationships.destroy_all
66
+ end
67
+
68
+ # group lives on TO side of relationship
69
+ def party_relationships
70
+ PartyRelationship.where(:party_id_to => self.party.id)
71
+ end
72
+
73
+ def join_party_relationships
74
+ role_type = RoleType.find_by_internal_identifier('group')
75
+ "party_relationships ON party_id_to = #{self.party.id} AND party_id_from = parties.id AND role_type_id_to=#{role_type.id}"
76
+ end
77
+
78
+ def members
79
+ Party.joins("JOIN #{join_party_relationships}")
80
+ end
81
+
82
+ # get users in this group
83
+ def users
84
+ User.joins(:party).joins("JOIN #{join_party_relationships}")
85
+ end
86
+
87
+ # get users not in this group
88
+ def users_not
89
+ User.joins(:party).joins("LEFT JOIN #{join_party_relationships}").where("party_relationships.id IS NULL")
90
+ end
91
+
92
+ # add user to group
93
+ def add_user(user)
94
+ add_party(user.party)
95
+ end
96
+
97
+ # remove user from group
98
+ def remove_user(user)
99
+ remove_party(user.party)
100
+ end
101
+
102
+ def get_relationship(a_party)
103
+ role_type = RoleType.find_by_internal_identifier('group')
104
+ PartyRelationship.where(:party_id_to => self.party.id, :party_id_from => a_party.id, :role_type_id_to => role_type.id)
105
+ end
106
+
107
+ # add party to group
108
+ # group lives on TO side of relationship
109
+ def add_party(a_party)
110
+ # check and see if party is already a member of this group
111
+ rel = get_relationship(a_party).first
112
+ unless rel.nil?
113
+ # if so, return relationship
114
+ return rel
115
+ else
116
+ # if not then build party_relationship
117
+ rt = RelationshipType.find_by_internal_identifier('group_membership')
118
+ pr = PartyRelationship.new
119
+ pr.description = rt.description
120
+ pr.relationship_type = rt
121
+ pr.from_role = RoleType.find_by_internal_identifier('group_member')
122
+ pr.to_role = RoleType.find_by_internal_identifier('group')
123
+ pr.from_party = a_party
124
+ pr.to_party = self.party
125
+ pr.save
126
+ return pr
127
+ end
128
+ end
129
+
130
+ # remove party from group
131
+ # group lives on TO side of relationship
132
+ def remove_party(a_party)
133
+ begin
134
+ get_relationship(a_party).first.destroy
135
+ rescue Exception => e
136
+ Rails.logger.error e.message
137
+ return nil
138
+ end
139
+ end
140
+
141
+ def class_capabilities_to_hash
142
+ class_capabilities.map {|capability|
143
+ { :capability_type_iid => capability.capability_type.internal_identifier,
144
+ :capability_resource_type => capability.capability_resource_type
145
+ }
146
+ }.compact
147
+ end
148
+
149
+ end
@@ -0,0 +1,5 @@
1
+ class ScopeType < ActiveRecord::Base
2
+
3
+ has_many :capabilities
4
+
5
+ end
@@ -0,0 +1,46 @@
1
+ class SecurityRole < ActiveRecord::Base
2
+ acts_as_erp_type
3
+ has_capability_accessors
4
+ has_and_belongs_to_many :parties
5
+
6
+ validates :description, :presence => {:message => 'Description cannot be blank'}
7
+ validates :internal_identifier, :presence => {:message => 'Internal identifier cannot be blank'}
8
+ validates_uniqueness_of :internal_identifier, :case_sensitive => false
9
+ validates_length_of :internal_identifier, :within => 3..100
10
+
11
+ def to_xml(options = {})
12
+ default_only = []
13
+ options[:only] = (options[:only] || []) + default_only
14
+ super(options)
15
+ end
16
+
17
+ # creating method because we only want a getter, not a setter for iid
18
+ def iid
19
+ self.internal_identifier
20
+ end
21
+
22
+ def join_parties_security_roles
23
+ "parties_security_roles ON parties_security_roles.party_id=parties.id AND parties_security_roles.security_role_id=#{self.id}"
24
+ end
25
+
26
+ # users with this role
27
+ def users
28
+ User.joins(:party).joins("JOIN #{join_parties_security_roles}")
29
+ end
30
+
31
+ # users without this role
32
+ def users_not
33
+ User.joins(:party).joins("LEFT JOIN #{join_parties_security_roles}").where("parties_security_roles.security_role_id IS NULL")
34
+ end
35
+
36
+ # groups with this role
37
+ def groups
38
+ Group.joins(:party).joins("JOIN #{join_parties_security_roles}")
39
+ end
40
+
41
+ # groups without this role
42
+ def groups_not
43
+ Group.joins(:party).joins("LEFT JOIN #{join_parties_security_roles}").where("parties_security_roles.security_role_id IS NULL")
44
+ end
45
+
46
+ end
data/app/models/user.rb CHANGED
@@ -1,26 +1,25 @@
1
1
  class User < ActiveRecord::Base
2
+ include ErpTechSvcs::Utils::CompassAccessNegotiator
2
3
  include ActiveModel::Validations
3
4
 
4
5
  attr_accessor :password_validator
5
6
 
6
- has_roles
7
- include ErpTechSvcs::Utils::CompassAccessNegotiator
8
-
9
7
  belongs_to :party
10
8
 
11
9
  attr_accessible :email, :password, :password_confirmation
12
10
  authenticates_with_sorcery!
11
+ has_capability_accessors
13
12
 
14
13
  #password validations
15
14
  validates_confirmation_of :password, :message => "should match confirmation", :if => :password
16
15
  validates :password, :presence => true, :password_strength => true, :if => :password
17
16
 
18
17
  #email validations
19
- validates :email, :presence => {:message => 'Email cannot be blank'}, :uniqueness => true
18
+ validates :email, :presence => {:message => 'Email cannot be blank'}, :uniqueness => {:case_sensitive => false}
20
19
  validates_format_of :email, :with => /\b[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}\z/
21
20
 
22
21
  #username validations
23
- validates :username, :presence => {:message => 'Username cannot be blank'}, :uniqueness => true
22
+ validates :username, :presence => {:message => 'Username cannot be blank'}, :uniqueness => {:case_sensitive => false}
24
23
 
25
24
  #these two methods allow us to assign instance level attributes that are not persisted. These are used for mailers
26
25
  def instance_attributes
@@ -32,4 +31,99 @@ class User < ActiveRecord::Base
32
31
  @instance_attrs[k] = v
33
32
  end
34
33
 
34
+ # roles this user does NOT have
35
+ def roles_not
36
+ party.roles_not
37
+ end
38
+
39
+ # roles this user has
40
+ def roles
41
+ party.security_roles
42
+ end
43
+
44
+ def has_role?(role)
45
+ role = role.is_a?(SecurityRole) ? role : SecurityRole.find_by_internal_identifier(role.to_s)
46
+ all_roles.include?(role)
47
+ end
48
+
49
+ def add_role(role)
50
+ party.add_role(role)
51
+ end
52
+
53
+ def remove_role(role)
54
+ party.remove_role(role)
55
+ end
56
+
57
+ def remove_all_roles
58
+ party.remove_all_roles
59
+ end
60
+
61
+ # user lives on FROM side of relationship
62
+ def group_relationships
63
+ role_type = RoleType.find_by_internal_identifier('group_member')
64
+ PartyRelationship.where(:party_id_from => self.party.id, :role_type_id_from => role_type.id)
65
+ end
66
+
67
+ def join_party_relationships
68
+ role_type = RoleType.find_by_internal_identifier('group_member')
69
+ "party_relationships ON party_id_from = #{self.party.id} AND party_id_to = parties.id AND role_type_id_from=#{role_type.id}"
70
+ end
71
+
72
+ # party records for the groups this user belongs to
73
+ def group_parties
74
+ Party.joins("JOIN #{join_party_relationships}")
75
+ end
76
+
77
+ # groups this user belongs to
78
+ def groups
79
+ Group.joins(:party).joins("JOIN #{join_party_relationships}")
80
+ end
81
+
82
+ # groups this user does NOT belong to
83
+ def groups_not
84
+ Group.joins(:party).joins("LEFT JOIN #{join_party_relationships}").where("party_relationships.id IS NULL")
85
+ end
86
+
87
+ # roles assigned to the groups this user belongs to
88
+ def group_roles
89
+ groups.collect{|g| g.roles }.flatten.uniq
90
+ end
91
+
92
+ # composite roles for this user
93
+ def all_roles
94
+ (group_roles + roles).uniq
95
+ end
96
+
97
+ def group_capabilities
98
+ groups.collect{|r| r.capabilities }.flatten.uniq.compact
99
+ end
100
+
101
+ def role_capabilities
102
+ all_roles.collect{|r| r.capabilities }.flatten.compact
103
+ end
104
+
105
+ def all_capabilities
106
+ (role_capabilities + group_capabilities + capabilities).uniq
107
+ end
108
+
109
+ def group_class_capabilities
110
+ groups.collect{|g| g.class_capabilities }.flatten.uniq.compact
111
+ end
112
+
113
+ def role_class_capabilities
114
+ all_roles.collect{|r| r.class_capabilities }.flatten.uniq.compact
115
+ end
116
+
117
+ def all_class_capabilities
118
+ (role_class_capabilities + group_class_capabilities + class_capabilities).uniq
119
+ end
120
+
121
+ def class_capabilities_to_hash
122
+ all_class_capabilities.map {|capability|
123
+ { :capability_type_iid => capability.capability_type.internal_identifier,
124
+ :capability_resource_type => capability.capability_resource_type
125
+ }
126
+ }.compact
127
+ end
128
+
35
129
  end
@@ -0,0 +1,14 @@
1
+ class CreateCapabilityScopeTypes
2
+
3
+ def self.up
4
+ CapabilityType.create(:internal_identifier => 'download', :description => 'Download') if CapabilityType.where("internal_identifier = 'download'").first.nil?
5
+
6
+ ScopeType.create(:description => 'Instance', :internal_identifier => 'instance') if ScopeType.where("internal_identifier = 'instance'").first.nil?
7
+ ScopeType.create(:description => 'Class', :internal_identifier => 'class') if ScopeType.where("internal_identifier = 'class'").first.nil?
8
+ ScopeType.create(:description => 'Query', :internal_identifier => 'query') if ScopeType.where("internal_identifier = 'query'").first.nil?
9
+ end
10
+
11
+ def self.down
12
+ end
13
+
14
+ end
@@ -0,0 +1,19 @@
1
+ class CreateGroupRelationshipAndRoleTypes
2
+
3
+ def self.up
4
+ #insert data here
5
+ to_role = RoleType.create(:description => 'Security Group', :internal_identifier => 'group')
6
+ from_role = RoleType.create(:description => 'Security Group Member', :internal_identifier => 'group_member')
7
+ RelationshipType.create(:description => 'Security Group Membership',
8
+ :name => 'Group Membership',
9
+ :internal_identifier => 'group_membership',
10
+ :valid_from_role => from_role,
11
+ :valid_to_role => to_role
12
+ )
13
+ end
14
+
15
+ def self.down
16
+ #remove data here
17
+ end
18
+
19
+ end
@@ -0,0 +1,23 @@
1
+ class NoteCapabilities
2
+
3
+ def self.up
4
+ #insert data here
5
+ admin = SecurityRole.find_by_internal_identifier('admin')
6
+ employee = SecurityRole.find_by_internal_identifier('employee')
7
+
8
+ admin.add_capability('create', 'Note')
9
+ admin.add_capability('delete', 'Note')
10
+ admin.add_capability('edit', 'Note')
11
+ admin.add_capability('view', 'Note')
12
+
13
+ employee.add_capability('create', 'Note')
14
+ employee.add_capability('delete', 'Note')
15
+ employee.add_capability('edit', 'Note')
16
+ employee.add_capability('view', 'Note')
17
+ end
18
+
19
+ def self.down
20
+ #remove data here
21
+ end
22
+
23
+ end
@@ -49,9 +49,16 @@ class BaseTechServices < ActiveRecord::Migration
49
49
 
50
50
  end
51
51
 
52
- unless table_exists?(:roles)
52
+ unless table_exists?(:groups)
53
+ create_table :groups do |t|
54
+ t.column :description, :string
55
+ t.timestamps
56
+ end
57
+ end
58
+
59
+ unless table_exists?(:security_roles)
53
60
  # create the roles table
54
- create_table :roles do |t|
61
+ create_table :security_roles do |t|
55
62
  t.column :description, :string
56
63
  t.column :internal_identifier, :string
57
64
  t.column :external_identifier, :string
@@ -139,26 +146,6 @@ class BaseTechServices < ActiveRecord::Migration
139
146
  end
140
147
  end
141
148
 
142
- unless table_exists?(:secured_models)
143
- create_table :secured_models do |t|
144
- t.references :secured_record, :polymorphic => true
145
-
146
- t.timestamps
147
- end
148
- add_index :secured_models, [:secured_record_id, :secured_record_type], :name => 'secured_record_idx'
149
- end
150
-
151
- unless table_exists?(:roles_secured_models)
152
- create_table :roles_secured_models, :id => false do |t|
153
- t.references :secured_model
154
- t.references :role
155
-
156
- t.timestamps
157
- end
158
- add_index :roles_secured_models, :secured_model_id
159
- add_index :roles_secured_models, :role_id
160
- end
161
-
162
149
  unless table_exists?(:file_assets)
163
150
  create_table :file_assets do |t|
164
151
  t.references :file_asset_holder, :polymorphic => true
@@ -219,31 +206,57 @@ class BaseTechServices < ActiveRecord::Migration
219
206
  unless table_exists?(:capabilities)
220
207
  # create the roles table
221
208
  create_table :capabilities do |t|
222
- t.string :resource
209
+ t.string :description
223
210
  t.references :capability_type
211
+ t.string :capability_resource_type
212
+ t.integer :capability_resource_id
213
+ t.integer :scope_type_id
214
+ t.text :scope_query
224
215
  t.timestamps
225
216
  end
226
217
 
227
218
  add_index :capabilities, :capability_type_id
219
+ add_index :capabilities, :scope_type_id
220
+ add_index :capabilities, [:capability_resource_id, :capability_resource_type], :name => 'capability_resource_index'
228
221
  end
229
222
 
230
- unless table_exists?(:capabilities_capable_models)
231
- # create the roles table
232
- create_table :capabilities_capable_models, :id => false do |t|
233
- t.references :capable_model
234
- t.references :capability
223
+ unless table_exists?(:capability_accessors)
224
+ create_table :capability_accessors do |t|
225
+ t.string :capability_accessor_record_type
226
+ t.integer :capability_accessor_record_id
227
+ t.integer :capability_id
228
+ t.timestamps
229
+ end
230
+
231
+ add_index :capability_accessors, :capability_id
232
+ add_index :capability_accessors, [:capability_accessor_record_id, :capability_accessor_record_type], :name => 'capability_accessor_record_index'
233
+ end
234
+
235
+ unless table_exists?(:scope_types)
236
+ create_table :scope_types do |t|
237
+ t.string :description
238
+ t.string :internal_identifier
235
239
  t.timestamps
236
240
  end
237
241
 
238
- add_index :capabilities_capable_models, :capable_model_id
239
- add_index :capabilities_capable_models, :capability_id
242
+ add_index :scope_types, :internal_identifier
243
+ end
244
+
245
+ unless table_exists?(:parties_security_roles)
246
+ create_table :parties_security_roles, :id => false do |t|
247
+ t.integer :party_id
248
+ t.integer :security_role_id
249
+ end
250
+
251
+ add_index :parties_security_roles, :party_id
252
+ add_index :parties_security_roles, :security_role_id
240
253
  end
241
254
 
242
255
  end
243
256
 
244
257
  def self.down
245
258
  # check that each table exists before trying to delete it.
246
- [
259
+ [ :groups,
247
260
  :audit_logs, :sessions, :simple_captcha_data,
248
261
  :capable_models, :capability_types, :capabilities,:capabilities_capable_models,
249
262
  :roles_users, :roles, :audit_log_items, :audit_log_item_types,
@@ -0,0 +1,18 @@
1
+ class CreateGroups < ActiveRecord::Migration
2
+ def self.up
3
+ unless table_exists?(:groups)
4
+ create_table :groups do |t|
5
+ t.column :description, :string
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ [ :groups ].each do |tbl|
13
+ if table_exists?(tbl)
14
+ drop_table tbl
15
+ end
16
+ end
17
+ end
18
+ end