boxroom 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +50 -0
- data/Rakefile +36 -0
- data/app/assets/config/boxroom_manifest.js +2 -0
- data/app/assets/images/boxroom/clipboard.png +0 -0
- data/app/assets/images/boxroom/clipboard_add.png +0 -0
- data/app/assets/images/boxroom/copy.png +0 -0
- data/app/assets/images/boxroom/delete.png +0 -0
- data/app/assets/images/boxroom/edit.png +0 -0
- data/app/assets/images/boxroom/exclamation.png +0 -0
- data/app/assets/images/boxroom/extend.png +0 -0
- data/app/assets/images/boxroom/failed.png +0 -0
- data/app/assets/images/boxroom/file.png +0 -0
- data/app/assets/images/boxroom/file_add.png +0 -0
- data/app/assets/images/boxroom/fileicons/7z.png +0 -0
- data/app/assets/images/boxroom/fileicons/ai.png +0 -0
- data/app/assets/images/boxroom/fileicons/aif.png +0 -0
- data/app/assets/images/boxroom/fileicons/aiff.png +0 -0
- data/app/assets/images/boxroom/fileicons/audio.png +0 -0
- data/app/assets/images/boxroom/fileicons/bz2.png +0 -0
- data/app/assets/images/boxroom/fileicons/c.png +0 -0
- data/app/assets/images/boxroom/fileicons/conf.png +0 -0
- data/app/assets/images/boxroom/fileicons/cpp.png +0 -0
- data/app/assets/images/boxroom/fileicons/cs.png +0 -0
- data/app/assets/images/boxroom/fileicons/css.png +0 -0
- data/app/assets/images/boxroom/fileicons/csv.png +0 -0
- data/app/assets/images/boxroom/fileicons/divx.png +0 -0
- data/app/assets/images/boxroom/fileicons/doc.png +0 -0
- data/app/assets/images/boxroom/fileicons/docx.png +0 -0
- data/app/assets/images/boxroom/fileicons/dot.png +0 -0
- data/app/assets/images/boxroom/fileicons/fla.png +0 -0
- data/app/assets/images/boxroom/fileicons/gif.png +0 -0
- data/app/assets/images/boxroom/fileicons/gz.png +0 -0
- data/app/assets/images/boxroom/fileicons/htm.png +0 -0
- data/app/assets/images/boxroom/fileicons/html.png +0 -0
- data/app/assets/images/boxroom/fileicons/image.png +0 -0
- data/app/assets/images/boxroom/fileicons/java.png +0 -0
- data/app/assets/images/boxroom/fileicons/jpeg.png +0 -0
- data/app/assets/images/boxroom/fileicons/jpg.png +0 -0
- data/app/assets/images/boxroom/fileicons/js.png +0 -0
- data/app/assets/images/boxroom/fileicons/mdb.png +0 -0
- data/app/assets/images/boxroom/fileicons/mdbx.png +0 -0
- data/app/assets/images/boxroom/fileicons/mov.png +0 -0
- data/app/assets/images/boxroom/fileicons/mp3.png +0 -0
- data/app/assets/images/boxroom/fileicons/mpg.png +0 -0
- data/app/assets/images/boxroom/fileicons/ogg.png +0 -0
- data/app/assets/images/boxroom/fileicons/pdf.png +0 -0
- data/app/assets/images/boxroom/fileicons/php.png +0 -0
- data/app/assets/images/boxroom/fileicons/pl.png +0 -0
- data/app/assets/images/boxroom/fileicons/png.png +0 -0
- data/app/assets/images/boxroom/fileicons/ppt.png +0 -0
- data/app/assets/images/boxroom/fileicons/pptx.png +0 -0
- data/app/assets/images/boxroom/fileicons/ps.png +0 -0
- data/app/assets/images/boxroom/fileicons/py.png +0 -0
- data/app/assets/images/boxroom/fileicons/ram.png +0 -0
- data/app/assets/images/boxroom/fileicons/rar.png +0 -0
- data/app/assets/images/boxroom/fileicons/rb.png +0 -0
- data/app/assets/images/boxroom/fileicons/rm.png +0 -0
- data/app/assets/images/boxroom/fileicons/rtf.png +0 -0
- data/app/assets/images/boxroom/fileicons/sql.png +0 -0
- data/app/assets/images/boxroom/fileicons/swf.png +0 -0
- data/app/assets/images/boxroom/fileicons/tar.png +0 -0
- data/app/assets/images/boxroom/fileicons/tgz.png +0 -0
- data/app/assets/images/boxroom/fileicons/txt.png +0 -0
- data/app/assets/images/boxroom/fileicons/video.png +0 -0
- data/app/assets/images/boxroom/fileicons/wav.png +0 -0
- data/app/assets/images/boxroom/fileicons/wma.png +0 -0
- data/app/assets/images/boxroom/fileicons/wmv.png +0 -0
- data/app/assets/images/boxroom/fileicons/xls.png +0 -0
- data/app/assets/images/boxroom/fileicons/xlsx.png +0 -0
- data/app/assets/images/boxroom/fileicons/xml.png +0 -0
- data/app/assets/images/boxroom/fileicons/xvid.png +0 -0
- data/app/assets/images/boxroom/fileicons/zip.png +0 -0
- data/app/assets/images/boxroom/folder.png +0 -0
- data/app/assets/images/boxroom/folder_add.png +0 -0
- data/app/assets/images/boxroom/group.png +0 -0
- data/app/assets/images/boxroom/group_add.png +0 -0
- data/app/assets/images/boxroom/group_grey.png +0 -0
- data/app/assets/images/boxroom/information.png +0 -0
- data/app/assets/images/boxroom/logo.png +0 -0
- data/app/assets/images/boxroom/move.png +0 -0
- data/app/assets/images/boxroom/permissions.png +0 -0
- data/app/assets/images/boxroom/share.png +0 -0
- data/app/assets/images/boxroom/spinner.gif +0 -0
- data/app/assets/images/boxroom/tick.png +0 -0
- data/app/assets/images/boxroom/user.png +0 -0
- data/app/assets/images/boxroom/user_add.png +0 -0
- data/app/assets/javascripts/boxroom/application.js.coffee +51 -0
- data/app/assets/javascripts/boxroom/files.js.coffee +33 -0
- data/app/assets/stylesheets/boxroom/application.scss +7 -0
- data/app/concepts/boxroom/base_cell.rb +7 -0
- data/app/concepts/boxroom/folder/cell/show.rb +25 -0
- data/app/concepts/boxroom/folder/view/show.erb +69 -0
- data/app/concepts/boxroom/search/contract/files_and_folders.rb +9 -0
- data/app/concepts/boxroom/search/operations/files_and_folders.rb +21 -0
- data/app/controllers/boxroom/admins_controller.rb +30 -0
- data/app/controllers/boxroom/application_controller.rb +5 -0
- data/app/controllers/boxroom/clipboard_controller.rb +87 -0
- data/app/controllers/boxroom/files_controller.rb +78 -0
- data/app/controllers/boxroom/folders_controller.rb +91 -0
- data/app/controllers/boxroom/groups_controller.rb +60 -0
- data/app/controllers/boxroom/permissions_controller.rb +19 -0
- data/app/controllers/boxroom/reset_password_controller.rb +45 -0
- data/app/controllers/boxroom/search_controller.rb +21 -0
- data/app/controllers/boxroom/sessions_controller.rb +48 -0
- data/app/controllers/boxroom/share_links_controller.rb +67 -0
- data/app/controllers/boxroom/signup_controller.rb +31 -0
- data/app/controllers/boxroom/users_controller.rb +75 -0
- data/app/controllers/concerns/boxroom/base_controller.rb +92 -0
- data/app/helpers/boxroom/application_helper.rb +4 -0
- data/app/helpers/boxroom/folders_helper.rb +17 -0
- data/app/jobs/boxroom/application_job.rb +4 -0
- data/app/mailers/boxroom/application_mailer.rb +6 -0
- data/app/mailers/boxroom/user_mailer.rb +18 -0
- data/app/models/boxroom/application_record.rb +5 -0
- data/app/models/boxroom/clipboard.rb +45 -0
- data/app/models/boxroom/folder.rb +113 -0
- data/app/models/boxroom/group.rb +57 -0
- data/app/models/boxroom/permission.rb +6 -0
- data/app/models/boxroom/permitted_params.rb +33 -0
- data/app/models/boxroom/share_link.rb +40 -0
- data/app/models/boxroom/user.rb +113 -0
- data/app/models/boxroom/user_file.rb +35 -0
- data/app/views/boxroom/admins/new.html.erb +42 -0
- data/app/views/boxroom/clipboard/_clipboard_empty.de.html.erb +2 -0
- data/app/views/boxroom/clipboard/_clipboard_empty.en.html.erb +2 -0
- data/app/views/boxroom/clipboard/_clipboard_empty.es.html.erb +2 -0
- data/app/views/boxroom/clipboard/_clipboard_empty.fr.html.erb +2 -0
- data/app/views/boxroom/clipboard/_clipboard_empty.it.html.erb +2 -0
- data/app/views/boxroom/clipboard/_clipboard_empty.nl.html.erb +2 -0
- data/app/views/boxroom/clipboard/_clipboard_empty.zh-CN.html.erb +2 -0
- data/app/views/boxroom/clipboard/_show.html.erb +72 -0
- data/app/views/boxroom/files/edit.html.erb +24 -0
- data/app/views/boxroom/files/new.html.erb +45 -0
- data/app/views/boxroom/folders/_form.html.erb +19 -0
- data/app/views/boxroom/folders/edit.html.erb +6 -0
- data/app/views/boxroom/folders/new.html.erb +6 -0
- data/app/views/boxroom/folders/show.html.erb +69 -0
- data/app/views/boxroom/groups/_form.html.erb +21 -0
- data/app/views/boxroom/groups/edit.html.erb +4 -0
- data/app/views/boxroom/groups/index.html.erb +42 -0
- data/app/views/boxroom/groups/new.html.erb +4 -0
- data/app/views/boxroom/permissions/_form.html.erb +46 -0
- data/app/views/boxroom/reset_password/_message.de.html.erb +2 -0
- data/app/views/boxroom/reset_password/_message.en.html.erb +2 -0
- data/app/views/boxroom/reset_password/_message.es.html.erb +2 -0
- data/app/views/boxroom/reset_password/_message.fr.html.erb +2 -0
- data/app/views/boxroom/reset_password/_message.it.html.erb +2 -0
- data/app/views/boxroom/reset_password/_message.nl.html.erb +2 -0
- data/app/views/boxroom/reset_password/_message.zh-CN.html.erb +2 -0
- data/app/views/boxroom/reset_password/edit.html.erb +30 -0
- data/app/views/boxroom/reset_password/new.html.erb +22 -0
- data/app/views/boxroom/search/show.html.erb +15 -0
- data/app/views/boxroom/sessions/new.html.erb +31 -0
- data/app/views/boxroom/share_links/index.html.erb +24 -0
- data/app/views/boxroom/share_links/new.html.erb +49 -0
- data/app/views/boxroom/shared/_footer.html.erb +9 -0
- data/app/views/boxroom/shared/_header.html.erb +45 -0
- data/app/views/boxroom/signup/edit.html.erb +42 -0
- data/app/views/boxroom/user_mailer/reset_password_email.de.text.erb +18 -0
- data/app/views/boxroom/user_mailer/reset_password_email.en.text.erb +17 -0
- data/app/views/boxroom/user_mailer/reset_password_email.es.text.erb +17 -0
- data/app/views/boxroom/user_mailer/reset_password_email.fr.text.erb +17 -0
- data/app/views/boxroom/user_mailer/reset_password_email.it.text.erb +17 -0
- data/app/views/boxroom/user_mailer/reset_password_email.nl.text.erb +17 -0
- data/app/views/boxroom/user_mailer/reset_password_email.zh-CN.text.erb +16 -0
- data/app/views/boxroom/user_mailer/share_link_email.de.text.erb +20 -0
- data/app/views/boxroom/user_mailer/share_link_email.en.text.erb +20 -0
- data/app/views/boxroom/user_mailer/share_link_email.es.text.erb +20 -0
- data/app/views/boxroom/user_mailer/share_link_email.fr.text.erb +20 -0
- data/app/views/boxroom/user_mailer/share_link_email.it.text.erb +20 -0
- data/app/views/boxroom/user_mailer/share_link_email.nl.text.erb +20 -0
- data/app/views/boxroom/user_mailer/share_link_email.zh-CN.text.erb +20 -0
- data/app/views/boxroom/user_mailer/signup_email.de.text.erb +9 -0
- data/app/views/boxroom/user_mailer/signup_email.en.text.erb +9 -0
- data/app/views/boxroom/user_mailer/signup_email.es.text.erb +9 -0
- data/app/views/boxroom/user_mailer/signup_email.fr.text.erb +9 -0
- data/app/views/boxroom/user_mailer/signup_email.it.text.erb +9 -0
- data/app/views/boxroom/user_mailer/signup_email.nl.text.erb +10 -0
- data/app/views/boxroom/user_mailer/signup_email.zh-CN.text.erb +8 -0
- data/app/views/boxroom/users/_form.html.erb +63 -0
- data/app/views/boxroom/users/edit.html.erb +4 -0
- data/app/views/boxroom/users/index.html.erb +68 -0
- data/app/views/boxroom/users/new.html.erb +4 -0
- data/app/views/layouts/boxroom/application.html.erb +37 -0
- data/config/locales/de.yml +414 -0
- data/config/locales/en.yml +407 -0
- data/config/locales/es.yml +403 -0
- data/config/locales/fr.yml +403 -0
- data/config/locales/it.yml +414 -0
- data/config/locales/nl.yml +408 -0
- data/config/locales/zh-CN.yml +406 -0
- data/config/routes.rb +44 -0
- data/db/migrate/20100930062939_boxroom_create_users.rb +20 -0
- data/db/migrate/20100930091426_boxroom_create_folders.rb +14 -0
- data/db/migrate/20100930091451_boxroom_create_groups.rb +12 -0
- data/db/migrate/20101002122244_boxroom_create_user_files.rb +17 -0
- data/db/migrate/20101005071402_boxroom_create_permissions.rb +16 -0
- data/db/migrate/20101005071508_boxroom_create_groups_users.rb +12 -0
- data/db/migrate/20110106045148_boxroom_drop_column_user_id_from_folders.rb +9 -0
- data/db/migrate/20110106045414_boxroom_drop_column_user_id_from_user_files.rb +9 -0
- data/db/migrate/20110529123402_boxroom_drop_column_access_key_from_users.rb +9 -0
- data/db/migrate/20110616215033_boxroom_create_share_links.rb +15 -0
- data/db/migrate/20120411075110_boxroom_add_column_signup_token_to_users.rb +8 -0
- data/db/migrate/20120411081345_boxroom_add_column_signup_token_expires_at_to_users.rb +7 -0
- data/db/migrate/20130626210927_boxroom_add_columns_message_user_id_to_share_links.rb +6 -0
- data/db/migrate/20130628082245_boxroom_populate_user_id_in_share_links.rb +9 -0
- data/lib/boxroom.rb +35 -0
- data/lib/boxroom/configuration.rb +18 -0
- data/lib/boxroom/engine.rb +9 -0
- data/lib/boxroom/version.rb +3 -0
- data/lib/paperclip/spoof_detector.rb +7 -0
- data/lib/tasks/boxroom_tasks.rake +4 -0
- metadata +481 -0
@@ -0,0 +1,113 @@
|
|
1
|
+
module Boxroom
|
2
|
+
class Folder < ActiveRecord::Base
|
3
|
+
acts_as_tree :order => 'name'
|
4
|
+
|
5
|
+
has_many :user_files, -> {order :attachment_file_name}, :dependent => :destroy
|
6
|
+
has_many :permissions, :dependent => :destroy
|
7
|
+
|
8
|
+
attr_accessor :is_copied_folder
|
9
|
+
|
10
|
+
validates_uniqueness_of :name, :scope => :parent_id
|
11
|
+
validates_presence_of :name
|
12
|
+
|
13
|
+
before_save :check_for_parent
|
14
|
+
after_create :create_permissions, :unless => :is_copied_folder
|
15
|
+
before_destroy :dont_destroy_root_folder
|
16
|
+
|
17
|
+
def copy(target_folder, originally_copied_folder = nil)
|
18
|
+
new_folder = self.dup
|
19
|
+
new_folder.is_copied_folder = true
|
20
|
+
new_folder.parent = target_folder
|
21
|
+
new_folder.save!
|
22
|
+
|
23
|
+
originally_copied_folder = new_folder if originally_copied_folder.nil?
|
24
|
+
|
25
|
+
# Copy original folder's permissions
|
26
|
+
self.permissions.each do |permission|
|
27
|
+
new_permission = permission.dup
|
28
|
+
new_permission.folder = new_folder
|
29
|
+
new_permission.save!
|
30
|
+
end
|
31
|
+
|
32
|
+
self.user_files.each do |file|
|
33
|
+
file.copy(new_folder)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Copy sub-folders recursively
|
37
|
+
self.children.each do |folder|
|
38
|
+
folder.copy(new_folder, originally_copied_folder) unless folder == originally_copied_folder
|
39
|
+
end
|
40
|
+
|
41
|
+
new_folder
|
42
|
+
end
|
43
|
+
|
44
|
+
def move(target_folder)
|
45
|
+
unless target_folder == self || self.parent_of?(target_folder)
|
46
|
+
self.parent = target_folder
|
47
|
+
save!
|
48
|
+
else
|
49
|
+
raise 'You cannot move a folder to its own sub-folder.'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def copy_permissions_to_children(permissions_to_copy)
|
54
|
+
permissions_to_copy.each do |permission|
|
55
|
+
attributes = permission.attributes.except('id', 'folder_id', 'group_id')
|
56
|
+
Permission.where(:folder_id => children, :group_id => permission.group_id).update_all(attributes)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Copy permissions recursively
|
60
|
+
children.each do |child|
|
61
|
+
child.copy_permissions_to_children(permissions_to_copy) if child.has_children?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def parent_of?(folder)
|
66
|
+
self.children.each do |child|
|
67
|
+
if child == folder
|
68
|
+
return true
|
69
|
+
else
|
70
|
+
return child.parent_of?(folder)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
false
|
74
|
+
end
|
75
|
+
|
76
|
+
def is_root?
|
77
|
+
parent.nil? && !new_record?
|
78
|
+
end
|
79
|
+
|
80
|
+
def has_children?
|
81
|
+
children.count > 0
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.root
|
85
|
+
@root_folder ||= find_by_name_and_parent_id('Root folder', nil)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def check_for_parent
|
91
|
+
raise 'Folders must have a parent.' if parent.nil? && name != 'Root folder'
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_permissions
|
95
|
+
unless is_root?
|
96
|
+
parent.permissions.each do |permission|
|
97
|
+
Permission.create! do |p|
|
98
|
+
p.group = permission.group
|
99
|
+
p.folder = self
|
100
|
+
p.can_create = permission.can_create
|
101
|
+
p.can_read = permission.can_read
|
102
|
+
p.can_update = permission.can_update
|
103
|
+
p.can_delete = permission.can_delete
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def dont_destroy_root_folder
|
110
|
+
raise "Can't delete Root folder" if is_root?
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Boxroom
|
2
|
+
class Group < ActiveRecord::Base
|
3
|
+
has_many :permissions, :dependent => :destroy
|
4
|
+
has_and_belongs_to_many :users
|
5
|
+
|
6
|
+
validates_uniqueness_of :name
|
7
|
+
validates_presence_of :name
|
8
|
+
|
9
|
+
after_create :create_admin_permissions, :if => :admins_group?
|
10
|
+
after_create :create_permissions, :unless => :admins_group?
|
11
|
+
before_destroy :dont_destroy_admins
|
12
|
+
|
13
|
+
def admins_group?
|
14
|
+
name == 'Admins'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.admins_group
|
18
|
+
where(:name => 'Admins').first
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.all_except_admins
|
22
|
+
where.not(:name => 'Admins')
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def create_admin_permissions
|
28
|
+
Folder.find_each do |folder|
|
29
|
+
Permission.create! do |p|
|
30
|
+
p.group = self
|
31
|
+
p.folder = folder
|
32
|
+
p.can_create = true
|
33
|
+
p.can_read = true
|
34
|
+
p.can_update = true
|
35
|
+
p.can_delete = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_permissions
|
41
|
+
Folder.find_each do |folder|
|
42
|
+
Permission.create! do |p|
|
43
|
+
p.group = self
|
44
|
+
p.folder = folder
|
45
|
+
p.can_create = false
|
46
|
+
p.can_read = folder.is_root? # New groups can read the root folder
|
47
|
+
p.can_update = false
|
48
|
+
p.can_delete = false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def dont_destroy_admins
|
54
|
+
raise "Can't delete admins group" if admins_group?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Boxroom
|
2
|
+
class PermittedParams < Struct.new(:params, :current_user)
|
3
|
+
%w{folder group share_link user user_file}.each do |model_name|
|
4
|
+
define_method model_name do
|
5
|
+
params.require(model_name.to_sym).permit(*send("#{model_name}_attributes"))
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def folder_attributes
|
10
|
+
[:name]
|
11
|
+
end
|
12
|
+
|
13
|
+
def group_attributes
|
14
|
+
[:name]
|
15
|
+
end
|
16
|
+
|
17
|
+
def share_link_attributes
|
18
|
+
[:emails, :link_expires_at, :message]
|
19
|
+
end
|
20
|
+
|
21
|
+
def user_attributes
|
22
|
+
if current_user && current_user.member_of_admins?
|
23
|
+
[:name, :email, :password, :password_confirmation, {:group_ids => []}]
|
24
|
+
else
|
25
|
+
[:name, :email, :password, :password_confirmation]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def user_file_attributes
|
30
|
+
[:attachment, :attachment_file_name]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Boxroom
|
2
|
+
class ShareLink < ActiveRecord::Base
|
3
|
+
belongs_to :user
|
4
|
+
belongs_to :user_file
|
5
|
+
|
6
|
+
validates_presence_of :emails, :link_expires_at
|
7
|
+
validates_length_of :emails, :maximum => 255
|
8
|
+
validate :format_of_emails
|
9
|
+
|
10
|
+
before_save :generate_token
|
11
|
+
|
12
|
+
def self.active_share_links
|
13
|
+
where('link_expires_at >= ?', DateTime.now).order(:link_expires_at)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.file_for_token(token)
|
17
|
+
share_link = find_by_link_token(token)
|
18
|
+
|
19
|
+
if share_link.link_expires_at < DateTime.now
|
20
|
+
raise 'This share link expired.'
|
21
|
+
else
|
22
|
+
share_link.user_file
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def format_of_emails
|
29
|
+
emails.split(/,\s*/).each do |email|
|
30
|
+
unless email.strip =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/
|
31
|
+
errors.add(:emails, I18n.t(:are_invalid_due_to, :email => email))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def generate_token
|
37
|
+
self.link_token = SecureRandom.hex(10)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Boxroom
|
2
|
+
class User < ActiveRecord::Base
|
3
|
+
has_and_belongs_to_many :groups
|
4
|
+
has_many :share_links
|
5
|
+
|
6
|
+
attr_accessor :password_confirmation, :password_required, :dont_clear_reset_password_token
|
7
|
+
|
8
|
+
validates_confirmation_of :password
|
9
|
+
validates_length_of :password, :in => 6..20, :allow_blank => true
|
10
|
+
validates_presence_of :password, :if => :password_required
|
11
|
+
validates_presence_of :name, :unless => :new_record?
|
12
|
+
validates_presence_of :email
|
13
|
+
validates_uniqueness_of :name, :unless => :new_record? && :name_is_blank?
|
14
|
+
validates_uniqueness_of :email
|
15
|
+
validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/
|
16
|
+
|
17
|
+
before_create :set_signup_token
|
18
|
+
before_save :clear_reset_password_token, :unless => :dont_clear_reset_password_token
|
19
|
+
before_update :clear_signup_token
|
20
|
+
after_create :create_root_folder_and_admins_group, :if => :is_admin
|
21
|
+
before_destroy :dont_destroy_admin
|
22
|
+
|
23
|
+
%w{create read update delete}.each do |method|
|
24
|
+
define_method "can_#{method}" do |folder|
|
25
|
+
has_permission = false
|
26
|
+
|
27
|
+
Permission.where(:group_id => groups, :folder_id => folder.id).each do |permission|
|
28
|
+
has_permission = permission.send("can_#{method}")
|
29
|
+
break if has_permission
|
30
|
+
end
|
31
|
+
|
32
|
+
has_permission
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def password
|
37
|
+
@password
|
38
|
+
end
|
39
|
+
|
40
|
+
def password=(new_password)
|
41
|
+
@password = new_password
|
42
|
+
|
43
|
+
unless @password.blank?
|
44
|
+
self.password_salt = SecureRandom.base64(32)
|
45
|
+
self.hashed_password = Digest::SHA256.hexdigest(password_salt + password)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def member_of_admins?
|
50
|
+
groups.admins_group.present?
|
51
|
+
end
|
52
|
+
|
53
|
+
def refresh_reset_password_token
|
54
|
+
self.reset_password_token = SecureRandom.hex(10)
|
55
|
+
self.reset_password_token_expires_at = 1.hour.from_now
|
56
|
+
self.dont_clear_reset_password_token = true
|
57
|
+
save(:validate => false)
|
58
|
+
end
|
59
|
+
|
60
|
+
def refresh_remember_token
|
61
|
+
self.remember_token = SecureRandom.base64(32)
|
62
|
+
save(:validate => false)
|
63
|
+
end
|
64
|
+
|
65
|
+
def forget_me
|
66
|
+
self.remember_token = nil
|
67
|
+
save(:validate => false)
|
68
|
+
end
|
69
|
+
|
70
|
+
def name_is_blank?
|
71
|
+
self.name.blank?
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.authenticate(name, password)
|
75
|
+
return nil if name.blank? || password.blank?
|
76
|
+
user = find_by_name(name) or return nil
|
77
|
+
hash = Digest::SHA256.hexdigest(user.password_salt + password)
|
78
|
+
hash == user.hashed_password ? user : nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.no_admin_yet?
|
82
|
+
find_by_is_admin(true).blank?
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def set_signup_token
|
88
|
+
self.signup_token = SecureRandom.hex(10)
|
89
|
+
self.signup_token_expires_at = 2.weeks.from_now
|
90
|
+
end
|
91
|
+
|
92
|
+
def clear_signup_token
|
93
|
+
unless self.name.blank?
|
94
|
+
self.signup_token = nil
|
95
|
+
self.signup_token_expires_at = nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def clear_reset_password_token
|
100
|
+
self.reset_password_token = nil
|
101
|
+
self.reset_password_token_expires_at = nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def create_root_folder_and_admins_group
|
105
|
+
Folder.find_or_create_by(name: 'Root folder')
|
106
|
+
groups << Group.find_or_create_by(name: 'Admins')
|
107
|
+
end
|
108
|
+
|
109
|
+
def dont_destroy_admin
|
110
|
+
raise "Can't delete original admin user" if is_admin
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Boxroom
|
2
|
+
class UserFile < ActiveRecord::Base
|
3
|
+
has_attached_file :attachment, :path => ":rails_root/#{Boxroom.configuration.uploads_path}/:rails_env/:id/:style/:id", :restricted_characters => Boxroom::RESTRICTED_CHARACTERS
|
4
|
+
do_not_validate_attachment_file_type :attachment
|
5
|
+
|
6
|
+
belongs_to :folder
|
7
|
+
has_many :share_links, :dependent => :destroy
|
8
|
+
|
9
|
+
validates_attachment_presence :attachment, :message => I18n.t(:blank, :scope => [:activerecord, :errors, :messages])
|
10
|
+
validates_presence_of :folder_id
|
11
|
+
validates_uniqueness_of :attachment_file_name, :scope => 'folder_id', :message => I18n.t(:exists_already, :scope => [:activerecord, :errors, :messages])
|
12
|
+
validates_format_of :attachment_file_name, :with => /\A[^\/\\\?\*:|"<>]+\z/, :message => I18n.t(:invalid_characters, :scope => [:activerecord, :errors, :messages])
|
13
|
+
|
14
|
+
def copy(target_folder)
|
15
|
+
new_file = self.dup
|
16
|
+
new_file.folder = target_folder
|
17
|
+
new_file.save!
|
18
|
+
|
19
|
+
path = "#{Rails.root}/#{Boxroom.configuration.uploads_path}/#{Rails.env}/#{new_file.id}/original"
|
20
|
+
FileUtils.mkdir_p path
|
21
|
+
FileUtils.cp_r self.attachment.path, "#{path}/#{new_file.id}"
|
22
|
+
|
23
|
+
new_file
|
24
|
+
end
|
25
|
+
|
26
|
+
def move(target_folder)
|
27
|
+
self.folder = target_folder
|
28
|
+
save!
|
29
|
+
end
|
30
|
+
|
31
|
+
def extension
|
32
|
+
File.extname(attachment_file_name)[1..-1]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<% content_for :title, t(:create_admin) -%>
|
2
|
+
|
3
|
+
<h1 class="title"><%= content_for :title %></h1>
|
4
|
+
<div class="notification is-warning">
|
5
|
+
<%= t :no_administrator_yet %>
|
6
|
+
</div>
|
7
|
+
<%= form_for @user, url: {action: 'create'} do |f| %>
|
8
|
+
<% if f.error_messages.size > 0 %>
|
9
|
+
<div class="notification is-danger">
|
10
|
+
<%= f.error_messages %>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
<div class="field">
|
14
|
+
<%= f.label :name, t(:username), class: 'label' %>
|
15
|
+
<div class="control">
|
16
|
+
<%= f.text_field :name, class: 'input' %>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
<div class="field">
|
20
|
+
<%= f.label :email, class: 'label' %>
|
21
|
+
<div class="control">
|
22
|
+
<%= f.text_field :email, class: 'input' %>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
<div class="field">
|
26
|
+
<%= label_tag :password, class: 'label' %>
|
27
|
+
<div class="control">
|
28
|
+
<%= f.password_field :password, class: 'input' %>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
<div class="field">
|
32
|
+
<%= label_tag :confirm_password, nil, class: 'label' %>
|
33
|
+
<div class="control">
|
34
|
+
<%= f.password_field :password_confirmation, class: 'input' %>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
<div class="field">
|
38
|
+
<div class="control">
|
39
|
+
<%= f.submit t(:create_admin_account), class: 'button is-link' %>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
<% end %>
|