repository-manager 0.0.13 → 0.0.22

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.
@@ -1,6 +1,6 @@
1
- class SharingsMember < ActiveRecord::Base
2
- attr_accessible :can_add, :can_remove if RepositoryManager.protected_attributes?
3
-
4
- belongs_to :member, polymorphic: true
5
- belongs_to :sharing
1
+ class SharingsMember < ActiveRecord::Base
2
+ attr_accessible :can_add, :can_remove if RepositoryManager.protected_attributes?
3
+
4
+ belongs_to :member, polymorphic: true
5
+ belongs_to :sharing
6
6
  end
@@ -0,0 +1,19 @@
1
+ en:
2
+ repository_manager:
3
+ models:
4
+ repo_folder:
5
+ name: Nouveau dossier
6
+ success:
7
+ repo_folder:
8
+ created: Le dossier a été créé avec succès !
9
+ repo_file:
10
+ created: Le fichier a été créé avec succès !
11
+ errors:
12
+ repo_folder:
13
+ not_created: Erreur, le dossier n'a pas été créé !
14
+ repo_file:
15
+ not_created: Erreur, le fichier n'a pas été envoyé !
16
+ form:
17
+ new:
18
+ repo_folder: Créer un dossier
19
+ repo_file: Envoyer un fichier
@@ -0,0 +1,19 @@
1
+ fr:
2
+ repository_manager:
3
+ models:
4
+ repo_folder:
5
+ name: Nouveau dossier
6
+ success:
7
+ repo_folder:
8
+ created: Le dossier a été créé avec succès !
9
+ repo_file:
10
+ created: Le fichier a été créé avec succès !
11
+ errors:
12
+ repo_folder:
13
+ not_created: Erreur, le dossier n'a pas été créé !
14
+ repo_file:
15
+ not_created: Erreur, le fichier n'a pas été envoyé !
16
+ form:
17
+ new:
18
+ repo_folder: Créer un dossier
19
+ repo_file: Envoyer un fichier
@@ -1,32 +1,33 @@
1
- class CreateRepositoryManager < ActiveRecord::Migration
2
-
3
- def change
4
-
5
- create_table :sharings do |t|
6
- t.references :owner, polymorphic: true
7
- t.references :repo_item
8
- t.boolean :can_create, :default => false
9
- t.boolean :can_read, :default => false
10
- t.boolean :can_update, :default => false
11
- t.boolean :can_delete, :default => false
12
- t.boolean :can_share, :default => false
13
- end
14
-
15
- create_table :sharings_members do |t|
16
- t.references :sharing
17
- t.references :member, polymorphic: true
18
- t.boolean :can_add, :default => false
19
- t.boolean :can_remove, :default => false
20
- end
21
-
22
- create_table :repo_items do |t|
23
- t.references :owner, polymorphic: true
24
- t.string :ancestry
25
- t.string :name
26
- t.float :file_size
27
- t.string :content_type
28
- t.string :file
29
- t.string :type
30
- end
31
- end
1
+ class CreateRepositoryManager < ActiveRecord::Migration
2
+
3
+ def change
4
+
5
+ create_table :sharings do |t|
6
+ t.references :owner, polymorphic: true
7
+ t.references :repo_item
8
+ t.boolean :can_create, :default => false
9
+ t.boolean :can_read, :default => false
10
+ t.boolean :can_update, :default => false
11
+ t.boolean :can_delete, :default => false
12
+ t.boolean :can_share, :default => false
13
+ end
14
+
15
+ create_table :sharings_members do |t|
16
+ t.references :sharing
17
+ t.references :member, polymorphic: true
18
+ t.boolean :can_add, :default => false
19
+ t.boolean :can_remove, :default => false
20
+ end
21
+
22
+ create_table :repo_items do |t|
23
+ t.references :owner, polymorphic: true
24
+ t.string :ancestry
25
+ t.integer :ancestry_depth, :default => 0
26
+ t.string :name
27
+ t.float :file_size
28
+ t.string :content_type
29
+ t.string :file
30
+ t.string :type
31
+ end
32
+ end
32
33
  end
@@ -1,33 +1,33 @@
1
- module RepositoryManager #:nodoc:
2
- class InstallGenerator < Rails::Generators::Base
3
- include Rails::Generators::Migration
4
- source_root File.expand_path("../templates", __FILE__)
5
- require 'rails/generators/migration'
6
-
7
- def self.next_migration_number path
8
- unless @prev_migration_nr
9
- @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
10
- else
11
- @prev_migration_nr += 1
12
- end
13
- @prev_migration_nr.to_s
14
- end
15
-
16
- def create_initializer_file
17
- template 'initializer.rb', 'config/initializers/repository_manager.rb'
18
- end
19
-
20
- # all public methods in here will be run in order
21
- #def copy_initializer_file
22
- # copy_file "initializer.rb", "config/initializers/repository_manager_initializer.rb"
23
- #end
24
-
25
- def copy_migrations
26
- migrations = [["20131018214212_create_repository_manager.rb","create_repository_manager.rb"]
27
- ]
28
- migrations.each do |migration|
29
- migration_template "../../../../db/migrate/" + migration[0], "db/migrate/" + migration[1]
30
- end
31
- end
32
- end
1
+ module RepositoryManager #:nodoc:
2
+ class InstallGenerator < Rails::Generators::Base
3
+ include Rails::Generators::Migration
4
+ source_root File.expand_path("../templates", __FILE__)
5
+ require 'rails/generators/migration'
6
+
7
+ def self.next_migration_number path
8
+ unless @prev_migration_nr
9
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
10
+ else
11
+ @prev_migration_nr += 1
12
+ end
13
+ @prev_migration_nr.to_s
14
+ end
15
+
16
+ def create_initializer_file
17
+ template 'initializer.rb', 'config/initializers/repository_manager.rb'
18
+ end
19
+
20
+ # all public methods in here will be run in order
21
+ #def copy_initializer_file
22
+ # copy_file "initializer.rb", "config/initializers/repository_manager_initializer.rb"
23
+ #end
24
+
25
+ def copy_migrations
26
+ migrations = [["20131018214212_create_repository_manager.rb","create_repository_manager.rb"]
27
+ ]
28
+ migrations.each do |migration|
29
+ migration_template "../../../../db/migrate/" + migration[0], "db/migrate/" + migration[1]
30
+ end
31
+ end
32
+ end
33
33
  end
@@ -1,12 +1,12 @@
1
- RepositoryManager.setup do |config|
2
-
3
- # Default repo_item permissions that an object has on the repo_item after a sharing.
4
- config.default_repo_item_permissions = { can_read: true, can_create: false, can_update:false, can_delete:false, can_share: false }
5
-
6
- # Default sharing permissions that an object has when he is added in a sharing.
7
- config.default_sharing_permissions = { can_add: false, can_remove: false }
8
-
9
- # Default path for generating the zip file when a user want to download a folder
10
- # Default is : "download/#{member.class.to_s.underscore}/#{member.id}/#{self.class.to_s.underscore}/#{self.id}/"
11
- #config.default_zip_path = true
1
+ RepositoryManager.setup do |config|
2
+
3
+ # Default repo_item permissions that an object has on the repo_item after a sharing.
4
+ config.default_repo_item_permissions = { can_read: true, can_create: false, can_update:false, can_delete:false, can_share: false }
5
+
6
+ # Default sharing permissions that an object has when he is added in a sharing.
7
+ config.default_sharing_permissions = { can_add: false, can_remove: false }
8
+
9
+ # Default path for generating the zip file when a user want to download a folder
10
+ # Default is : "download/#{member.class.to_s.underscore}/#{member.id}/#{self.class.to_s.underscore}/#{self.id}/"
11
+ #config.default_zip_path = true
12
12
  end
@@ -1,10 +1,10 @@
1
- module RepositoryManager
2
- class RepositoryManagerException < RuntimeError
3
- end
4
-
5
- class AuthorisationException < RepositoryManagerException
6
- end
7
-
8
- class NestedSharingException < RepositoryManagerException
9
- end
1
+ module RepositoryManager
2
+ class RepositoryManagerException < RuntimeError
3
+ end
4
+
5
+ class AuthorisationException < RepositoryManagerException
6
+ end
7
+
8
+ class NestedSharingException < RepositoryManagerException
9
+ end
10
10
  end
@@ -1,453 +1,507 @@
1
- module RepositoryManager
2
- module HasRepository
3
- extend ActiveSupport::Concern
4
-
5
- module ClassMethods
6
- def has_repository(options = {})
7
-
8
- has_many :sharings, through: :sharings_members
9
- has_many :sharings_members, as: :member, dependent: :destroy
10
- has_many :sharings_owners, as: :owner, class_name: 'Sharing'
11
-
12
- # The own repo_items
13
- has_many :repo_items, as: :owner #, dependent: :destroy
14
- # The sharing repo_items
15
- has_many :shared_repo_items, through: :sharings, source: :repo_item, class_name: 'RepoItem'
16
-
17
- #scope :all_repo_items, -> { self.repo_items.shared_repo_items }
18
-
19
- #All repo_items (own and sharings)
20
- #has_many :all_repo_items
21
-
22
- include RepositoryManager::HasRepository::LocalInstanceMethods
23
- end
24
- end
25
-
26
- module LocalInstanceMethods
27
-
28
- # Sharing the repo_item with the members, with the options
29
- # options[:repo_item_permissions] contains :
30
- # <tt>:can_read</tt> - Member can download the repo_item
31
- # <tt>:can_create</tt> - Member can create a new repo_item on it
32
- # <tt>:can_edit</tt> - Member can edit the repo_item
33
- # <tt>:can_delete</tt> - Member can delete the repo_item
34
- # <tt>:can_share</tt> - Member can share the repo_item
35
- # options[:sharing_permissions] contains :
36
- # <tt>:can_add</tt> - Specify if the member can add objects to the sharing
37
- # <tt>:can_remove</tt> - Specify if the member can remove object to the sharing
38
- def share!(repo_item, members, options = {})
39
-
40
- # Nested sharing are not accepted
41
- if !RepositoryManager.accept_nested_sharing
42
- # Check if no other sharing exist in the path
43
- if repo_item.has_nested_sharing?
44
- raise RepositoryManager::NestedSharingException.new("sharing failed. Another sharing already exist on the subtree or an ancestor '#{repo_item.name}'")
45
- end
46
- end
47
-
48
- authorisations = get_authorisations(repo_item)
49
-
50
- # Here we look if the instance has the authorisation for making a sharing
51
- if can_share?(nil, authorisations)
52
-
53
- # We put the default options
54
- repo_item_permissions = RepositoryManager.default_repo_item_permissions
55
- sharing_permissions = RepositoryManager.default_sharing_permissions
56
-
57
- # If there is options, we have to take it
58
- repo_item_permissions = options[:repo_item_permissions] if options[:repo_item_permissions]
59
- sharing_permissions = options[:sharing_permissions] if options[:sharing_permissions]
60
-
61
- # Correct the item permission with accepted permissions
62
- repo_item_permissions = make_repo_item_permissions(repo_item_permissions, authorisations)
63
-
64
- sharing = Sharing.new(repo_item_permissions)
65
- sharing.owner = self
66
-
67
- sharing.add_members(members, sharing_permissions)
68
-
69
- repo_item.sharings << sharing
70
- repo_item.save
71
- sharing
72
- else
73
- # No permission => No sharing
74
- raise RepositoryManager::AuthorisationException.new("sharing failed. You don't have the permission to share the repo_item '#{repo_item.name}'")
75
- end
76
- end
77
-
78
- def share(repo_item, members, options = {})
79
- begin
80
- share!(repo_item, members, options)
81
- rescue RepositoryManager::AuthorisationException, RepositoryManager::NestedSharingException
82
- false
83
- end
84
- end
85
-
86
- # Create a folder with the name (name) in the directory (source_folder)
87
- # Returns the object of the folder created if it is ok
88
- # Returns an Exception if the folder is not created
89
- # RepositoryManagerException if the name already exist
90
- # AuthorisationException if the object don't have the permission
91
- def create_folder!(name = 'New folder', source_folder = nil)
92
- # If he want to create a folder in a directory, we have to check if he have the authorisation
93
- if can_create?(source_folder)
94
-
95
- folder = RepoFolder.new(name: name)
96
- folder.owner = self
97
- folder.save
98
-
99
- # We have to look if it is ok to add the folder here
100
- if source_folder == nil || source_folder.add(folder)
101
- folder
102
- else
103
- # The add didn't works, we delete the folder
104
- folder.destroy
105
- raise RepositoryManager::RepositoryManagerException.new("create_folder failed. The folder name '#{name}' already exist in folder '#{source_folder.name}'")
106
- end
107
- else
108
- raise RepositoryManager::AuthorisationException.new("create_folder failed. You don't have the permission to create a folder in '#{source_folder.name}'")
109
- end
110
- end
111
-
112
- def create_folder(name = 'New folder', source_folder = nil)
113
- begin
114
- create_folder!(name, source_folder)
115
- rescue RepositoryManager::AuthorisationException, RepositoryManager::RepositoryManagerException
116
- false
117
- end
118
- end
119
-
120
- # Delete the repo_item
121
- def delete_repo_item!(repo_item)
122
- if can_delete?(repo_item)
123
- repo_item.destroy
124
- else
125
- raise RepositoryManager::AuthorisationException.new("delete_repo_item failed. You don't have the permission to delete the repo_item '#{repo_item.name}'")
126
- end
127
- end
128
-
129
- def delete_repo_item(repo_item)
130
- begin
131
- delete_repo_item!(repo_item)
132
- rescue RepositoryManager::AuthorisationException
133
- false
134
- end
135
- end
136
-
137
- # Create the file (file) in the directory (source_folder)
138
- # Param file can be a File, or a instance of RepoFile
139
- # Return the object of the file created if it is ok
140
- # Return false if the file is not created (no authorisation)
141
- def create_file!(file, source_folder = nil)
142
- # If he want to create a file in a directory, we have to check if he have the authorisation
143
- if can_create?(source_folder)
144
- if file.class.name == 'File'
145
- repo_file = RepoFile.new
146
- repo_file.file = file
147
- repo_file.owner = self
148
- repo_file.save
149
- elsif file.class.name == 'RepoFile'
150
- repo_file = file
151
- repo_file.owner = self
152
- repo_file.save
153
- end
154
-
155
- # We have to look if it is ok to add the file here
156
- if source_folder == nil || source_folder.add(file)
157
- return repo_file
158
- else
159
- # The add didn't works, we delete the file
160
- file.destroy
161
- raise RepositoryManager::RepositoryManagerException.new("create_file failed. The file '#{name}' already exist in folder '#{source_folder.name}'")
162
- end
163
- else
164
- #raise "create_file failed. You don't have the permission to create a file in the folder '#{source_folder.name}'"
165
- raise RepositoryManager::AuthorisationException.new("create_file failed. The file '#{name}' already exist in folder '#{source_folder.name}'")
166
- end
167
- end
168
-
169
- def create_file(file, source_folder = nil)
170
- begin
171
- create_file!(file, source_folder)
172
- rescue RepositoryManager::AuthorisationException, RepositoryManager::RepositoryManagerException
173
- false
174
- end
175
- end
176
-
177
- # Gets the repo authorisations
178
- # Return false if the entity has not the authorisation to share this rep
179
- # Return true if the entity can share this rep with all the authorisations
180
- # Return an Array if the entity can share but with restriction
181
- # Return true if the repo_item is nil (he as all authorisations on his own rep)
182
- def get_authorisations(repo_item = nil)
183
- # If repo_item is nil, he can do what he want
184
- return true if repo_item == nil
185
-
186
- # If the member is the owner, he can do what he want !
187
- if repo_item.owner == self
188
- # You can do what ever you want :)
189
- return true
190
- # Find if a sharing of this rep exist for the self instance or it ancestors
191
- else
192
- path_ids = repo_item.path_ids
193
- # Check the nearest sharing if it exist
194
- if s = self.sharings.where(repo_item_id: path_ids).last
195
- return {can_share: s.can_share, can_read: s.can_read, can_create: s.can_create, can_update: s.can_update, can_delete: s.can_delete}
196
- end
197
- end
198
- # Else, false
199
- return false
200
- end
201
-
202
- # Download a repo_item if the object can_read it
203
- # If it is a file, he download the file
204
- # If it is a folder, we check witch repo_item is in it, and witch he can_read
205
- # We zip all the content that the object has access.
206
- # options
207
- # :path => 'path/to/zip'
208
- def download!(repo_item, options = {})
209
- if can_download?(repo_item)
210
- path = options[:path] if options[:path]
211
-
212
- repo_item.download({object: self, path: path})
213
- else
214
- raise RepositoryManager::AuthorisationException.new("download failed. You don't have the permission to download the repo_item '#{repo_item.name}'")
215
- end
216
- end
217
-
218
- def download(repo_item, options = {})
219
- begin
220
- download!(repo_item, options)
221
- rescue RepositoryManager::AuthorisationException
222
- false
223
- end
224
- end
225
-
226
- # Move the repo_item in the target_folder
227
- def move_repo_item!(repo_item, target_folder)
228
- unless can_delete?(repo_item)
229
- raise RepositoryManager::AuthorisationException.new("move repo_item failed. You don't have the permission to delete the repo_item '#{repo_item.name}'")
230
- end
231
- unless can_create?(target_folder)
232
- raise RepositoryManager::AuthorisationException.new("move repo_item failed. You don't have the permission to create in the target_folder '#{target_folder.name}'")
233
- end
234
- # If it has the permission, we move the repo_item in the target_folder
235
- repo_item.move(target_folder)
236
- end
237
-
238
- def move_repo_item(repo_item, target_folder)
239
- begin
240
- move_repo_item!(repo_item, target_folder)
241
- rescue RepositoryManager::AuthorisationException
242
- false
243
- end
244
- end
245
-
246
- # Delete the download folder of the user
247
- def delete_download_path
248
- FileUtils.rm_rf(self.get_default_download_path())
249
- end
250
-
251
- #Return the authorisations of the sharing (can_add, can_remove)
252
- def get_sharing_authorisations(sharing)
253
- sharing.get_authorisations(self)
254
- end
255
-
256
- # Return true if you can share the repo, else false
257
- # You can give the authorisations or the repo_item as params
258
- def can_share?(repo_item, authorisations = nil)
259
- can_do?('share', repo_item, authorisations)
260
- end
261
-
262
- # Return true if you can read the repo, else false
263
- def can_read?(repo_item, authorisations = nil)
264
- can_do?('read', repo_item, authorisations)
265
- end
266
-
267
- # Return true if you can download the repo, else false
268
- # Read = Download for the moment
269
- def can_download?(repo_item, authorisations = nil)
270
- can_do?('read', repo_item, authorisations)
271
- end
272
-
273
- # Return true if you can create in the repo, false else
274
- def can_create?(repo_item, authorisations = nil)
275
- can_do?('create', repo_item, authorisations)
276
- end
277
-
278
- # Returns true if you can edit the repo, false else
279
- def can_update?(repo_item, authorisations = nil)
280
- can_do?('update', repo_item, authorisations)
281
- end
282
-
283
- # Returns true if you can delete the repo, false else
284
- def can_delete?(repo_item, authorisations = nil)
285
- can_do?('delete', repo_item, authorisations)
286
- end
287
-
288
- ## Returns true if it exist a sharing in the ancestors of descendant_ids of the repo_item (without itself)
289
- #def has_sharing?(repo_item)
290
- # # An array with the ids of all ancestors and descendants
291
- # ancestor_and_descendant_ids = []
292
- # ancestor_and_descendant_ids << repo_item.descendant_ids if !repo_item.descendant_ids.empty?
293
- # ancestor_and_descendant_ids << repo_item.ancestor_ids if !repo_item.ancestor_ids.empty?
294
- #
295
- # # If it is a sharing, it returns true
296
- # if self.sharings.where(repo_item_id: ancestor_and_descendant_ids).count > 0
297
- # true
298
- # else
299
- # false
300
- # end
301
- #
302
- #end
303
-
304
- # Return true if you can add a member in this sharing, false else
305
- def can_add_to?(sharing)
306
- can_do_to?('add', sharing)
307
- end
308
-
309
- # Return true if you can remove a member in this sharing, false else
310
- def can_remove_from?(sharing)
311
- can_do_to?('remove', sharing)
312
- end
313
-
314
- # You can here add new members in the sharing
315
- # Param member could be an object or an array of object
316
- def add_members_to!(sharing, members, options = RepositoryManager.default_sharing_permissions)
317
- authorisations = get_sharing_authorisations(sharing)
318
- if can_add_to?(sharing)
319
- sharing_permissions = make_sharing_permissions(options, authorisations)
320
- sharing.add_members(members, sharing_permissions)
321
- else
322
- raise RepositoryManager::AuthorisationException.new("add members failed. You don't have the permission to add a member in this sharing")
323
- end
324
- end
325
-
326
- def add_members_to(sharing, members, options = RepositoryManager.default_sharing_permissions)
327
- begin
328
- add_members_to!(sharing, members, options = RepositoryManager.default_sharing_permissions)
329
- rescue RepositoryManager::AuthorisationException
330
- false
331
- end
332
- end
333
-
334
- # You can here add new members in the sharing
335
- # Param member could be an object or an array of object
336
- def remove_members_from!(sharing, members)
337
- if can_remove_from?(sharing)
338
- sharing.remove_members(members)
339
- else
340
- raise RepositoryManager::AuthorisationException.new("remove members failed. You don't have the permission to remove a member on this sharing")
341
- end
342
- end
343
-
344
- def remove_members_from(sharing, members)
345
- begin
346
- remove_members_from!(sharing, members)
347
- rescue RepositoryManager::AuthorisationException
348
- false
349
- end
350
- end
351
-
352
- # Get the download path of the member
353
- def get_default_download_path(prefix = 'download/')
354
- "#{prefix}#{self.class.to_s.underscore}/#{self.id}/"
355
- end
356
-
357
- private
358
-
359
- # Return if you can do or not this action in the sharing
360
- def can_do_to?(what, sharing, authorisations = nil)
361
- if authorisations == nil
362
- authorisations = sharing.get_authorisations(self)
363
- end
364
- case what
365
- when 'add'
366
- authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_add] == true)
367
- when 'remove'
368
- authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_remove] == true)
369
- end
370
- end
371
-
372
- # Return if you can do or not this action (what)
373
- def can_do?(what, repo_item, authorisations = nil)
374
- # If we pass no authorisations we have to get it
375
- if authorisations == nil
376
- authorisations = get_authorisations(repo_item)
377
- end
378
-
379
- case what
380
- when 'read'
381
- authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_read] == true)
382
- when 'delete'
383
- if RepositoryManager.accept_nested_sharing
384
- # TODO implement to look if he can delete all the folder
385
- else
386
- authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_delete] == true)
387
- end
388
- when 'update'
389
- authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_update] == true)
390
- when 'share'
391
- if RepositoryManager.accept_nested_sharing
392
- # TODO implement to look if he can delete all the folder
393
- else
394
- authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_share] == true)
395
- end
396
- when 'create'
397
- if RepositoryManager.accept_nested_sharing
398
- # TODO implement to look if he can delete all the folder
399
- else
400
- authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_create] == true)
401
- end
402
- else
403
- false
404
- end
405
-
406
- end
407
-
408
- # Correct the repo_item_permissions with the authorisations
409
- def make_repo_item_permissions(wanted_permissions, authorisations)
410
- # If it is an array, we have restriction in the permissions
411
- if authorisations.kind_of?(Hash) && wanted_permissions
412
- # Built the sharing with the accepted permissions
413
- # We remove the permission if we can't sharing it
414
- if wanted_permissions[:can_read] == true && authorisations[:can_read] == false
415
- wanted_permissions[:can_read] = false
416
- end
417
- if wanted_permissions[:can_create] == true && authorisations[:can_create] == false
418
- wanted_permissions[:can_create] = false
419
- end
420
- if wanted_permissions[:can_update] == true && authorisations[:can_update] == false
421
- wanted_permissions[:can_update] = false
422
- end
423
- if wanted_permissions[:can_delete] == true && authorisations[:can_delete] == false
424
- wanted_permissions[:can_delete] = false
425
- end
426
- if wanted_permissions[:can_share] == true && authorisations[:can_share] == false
427
- wanted_permissions[:can_share] = false
428
- end
429
- end
430
- return wanted_permissions
431
- end
432
-
433
- # Correct the sharing_permissions with the authorisations
434
- def make_sharing_permissions(wanted_permissions, authorisations)
435
- # If it is an array, we have restriction in the permissions
436
- if authorisations.kind_of?(Hash) && wanted_permissions
437
- # Built the sharing with the accepted permissions
438
- # We remove the permission if we can't share it
439
- if wanted_permissions[:can_add] == true && authorisations[:can_add] == false
440
- wanted_permissions[:can_add] = false
441
- end
442
- if wanted_permissions[:can_remove] == true && authorisations[:can_remove] == false
443
- wanted_permissions[:can_remove] = false
444
- end
445
- end
446
- return wanted_permissions
447
- end
448
-
449
- end
450
- end
451
- end
452
-
1
+ module RepositoryManager
2
+ module HasRepository
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def has_repository(options = {})
7
+
8
+ has_many :sharings, through: :sharings_members
9
+ has_many :sharings_members, as: :member, dependent: :destroy
10
+ has_many :sharings_owners, as: :owner, class_name: 'Sharing'
11
+
12
+ # The own repo_items
13
+ has_many :repo_items, as: :owner #, dependent: :destroy
14
+ # The sharing repo_items
15
+ has_many :shared_repo_items, through: :sharings, source: :repo_item, class_name: 'RepoItem'
16
+
17
+ #scope :all_repo_items, -> { self.repo_items.shared_repo_items }
18
+
19
+ #All repo_items (own and sharings)
20
+ #has_many :all_repo_items
21
+
22
+ include RepositoryManager::HasRepository::LocalInstanceMethods
23
+ end
24
+ end
25
+
26
+ module LocalInstanceMethods
27
+
28
+ # Sharing the repo_item with the members, with the options
29
+ # options[:repo_item_permissions] contains :
30
+ # <tt>:can_read</tt> - Member can download the repo_item
31
+ # <tt>:can_create</tt> - Member can create a new repo_item on it
32
+ # <tt>:can_edit</tt> - Member can edit the repo_item
33
+ # <tt>:can_delete</tt> - Member can delete the repo_item
34
+ # <tt>:can_share</tt> - Member can share the repo_item
35
+ # options[:sharing_permissions] contains :
36
+ # <tt>:can_add</tt> - Specify if the member can add objects to the sharing
37
+ # <tt>:can_remove</tt> - Specify if the member can remove object to the sharing
38
+ def share!(repo_item, members, options = {})
39
+
40
+ # Nested sharing are not accepted
41
+ if !RepositoryManager.accept_nested_sharing
42
+ # Check if no other sharing exist in the path
43
+ if repo_item.has_nested_sharing?
44
+ raise RepositoryManager::NestedSharingException.new("sharing failed. Another sharing already exist on the subtree or an ancestor '#{repo_item.name}'")
45
+ end
46
+ end
47
+
48
+ authorisations = get_authorisations(repo_item)
49
+
50
+ # Here we look if the instance has the authorisation for making a sharing
51
+ if can_share?(nil, authorisations)
52
+
53
+ # We put the default options
54
+ repo_item_permissions = RepositoryManager.default_repo_item_permissions
55
+ sharing_permissions = RepositoryManager.default_sharing_permissions
56
+
57
+ # If there is options, we have to take it
58
+ repo_item_permissions = options[:repo_item_permissions] if options[:repo_item_permissions]
59
+ sharing_permissions = options[:sharing_permissions] if options[:sharing_permissions]
60
+
61
+ # Correct the item permission with accepted permissions
62
+ repo_item_permissions = make_repo_item_permissions(repo_item_permissions, authorisations)
63
+
64
+ sharing = Sharing.new(repo_item_permissions)
65
+ sharing.owner = self
66
+
67
+ sharing.add_members(members, sharing_permissions)
68
+
69
+ repo_item.sharings << sharing
70
+ repo_item.save
71
+ sharing
72
+ else
73
+ # No permission => No sharing
74
+ raise RepositoryManager::AuthorisationException.new("sharing failed. You don't have the permission to share the repo_item '#{repo_item.name}'")
75
+ end
76
+ end
77
+
78
+ def share(repo_item, members, options = {})
79
+ begin
80
+ share!(repo_item, members, options)
81
+ rescue RepositoryManager::AuthorisationException, RepositoryManager::NestedSharingException
82
+ false
83
+ end
84
+ end
85
+
86
+ # Create a folder with the name (name) in the directory (source_folder)
87
+ # Returns the object of the folder created if it is ok
88
+ # Returns an Exception if the folder is not created
89
+ # RepositoryManagerException if the name already exist
90
+ # AuthorisationException if the object don't have the permission
91
+ def create_folder!(name = '', source_folder = nil)
92
+ # If he want to create a folder in a directory, we have to check if he have the authorisation
93
+ if can_create?(source_folder)
94
+
95
+ folder = RepoFolder.new
96
+ if name == ''
97
+ folder.name = default_folder_name(source_folder)
98
+ else
99
+ folder.name = name
100
+ end
101
+ folder.owner = self
102
+
103
+ # Soit il a une source_folder, donc on l'ajoute et on le sauve et ça fonctionne pas => ERREUR
104
+ # Soit il n'a pas de source_folder et le save ne va pas => ERREUR
105
+ unless (folder.save && source_folder && source_folder.add(folder)) || (!source_folder && folder.save)
106
+ folder.destroy
107
+ raise RepositoryManager::RepositoryManagerException.new("create_folder failed. Can\'t save the folder '#{name}'.")
108
+ end
109
+ else
110
+ raise RepositoryManager::AuthorisationException.new("create_folder failed. You don't have the permission to create a folder in '#{source_folder.name}'")
111
+ end
112
+ folder
113
+ end
114
+
115
+ def create_folder(name = '', source_folder = nil)
116
+ begin
117
+ create_folder!(name, source_folder)
118
+ rescue RepositoryManager::AuthorisationException, RepositoryManager::RepositoryManagerException
119
+ false
120
+ end
121
+ end
122
+
123
+ # Delete the repo_item
124
+ def delete_repo_item!(repo_item)
125
+ if can_delete?(repo_item)
126
+ repo_item.destroy
127
+ else
128
+ raise RepositoryManager::AuthorisationException.new("delete_repo_item failed. You don't have the permission to delete the repo_item '#{repo_item.name}'")
129
+ end
130
+ end
131
+
132
+ def delete_repo_item(repo_item)
133
+ begin
134
+ delete_repo_item!(repo_item)
135
+ rescue RepositoryManager::AuthorisationException
136
+ false
137
+ end
138
+ end
139
+
140
+ # Create the file (file) in the directory (source_folder)
141
+ # Param file can be a File, or a instance of RepoFile
142
+ # Return the object of the file created if it is ok
143
+ # Return false if the file is not created (no authorisation)
144
+ def create_file!(file, source_folder = nil)
145
+ # If he want to create a file in a directory, we have to check if he have the authorisation
146
+ if can_create?(source_folder)
147
+ if file.class.name == 'RepoFile'
148
+ repo_file = file
149
+ repo_file.owner = self
150
+ unless repo_file.save
151
+ raise RepositoryManager::RepositoryManagerException.new("create_file failed. The file '#{name}' can't be save")
152
+ end
153
+ else
154
+ repo_file = RepoFile.new
155
+ repo_file.file = file
156
+ repo_file.owner = self
157
+ unless repo_file.save
158
+ raise RepositoryManager::RepositoryManagerException.new("create_file failed. The file '#{name}' can't be save")
159
+ end
160
+ end
161
+
162
+ # We have to look if it is ok to add the file here
163
+ if source_folder == nil || source_folder.add(file)
164
+ return repo_file
165
+ else
166
+ # The add didn't works, we delete the file
167
+ file.destroy
168
+ raise RepositoryManager::RepositoryManagerException.new("create_file failed. The file '#{name}' already exist in folder '#{source_folder.name}'")
169
+ end
170
+ else
171
+ #raise "create_file failed. You don't have the permission to create a file in the folder '#{source_folder.name}'"
172
+ raise RepositoryManager::AuthorisationException.new("create_file failed. The file '#{name}' already exist in folder '#{source_folder.name}'")
173
+ end
174
+ end
175
+
176
+ def create_file(file, source_folder = nil)
177
+ begin
178
+ create_file!(file, source_folder)
179
+ rescue RepositoryManager::AuthorisationException, RepositoryManager::RepositoryManagerException
180
+ false
181
+ end
182
+ end
183
+
184
+ # Gets the repo authorisations
185
+ # Return false if the entity has not the authorisation to share this rep
186
+ # Return true if the entity can share this rep with all the authorisations
187
+ # Return an Array if the entity can share but with restriction
188
+ # Return true if the repo_item is nil (he as all authorisations on his own rep)
189
+ def get_authorisations(repo_item = nil)
190
+ # If repo_item is nil, he can do what he want
191
+ return true if repo_item == nil
192
+
193
+ # If the member is the owner, he can do what he want !
194
+ if repo_item.owner == self
195
+ # You can do what ever you want :)
196
+ return true
197
+ # Find if a sharing of this rep exist for the self instance or it ancestors
198
+ else
199
+ path_ids = repo_item.path_ids
200
+ # Check the nearest sharing if it exist
201
+ if s = self.sharings.where(repo_item_id: path_ids).last
202
+ return {can_share: s.can_share, can_read: s.can_read, can_create: s.can_create, can_update: s.can_update, can_delete: s.can_delete}
203
+ end
204
+ end
205
+ # Else, false
206
+ return false
207
+ end
208
+
209
+ # Download a repo_item if the object can_read it
210
+ # If it is a file, he download the file
211
+ # If it is a folder, we check witch repo_item is in it, and witch he can_read
212
+ # We zip all the content that the object has access.
213
+ # options
214
+ # :path => 'path/to/zip'
215
+ def download!(repo_item, options = {})
216
+ if can_download?(repo_item)
217
+ path = options[:path] if options[:path]
218
+
219
+ repo_item.download({object: self, path: path})
220
+ else
221
+ raise RepositoryManager::AuthorisationException.new("download failed. You don't have the permission to download the repo_item '#{repo_item.name}'")
222
+ end
223
+ end
224
+
225
+ def download(repo_item, options = {})
226
+ begin
227
+ download!(repo_item, options)
228
+ rescue RepositoryManager::AuthorisationException
229
+ false
230
+ end
231
+ end
232
+
233
+ # Rename the repo_item with the new_name
234
+ def rename_repo_item!(repo_item, new_name)
235
+ unless can_update?(repo_item)
236
+ raise RepositoryManager::AuthorisationException.new("rename repo_item failed. You don't have the permission to update the repo_item '#{repo_item.name}'")
237
+ end
238
+ repo_item.rename(new_name)
239
+ end
240
+
241
+ # Rename the repo_item with the new_name
242
+ def rename_repo_item(repo_item, new_name)
243
+ begin
244
+ rename_repo_item!(repo_item, new_name)
245
+ rescue RepositoryManager::AuthorisationException
246
+ false
247
+ end
248
+ end
249
+
250
+ # Move the repo_item in the target_folder
251
+ def move_repo_item!(repo_item, target_folder)
252
+ unless can_delete?(repo_item)
253
+ raise RepositoryManager::AuthorisationException.new("move repo_item failed. You don't have the permission to delete the repo_item '#{repo_item.name}'")
254
+ end
255
+ unless can_create?(target_folder)
256
+ raise RepositoryManager::AuthorisationException.new("move repo_item failed. You don't have the permission to create in the target_folder '#{target_folder.name}'")
257
+ end
258
+ # If it has the permission, we move the repo_item in the target_folder
259
+ repo_item.move(target_folder)
260
+ end
261
+
262
+ def move_repo_item(repo_item, target_folder)
263
+ begin
264
+ move_repo_item!(repo_item, target_folder)
265
+ rescue RepositoryManager::AuthorisationException
266
+ false
267
+ end
268
+ end
269
+
270
+ # Delete the download folder of the user
271
+ def delete_download_path
272
+ FileUtils.rm_rf(self.get_default_download_path())
273
+ end
274
+
275
+ #Return the authorisations of the sharing (can_add, can_remove)
276
+ def get_sharing_authorisations(sharing)
277
+ sharing.get_authorisations(self)
278
+ end
279
+
280
+ # Return true if you can share the repo, else false
281
+ # You can give the authorisations or the repo_item as params
282
+ def can_share?(repo_item, authorisations = nil)
283
+ can_do?('share', repo_item, authorisations)
284
+ end
285
+
286
+ # Return true if you can read the repo, else false
287
+ def can_read?(repo_item, authorisations = nil)
288
+ can_do?('read', repo_item, authorisations)
289
+ end
290
+
291
+ # Return true if you can download the repo, else false
292
+ # Read = Download for the moment
293
+ def can_download?(repo_item, authorisations = nil)
294
+ can_do?('read', repo_item, authorisations)
295
+ end
296
+
297
+ # Return true if you can create in the repo, false else
298
+ def can_create?(repo_item, authorisations = nil)
299
+ can_do?('create', repo_item, authorisations)
300
+ end
301
+
302
+ # Returns true if you can edit the repo, false else
303
+ def can_update?(repo_item, authorisations = nil)
304
+ can_do?('update', repo_item, authorisations)
305
+ end
306
+
307
+ # Returns true if you can delete the repo, false else
308
+ def can_delete?(repo_item, authorisations = nil)
309
+ can_do?('delete', repo_item, authorisations)
310
+ end
311
+
312
+ ## Returns true if it exist a sharing in the ancestors of descendant_ids of the repo_item (without itself)
313
+ #def has_sharing?(repo_item)
314
+ # # An array with the ids of all ancestors and descendants
315
+ # ancestor_and_descendant_ids = []
316
+ # ancestor_and_descendant_ids << repo_item.descendant_ids if !repo_item.descendant_ids.empty?
317
+ # ancestor_and_descendant_ids << repo_item.ancestor_ids if !repo_item.ancestor_ids.empty?
318
+ #
319
+ # # If it is a sharing, it returns true
320
+ # if self.sharings.where(repo_item_id: ancestor_and_descendant_ids).count > 0
321
+ # true
322
+ # else
323
+ # false
324
+ # end
325
+ #
326
+ #end
327
+
328
+ # Return true if you can add a member in this sharing, false else
329
+ def can_add_to?(sharing)
330
+ can_do_to?('add', sharing)
331
+ end
332
+
333
+ # Return true if you can remove a member in this sharing, false else
334
+ def can_remove_from?(sharing)
335
+ can_do_to?('remove', sharing)
336
+ end
337
+
338
+ # You can here add new members in the sharing
339
+ # Param member could be an object or an array of object
340
+ def add_members_to!(sharing, members, options = RepositoryManager.default_sharing_permissions)
341
+ authorisations = get_sharing_authorisations(sharing)
342
+ if can_add_to?(sharing)
343
+ sharing_permissions = make_sharing_permissions(options, authorisations)
344
+ sharing.add_members(members, sharing_permissions)
345
+ else
346
+ raise RepositoryManager::AuthorisationException.new("add members failed. You don't have the permission to add a member in this sharing")
347
+ end
348
+ end
349
+
350
+ def add_members_to(sharing, members, options = RepositoryManager.default_sharing_permissions)
351
+ begin
352
+ add_members_to!(sharing, members, options = RepositoryManager.default_sharing_permissions)
353
+ rescue RepositoryManager::AuthorisationException
354
+ false
355
+ end
356
+ end
357
+
358
+ # You can here add new members in the sharing
359
+ # Param member could be an object or an array of object
360
+ def remove_members_from!(sharing, members)
361
+ if can_remove_from?(sharing)
362
+ sharing.remove_members(members)
363
+ else
364
+ raise RepositoryManager::AuthorisationException.new("remove members failed. You don't have the permission to remove a member on this sharing")
365
+ end
366
+ end
367
+
368
+ def remove_members_from(sharing, members)
369
+ begin
370
+ remove_members_from!(sharing, members)
371
+ rescue RepositoryManager::AuthorisationException
372
+ false
373
+ end
374
+ end
375
+
376
+ # Get the download path of the member
377
+ def get_default_download_path(prefix = 'download/')
378
+ "#{prefix}#{self.class.to_s.underscore}/#{self.id}/"
379
+ end
380
+
381
+ private
382
+
383
+ # Return if you can do or not this action in the sharing
384
+ def can_do_to?(what, sharing, authorisations = nil)
385
+ if authorisations == nil
386
+ authorisations = sharing.get_authorisations(self)
387
+ end
388
+ case what
389
+ when 'add'
390
+ authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_add] == true)
391
+ when 'remove'
392
+ authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_remove] == true)
393
+ end
394
+ end
395
+
396
+ # Return if you can do or not this action (what)
397
+ def can_do?(what, repo_item, authorisations = nil)
398
+ # If we pass no authorisations we have to get it
399
+ if authorisations == nil
400
+ authorisations = get_authorisations(repo_item)
401
+ end
402
+
403
+ case what
404
+ when 'read'
405
+ authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_read] == true)
406
+ when 'delete'
407
+ if RepositoryManager.accept_nested_sharing
408
+ # TODO implement to look if he can delete all the folder
409
+ else
410
+ authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_delete] == true)
411
+ end
412
+ when 'update'
413
+ authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_update] == true)
414
+ when 'share'
415
+ if RepositoryManager.accept_nested_sharing
416
+ # TODO implement to look if he can delete all the folder
417
+ else
418
+ authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_share] == true)
419
+ end
420
+ when 'create'
421
+ if RepositoryManager.accept_nested_sharing
422
+ # TODO implement to look if he can delete all the folder
423
+ else
424
+ authorisations == true || (authorisations.kind_of?(Hash) && authorisations[:can_create] == true)
425
+ end
426
+ else
427
+ false
428
+ end
429
+
430
+ end
431
+
432
+ # Correct the repo_item_permissions with the authorisations
433
+ def make_repo_item_permissions(wanted_permissions, authorisations)
434
+ # If it is an array, we have restriction in the permissions
435
+ if authorisations.kind_of?(Hash) && wanted_permissions
436
+ # Built the sharing with the accepted permissions
437
+ # We remove the permission if we can't sharing it
438
+ if wanted_permissions[:can_read] == true && authorisations[:can_read] == false
439
+ wanted_permissions[:can_read] = false
440
+ end
441
+ if wanted_permissions[:can_create] == true && authorisations[:can_create] == false
442
+ wanted_permissions[:can_create] = false
443
+ end
444
+ if wanted_permissions[:can_update] == true && authorisations[:can_update] == false
445
+ wanted_permissions[:can_update] = false
446
+ end
447
+ if wanted_permissions[:can_delete] == true && authorisations[:can_delete] == false
448
+ wanted_permissions[:can_delete] = false
449
+ end
450
+ if wanted_permissions[:can_share] == true && authorisations[:can_share] == false
451
+ wanted_permissions[:can_share] = false
452
+ end
453
+ end
454
+ return wanted_permissions
455
+ end
456
+
457
+ # Correct the sharing_permissions with the authorisations
458
+ def make_sharing_permissions(wanted_permissions, authorisations)
459
+ # If it is an array, we have restriction in the permissions
460
+ if authorisations.kind_of?(Hash) && wanted_permissions
461
+ # Built the sharing with the accepted permissions
462
+ # We remove the permission if we can't share it
463
+ if wanted_permissions[:can_add] == true && authorisations[:can_add] == false
464
+ wanted_permissions[:can_add] = false
465
+ end
466
+ if wanted_permissions[:can_remove] == true && authorisations[:can_remove] == false
467
+ wanted_permissions[:can_remove] = false
468
+ end
469
+ end
470
+ return wanted_permissions
471
+ end
472
+
473
+ # Put a default name if none is given
474
+ def default_folder_name(source_folder)
475
+ i = ''
476
+ name = "#{I18n.t 'repository_manager.models.repo_folder.name'}#{i}"
477
+ # We check if another item has the same name
478
+
479
+ if source_folder
480
+ # We check if another item has the same name
481
+ until !RepoItem.where(name: name).where(id: source_folder.child_ids).first do
482
+ if i == ''
483
+ i = 1
484
+ end
485
+ i += 1
486
+ name = "#{I18n.t 'repository_manager.models.repo_folder.name'}#{i}"
487
+ end
488
+
489
+ else
490
+ # Si il n'a pas de parent, racine
491
+ until !RepoItem.where(name: name).where(owner: self).where(ancestry: nil).first do
492
+ if i == ''
493
+ i = 1
494
+ end
495
+ i += 1
496
+ name = "#{I18n.t 'repository_manager.models.repo_folder.name'}#{i}"
497
+ end
498
+
499
+ end
500
+ name
501
+ end
502
+
503
+ end
504
+ end
505
+ end
506
+
453
507
  ActiveRecord::Base.send :include, RepositoryManager::HasRepository