erp_tech_svcs 3.0.10 → 3.0.11

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.
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
@@ -0,0 +1,53 @@
1
+ class UpgradeSecurity < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ unless table_exists?(:capability_accessors)
5
+ create_table :capability_accessors do |t|
6
+ t.string :capability_accessor_record_type
7
+ t.integer :capability_accessor_record_id
8
+ t.integer :capability_id
9
+ t.timestamps
10
+ end
11
+
12
+ add_index :capability_accessors, :capability_id
13
+ add_index :capability_accessors, [:capability_accessor_record_id, :capability_accessor_record_type], :name => 'capability_accessor_record_index'
14
+ end
15
+
16
+ unless columns(:capabilities).collect {|c| c.name}.include?('scope_query')
17
+ add_column :capabilities, :description, :string
18
+ add_column :capabilities, :capability_resource_type, :string
19
+ add_column :capabilities, :capability_resource_id, :integer
20
+ add_column :capabilities, :scope_type_id, :integer
21
+ add_column :capabilities, :scope_query, :text
22
+
23
+ add_index :capabilities, :scope_type_id
24
+ add_index :capabilities, [:capability_resource_id, :capability_resource_type], :name => 'capability_resource_index'
25
+ end
26
+
27
+ unless table_exists?(:scope_types)
28
+ create_table :scope_types do |t|
29
+ t.string :description
30
+ t.string :internal_identifier
31
+ t.timestamps
32
+ end
33
+
34
+ add_index :scope_types, :internal_identifier
35
+ end
36
+
37
+ unless table_exists?(:parties_security_roles)
38
+ create_table :parties_security_roles, :id => false do |t|
39
+ t.integer :party_id
40
+ t.integer :security_role_id
41
+ end
42
+
43
+ add_index :parties_security_roles, :party_id
44
+ add_index :parties_security_roles, :security_role_id
45
+ end
46
+
47
+ rename_table :roles, :security_roles unless table_exists?(:security_roles)
48
+
49
+ end
50
+
51
+ def self.down
52
+ end
53
+ end
@@ -0,0 +1,274 @@
1
+ class UpgradeSecurity2 < ActiveRecord::Migration
2
+ def self.up
3
+ if table_exists?(:secured_models)
4
+ Website.all.each do |w|
5
+ old_role_iid = "website_#{w.name.underscore.gsub("'","").gsub(",","")}_access"
6
+
7
+ r = SecurityRole.find_by_internal_identifier(old_role_iid)
8
+ unless r.nil?
9
+ r.internal_identifier = w.website_role_iid
10
+ r.save
11
+ end
12
+ end
13
+ instance = ScopeType.create(:description => 'Instance', :internal_identifier => 'instance')
14
+ class_scope_type = ScopeType.create(:description => 'Class', :internal_identifier => 'class')
15
+ ScopeType.create(:description => 'Query', :internal_identifier => 'query')
16
+
17
+ execute('BEGIN TRANSACTION')
18
+ puts "populating parties_security_roles"
19
+ sql =
20
+ "INSERT INTO parties_security_roles (
21
+ party_id,
22
+ security_role_id
23
+ )
24
+ SELECT
25
+ u.party_id AS party_id,
26
+ rsm.role_id AS security_role_id
27
+ FROM secured_models sm
28
+ JOIN roles_secured_models rsm ON sm.id=rsm.secured_model_id
29
+ JOIN users u ON sm.secured_record_id=u.id
30
+ WHERE sm.secured_record_type='User'"
31
+
32
+ execute(sql)
33
+ execute('COMMIT')
34
+
35
+ execute('BEGIN TRANSACTION')
36
+ puts "populating capabilities with secure File Assets"
37
+ sql =
38
+ "INSERT INTO capabilities (
39
+ capability_type_id,
40
+ capability_resource_type,
41
+ capability_resource_id,
42
+ scope_type_id
43
+ )
44
+ SELECT
45
+ c.capability_type_id AS capability_type_id,
46
+ 'FileAsset' AS capability_resource_type,
47
+ cm.capable_model_record_id AS capability_resource_id,
48
+ #{instance.id} AS scope_type_id
49
+ FROM capable_models AS cm
50
+ JOIN capabilities_capable_models AS ccm ON ccm.capable_model_id = cm.id
51
+ JOIN capabilities AS c ON ccm.capability_id = c.id
52
+ JOIN secured_models AS sm ON sm.secured_record_id = c.id AND sm.secured_record_type = 'Capability'
53
+ JOIN roles_secured_models AS rsm ON rsm.secured_model_id = sm.id
54
+ JOIN security_roles AS r ON r.id = rsm.role_id
55
+ WHERE cm.capable_model_record_type = 'FileAsset'"
56
+
57
+ execute(sql)
58
+ execute('COMMIT')
59
+
60
+ view = CapabilityType.find_by_internal_identifier('view')
61
+
62
+ execute('BEGIN TRANSACTION')
63
+ puts "populating capabilities with secure Website Sections"
64
+ sql =
65
+ "INSERT INTO capabilities (
66
+ capability_type_id,
67
+ capability_resource_type,
68
+ capability_resource_id,
69
+ scope_type_id
70
+ )
71
+ SELECT
72
+ #{view.id} AS capability_type_id,
73
+ 'WebsiteSection' AS capability_resource_type,
74
+ ws.id AS capability_resource_id,
75
+ #{instance.id} AS scope_type_id
76
+ FROM secured_models sm
77
+ JOIN roles_secured_models rsm ON sm.id=rsm.secured_model_id
78
+ JOIN website_sections ws ON sm.secured_record_id=ws.id
79
+ WHERE sm.secured_record_type='WebsiteSection'"
80
+
81
+ execute(sql)
82
+ execute('COMMIT')
83
+
84
+ execute('BEGIN TRANSACTION')
85
+ puts "populating capabilities with secure Website Nav Items"
86
+ sql =
87
+ "INSERT INTO capabilities (
88
+ capability_type_id,
89
+ capability_resource_type,
90
+ capability_resource_id,
91
+ scope_type_id
92
+ )
93
+ SELECT
94
+ #{view.id} AS capability_type_id,
95
+ 'WebsiteNavItem' AS capability_resource_type,
96
+ ws.id AS capability_resource_id,
97
+ #{instance.id} AS scope_type_id
98
+ FROM secured_models sm
99
+ JOIN roles_secured_models rsm ON sm.id=rsm.secured_model_id
100
+ JOIN website_sections ws ON sm.secured_record_id=ws.id
101
+ WHERE sm.secured_record_type='WebsiteNavItem'"
102
+
103
+ execute(sql)
104
+ execute('COMMIT')
105
+
106
+ # delete obsolete records: Application, Widget, dupes?
107
+ Capability.where("capability_resource_type IS NULL").delete_all
108
+
109
+ admin = SecurityRole.find_by_internal_identifier('admin')
110
+ website_author = SecurityRole.find_by_internal_identifier('website_author')
111
+ layout_author = SecurityRole.find_by_internal_identifier('layout_author')
112
+ content_author = SecurityRole.find_by_internal_identifier('content_author')
113
+ designer = SecurityRole.find_by_internal_identifier('designer')
114
+ publisher = SecurityRole.find_by_internal_identifier('publisher')
115
+
116
+ # add instance capabilities to roles
117
+ instance_capabilities = Capability.where(:scope_type_id => instance.id).all
118
+ instance_capabilities.each do |c|
119
+ case c.capability_resource_type
120
+ when 'FileAsset'
121
+ admin.add_capability(c)
122
+ website_author.add_capability(c)
123
+ content_author.add_capability(c)
124
+ if c.capability_resource.file_asset_holder_type == 'Website'
125
+ website_role = c.capability_resource.file_asset_holder.role
126
+ website_role.add_capability(c)
127
+ end
128
+ when 'WebsiteSection'
129
+ admin.add_capability(c)
130
+ website_author.add_capability(c)
131
+ website_role = c.capability_resource.website.role
132
+ website_role.add_capability(c)
133
+ when 'WebsiteNavItem'
134
+ admin.add_capability(c)
135
+ website_author.add_capability(c)
136
+ website_role = c.capability_resource.website_nav.website.role
137
+ website_role.add_capability(c)
138
+ end
139
+ end
140
+
141
+ # adding user mgmt capabilities to admin role
142
+ admin.add_capability('create', 'User')
143
+ admin.add_capability('delete', 'User')
144
+ admin.add_capability('edit', 'User')
145
+
146
+ # add knitkit class capabilities to roles
147
+ admin.add_capability('create', 'WebsiteNav')
148
+ admin.add_capability('delete', 'WebsiteNav')
149
+ admin.add_capability('edit', 'WebsiteNav')
150
+
151
+ website_author.add_capability('create', 'WebsiteNav')
152
+ website_author.add_capability('delete', 'WebsiteNav')
153
+ website_author.add_capability('edit', 'WebsiteNav')
154
+
155
+ admin.add_capability('create', 'Website')
156
+ admin.add_capability('delete', 'Website')
157
+ admin.add_capability('edit', 'Website')
158
+ admin.add_capability('import', 'Website')
159
+ admin.add_capability('publish', 'Website')
160
+ admin.add_capability('activate', 'Website')
161
+
162
+ website_author.add_capability('create', 'Website')
163
+ website_author.add_capability('delete', 'Website')
164
+ website_author.add_capability('edit', 'Website')
165
+ website_author.add_capability('import', 'Website')
166
+ publisher.add_capability('publish', 'Website')
167
+ publisher.add_capability('activate', 'Website')
168
+
169
+ admin.add_capability('create', 'WebsiteHost')
170
+ admin.add_capability('delete', 'WebsiteHost')
171
+ admin.add_capability('edit', 'WebsiteHost')
172
+
173
+ website_author.add_capability('create', 'WebsiteHost')
174
+ website_author.add_capability('delete', 'WebsiteHost')
175
+ website_author.add_capability('edit', 'WebsiteHost')
176
+
177
+ admin.add_capability('create', 'WebsiteSection')
178
+ admin.add_capability('delete', 'WebsiteSection')
179
+ admin.add_capability('edit', 'WebsiteSection')
180
+ admin.add_capability('secure', 'WebsiteSection')
181
+ admin.add_capability('unsecure', 'WebsiteSection')
182
+
183
+ website_author.add_capability('create', 'WebsiteSection')
184
+ website_author.add_capability('delete', 'WebsiteSection')
185
+ website_author.add_capability('edit', 'WebsiteSection')
186
+ website_author.add_capability('secure', 'WebsiteSection')
187
+ website_author.add_capability('unsecure', 'WebsiteSection')
188
+
189
+ admin.add_capability('create', 'WebsiteSectionLayout')
190
+ admin.add_capability('edit', 'WebsiteSectionLayout')
191
+
192
+ layout_author.add_capability('create', 'WebsiteSectionLayout')
193
+ layout_author.add_capability('edit', 'WebsiteSectionLayout')
194
+
195
+ admin.add_capability('create', 'Content')
196
+ admin.add_capability('delete', 'Content')
197
+ admin.add_capability('edit', 'Content')
198
+ admin.add_capability('publish', 'Content')
199
+ admin.add_capability('revert_version', 'Content')
200
+ admin.add_capability('add_existing', 'Content')
201
+ admin.add_capability('edit_html', 'Content')
202
+ admin.add_capability('edit_excerpt', 'Content')
203
+
204
+ content_author.add_capability('create', 'Content')
205
+ content_author.add_capability('delete', 'Content')
206
+ content_author.add_capability('edit', 'Content')
207
+ content_author.add_capability('publish', 'Content')
208
+ content_author.add_capability('revert_version', 'Content')
209
+ content_author.add_capability('add_existing', 'Content')
210
+ content_author.add_capability('edit_html', 'Content')
211
+ content_author.add_capability('edit_excerpt', 'Content')
212
+
213
+ admin.add_capability('create', 'WebsiteNavItem')
214
+ admin.add_capability('delete', 'WebsiteNavItem')
215
+ admin.add_capability('edit', 'WebsiteNavItem')
216
+ admin.add_capability('secure', 'WebsiteNavItem')
217
+ admin.add_capability('unsecure', 'WebsiteNavItem')
218
+
219
+ website_author.add_capability('create', 'WebsiteNavItem')
220
+ website_author.add_capability('delete', 'WebsiteNavItem')
221
+ website_author.add_capability('edit', 'WebsiteNavItem')
222
+ website_author.add_capability('secure', 'WebsiteNavItem')
223
+ website_author.add_capability('unsecure', 'WebsiteNavItem')
224
+
225
+ admin.add_capability('view', 'Theme')
226
+ designer.add_capability('view', 'Theme')
227
+
228
+ admin.add_capability('view', 'SiteImageAsset')
229
+ website_author.add_capability('view', 'SiteImageAsset')
230
+ content_author.add_capability('view', 'SiteImageAsset')
231
+
232
+ content_author.add_capability('view', 'GlobalImageAsset')
233
+
234
+ admin.add_capability('view', 'GlobalImageAsset')
235
+ admin.add_capability('upload', 'GlobalImageAsset')
236
+ admin.add_capability('delete', 'GlobalImageAsset')
237
+
238
+ website_author.add_capability('view', 'GlobalImageAsset')
239
+ website_author.add_capability('upload', 'GlobalImageAsset')
240
+ website_author.add_capability('delete', 'GlobalImageAsset')
241
+
242
+ admin.add_capability('view', 'SiteFileAsset')
243
+ website_author.add_capability('view', 'SiteFileAsset')
244
+ content_author.add_capability('view', 'SiteFileAsset')
245
+
246
+ content_author.add_capability('view', 'GlobalFileAsset')
247
+
248
+ admin.add_capability('view', 'GlobalFileAsset')
249
+ admin.add_capability('upload', 'GlobalFileAsset')
250
+ admin.add_capability('delete', 'GlobalFileAsset')
251
+
252
+ website_author.add_capability('view', 'GlobalFileAsset')
253
+ website_author.add_capability('upload', 'GlobalFileAsset')
254
+ website_author.add_capability('delete', 'GlobalFileAsset')
255
+
256
+ admin.add_capability('drag_item', 'WebsiteTree')
257
+ website_author.add_capability('drag_item', 'WebsiteTree')
258
+
259
+ # update capability descriptions
260
+ Capability.all.each do |c|
261
+ c.update_description
262
+ end
263
+
264
+ drop_table :capable_models
265
+ drop_table :capabilities_capable_models
266
+ drop_table :secured_models
267
+ drop_table :roles_secured_models
268
+ remove_column :capabilities, :resource
269
+ end
270
+ end
271
+
272
+ def self.down
273
+ end
274
+ end
@@ -3,18 +3,18 @@ module ErpTechSvcs
3
3
  config.erp_tech_svcs = ErpTechSvcs::Config
4
4
 
5
5
  isolate_namespace ErpTechSvcs
6
-
6
+
7
+ Mime::Type.register "application/pdf", :pdf
8
+
7
9
  ActiveSupport.on_load(:active_record) do
8
- include ErpTechSvcs::Extensions::ActiveRecord::HasRoles
10
+ include ErpTechSvcs::Extensions::ActiveRecord::HasSecurityRoles
9
11
  include ErpTechSvcs::Extensions::ActiveRecord::HasFileAssets
10
- include ErpTechSvcs::Extensions::ActiveRecord::HasCapabilities
12
+ include ErpTechSvcs::Extensions::ActiveRecord::ProtectedByCapabilities
13
+ include ErpTechSvcs::Extensions::ActiveRecord::HasCapabilityAccessors
11
14
  include ErpTechSvcs::Extensions::ActiveRecord::HasRelationalDynamicAttributes
12
15
  end
13
16
 
14
- engine = self
15
- config.to_prepare do
16
- ErpBaseErpSvcs.register_compass_ae_engine(engine)
17
- end
17
+ ErpBaseErpSvcs.register_as_compass_ae_engine(config, self)
18
18
 
19
19
  end
20
20
  end
@@ -0,0 +1,17 @@
1
+ ::ActiveRecord::Base.class_eval do
2
+
3
+ # class method to get superclass of ActiveRecord model
4
+ def self.get_superclass(class_name)
5
+ klass = Module.const_get(class_name)
6
+ while klass.superclass != ::ActiveRecord::Base do
7
+ klass = klass.superclass
8
+ end
9
+ return klass.name
10
+ end
11
+
12
+ # instance method to get superclass of ActiveRecord model
13
+ def get_superclass
14
+ self.class.get_superclass(self.class.name)
15
+ end
16
+
17
+ end
@@ -0,0 +1,131 @@
1
+ module ErpTechSvcs
2
+ module Extensions
3
+ module ActiveRecord
4
+ module HasCapabilityAccessors
5
+
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ def has_capability_accessors
13
+ extend HasCapabilityAccessors::SingletonMethods
14
+ include HasCapabilityAccessors::InstanceMethods
15
+
16
+ has_many :capability_accessors, :as => :capability_accessor_record
17
+ end
18
+
19
+ end
20
+
21
+ module SingletonMethods
22
+
23
+ end
24
+
25
+ module InstanceMethods
26
+
27
+ # method to get capabilities this instance does NOT have
28
+ def capabilities_not
29
+ Capability.joins(:capability_type).
30
+ joins("LEFT JOIN capability_accessors ON capability_accessors.capability_id = capabilities.id AND capability_accessors.capability_accessor_record_type = '#{self.class.name}' AND capability_accessors.capability_accessor_record_id = #{self.id}").
31
+ where("capability_accessors.id IS NULL")
32
+ end
33
+
34
+ def scope_capabilities_not(scope_type_iid)
35
+ scope_type = ScopeType.find_by_internal_identifier(scope_type_iid)
36
+ capabilities_not.where(:scope_type_id => scope_type.id)
37
+ end
38
+
39
+ # method to get only class capabilities this instance does NOT have
40
+ def class_capabilities_not
41
+ scope_capabilities_not('class')
42
+ end
43
+
44
+ def query_capabilities_not
45
+ scope_capabilities_not('query')
46
+ end
47
+
48
+ def capabilities
49
+ Capability.joins(:capability_type).joins(:capability_accessors).
50
+ where(:capability_accessors => { :capability_accessor_record_type => self.class.name, :capability_accessor_record_id => self.id })
51
+ end
52
+
53
+ def scope_capabilities(scope_type_iid)
54
+ scope_type = ScopeType.find_by_internal_identifier(scope_type_iid)
55
+ capabilities.where(:scope_type_id => scope_type.id)
56
+ end
57
+
58
+ # method to get all capabilities for this model
59
+ def all_capabilities
60
+ capabilities
61
+ end
62
+
63
+ # method to get only class capabilities for this model
64
+ def class_capabilities
65
+ scope_capabilities('class')
66
+ end
67
+
68
+ # method to get only query capabilities for this model
69
+ def query_capabilities
70
+ scope_capabilities('query')
71
+ end
72
+
73
+ # method to get only instance capabilities for this model
74
+ def instance_capabilities
75
+ scope_capabilities('instance')
76
+ end
77
+
78
+ # pass in (capability_type_iid, klass) or (capability) object
79
+ def add_capability(*capability)
80
+ capability = capability.first.is_a?(String) ? get_or_create_capability(capability.first, capability.second) : capability.first
81
+ ca = CapabilityAccessor.find_or_create_by_capability_accessor_record_type_and_capability_accessor_record_id_and_capability_id(get_superclass, self.id, capability.id)
82
+ self.reload
83
+ ca
84
+ end
85
+
86
+ def grant_capability(*capability)
87
+ add_capability(*capability)
88
+ end
89
+
90
+ def get_or_create_capability(capability_type_iid, klass)
91
+ capability_type = convert_capability_type(capability_type_iid)
92
+ scope_type = ScopeType.find_by_internal_identifier('class')
93
+ Capability.find_or_create_by_capability_resource_type_and_capability_type_id_and_scope_type_id(klass, capability_type.id, scope_type.id)
94
+ end
95
+
96
+ def get_capability(capability_type_iid, klass)
97
+ capability_type = convert_capability_type(capability_type_iid)
98
+ scope_type = ScopeType.find_by_internal_identifier('class')
99
+ Capability.find_by_capability_resource_type_and_capability_type_id_and_scope_type_id(klass, capability_type.id, scope_type.id)
100
+ end
101
+
102
+ # pass in (capability_type_iid, klass) or (capability) object
103
+ def remove_capability(*capability)
104
+ capability = capability.first.is_a?(String) ? get_or_create_capability(capability.first, capability.second) : capability.first
105
+ ca = capability_accessors.where(:capability_accessor_record_type => get_superclass, :capability_accessor_record_id => self.id, :capability_id => capability.id).first
106
+ ca.destroy unless ca.nil?
107
+ self.reload
108
+ ca
109
+ end
110
+
111
+ def revoke_capability(*capability)
112
+ remove_capability(*capability)
113
+ end
114
+
115
+ def has_capabilities?
116
+ !capability_accessors.empty?
117
+ end
118
+
119
+ private
120
+ def convert_capability_type(type)
121
+ return type if type.is_a?(CapabilityType)
122
+ return nil unless (type.is_a?(String) || type.is_a?(Symbol))
123
+ ct = CapabilityType.find_by_internal_identifier(type.to_s)
124
+ return ct unless ct.nil?
125
+ CapabilityType.create(:internal_identifier => type.to_s, :description => type.to_s.titleize)
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -12,7 +12,7 @@ module ErpTechSvcs
12
12
  extend HasFileAssets::SingletonMethods
13
13
  include HasFileAssets::InstanceMethods
14
14
 
15
- has_many :files, :as => :file_asset_holder, :class_name => 'FileAsset', :dependent => :delete_all, :include => :capabilities
15
+ has_many :files, :as => :file_asset_holder, :class_name => 'FileAsset', :dependent => :destroy, :include => :capabilities
16
16
  end
17
17
  end
18
18
 
@@ -45,6 +45,14 @@ module ErpTechSvcs
45
45
  def templates
46
46
  self.files.where('type = ?', 'Template')
47
47
  end
48
+
49
+ def pdfs
50
+ self.files.where('type = ?', 'Pdf')
51
+ end
52
+
53
+ def xmls
54
+ self.files.where('type = ?', 'XmlFile')
55
+ end
48
56
 
49
57
  end
50
58
  end
@@ -0,0 +1,89 @@
1
+ module ErpTechSvcs
2
+ module Extensions
3
+ module ActiveRecord
4
+ module HasSecurityRoles
5
+
6
+ module Errors
7
+ exceptions = %w[UserDoesNotHaveAccess]
8
+ exceptions.each { |e| const_set(e, Class.new(StandardError)) }
9
+ end
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+
15
+ module ClassMethods
16
+ def has_security_roles
17
+ extend HasSecurityRoles::SingletonMethods
18
+ include HasSecurityRoles::InstanceMethods
19
+ end
20
+ end
21
+
22
+ module SingletonMethods
23
+ end
24
+
25
+ module InstanceMethods
26
+
27
+ def join_parties_security_roles
28
+ "parties_security_roles ON parties_security_roles.security_role_id=security_roles.id"
29
+ end
30
+
31
+ def roles_not
32
+ SecurityRole.joins("LEFT JOIN #{join_parties_security_roles}").where("parties_security_roles.party_id IS NULL")
33
+ end
34
+
35
+ def roles
36
+ self.security_roles
37
+ end
38
+
39
+ def add_role(role)
40
+ role = role.is_a?(SecurityRole) ? role : SecurityRole.find_by_internal_identifier(role.to_s)
41
+ unless self.has_role?(role)
42
+ self.security_roles << role
43
+ self.save
44
+ end
45
+ end
46
+
47
+ def add_roles(*passed_roles)
48
+ passed_roles.flatten!
49
+ passed_roles = passed_roles.first if passed_roles.first.is_a? Array
50
+ passed_roles.each do |role|
51
+ self.add_role(role)
52
+ end
53
+ end
54
+
55
+ def remove_role(role)
56
+ role = role.is_a?(SecurityRole) ? role : SecurityRole.find_by_internal_identifier(role.to_s)
57
+ self.security_roles.delete(role) if has_role?(role)
58
+ end
59
+
60
+ def remove_roles(*passed_roles)
61
+ passed_roles.flatten!
62
+ passed_roles.each do |role|
63
+ self.remove_role(role)
64
+ end
65
+ end
66
+
67
+ def remove_all_roles
68
+ self.security_roles = []
69
+ self.save
70
+ end
71
+
72
+ def has_role?(*passed_roles)
73
+ result = false
74
+ passed_roles.flatten!
75
+ passed_roles.each do |role|
76
+ role_iid = role.is_a?(SecurityRole) ? role.internal_identifier : role.to_s
77
+ self.security_roles.each do |this_role|
78
+ result = true if (this_role.internal_identifier == role_iid)
79
+ break if result
80
+ end
81
+ break if result
82
+ end
83
+ result
84
+ end
85
+ end
86
+ end #HasSecurityRoles
87
+ end #ActiveRecord
88
+ end #Extensions
89
+ end #ErpTechSvcs