initial import boxroom 0.6.2
[boxroom-stian.git] / app / controllers / folder_controller.rb
blob4f2cd502f920fba4f93865b67c9107b8d08dfbcf
1 # The folder controller contains the following actions:\r
2 # [#index]              the default action, redirects to list\r
3 # [#list]               list files and sub folders in a folder\r
4 # [#feed]               authorizes, sets appropriate variables and header for RSS feed\r
5 # [#feed_warning]       renders page with explanations/warnings about RSS feed\r
6 # [#new]                shows the form for creating a new folder\r
7 # [#create]             create a new folder\r
8 # [#rename]             show the form for adjusting the folder's name\r
9 # [#update]             updates the attributes of a folder\r
10 # [#destroy]            delete a folder\r
11 # [#update_permissions] save the new rights given by the user\r
12 class FolderController < ApplicationController\r
13   skip_before_filter :authorize, :only => :feed\r
15   before_filter :does_folder_exist, :except => [:list, :feed, :feed_warning]\r
16   before_filter :authorize_creating, :only => [:new, :create]\r
17   before_filter :authorize_reading, :only => :list\r
18   before_filter :authorize_updating, :only => [:rename, :update, :update_rights]\r
19   before_filter :authorize_deleting, :only => :destroy\r
21   # Sessions are not needed for feeds\r
22   session :off, :only => 'feed'\r
23   layout 'folder', :except => 'feed'\r
25   # The default action, redirects to list.\r
26   def index\r
27     list\r
28     render_action 'list'\r
29   end\r
31   # List the files and sub-folders in a folder.\r
32   def list\r
33     # Get the folder\r
34     @folder = Folder.find_by_id(folder_id)\r
36     # Set if the user is allowed to update or delete in this folder;\r
37     # these instance variables are used in the view.\r
38     @can_update = @logged_in_user.can_update(@folder.id)\r
39     @can_delete = @logged_in_user.can_delete(@folder.id)\r
41     # determine the order in which files are shown\r
42     file_order = 'filename '\r
43     file_order = params[:order_by].sub('name', 'filename') + ' ' if params[:order_by]\r
44     file_order += params[:order] if params[:order]\r
46     # determine the order in which folders are shown\r
47     folder_order = 'name '\r
48     if params[:order_by] and params[:order_by] != 'filesize'    \r
49       folder_order = params[:order_by] + ' '\r
50       folder_order += params[:order] if params[:order]\r
51     end\r
53     # List of subfolders\r
54     @folders = @folder.list_subfolders(@logged_in_user, folder_order.rstrip)\r
56     # List of files in the folder\r
57     @myfiles = @folder.list_files(@logged_in_user, file_order.rstrip)\r
59     #get the correct URL\r
60     url = url_for(:controller => 'folder', :action => 'list', :id => nil)\r
62     # it's nice to have the possibility to go up one level\r
63     @folder_up = '<a href="' + url + '/' + @folder.parent.id.to_s + '">..</a>' if @folder.parent\r
64   end\r
66   # Authorizes, sets the appropriate variables and headers.\r
67   # The feed is actually implemented in: app/views/folder/feed.rxml.\r
68   def feed\r
69     # check for valid access key:\r
70     user = User.find_by_rss_access_key(params[:access_key])\r
71     @authorized = !user.blank?\r
73     # get the folder\r
74     @folder = Folder.find_by_id(folder_id)\r
76     # set appriopriate instance variables,\r
77     # so the feed can be created in folder.rxml\r
78     if @authorized and not @folder.blank?\r
79       if @folder.is_root or user.can_read(@folder.id)\r
80         @folders = @folder.list_subfolders(user, 'name')\r
81         @myfiles = @folder.list_files(user, 'filename')\r
82       else\r
83         @authorized = false\r
84       end\r
85     end\r
87     # finally, set correct header\r
88     if @authorized\r
89       headers['Content-Type'] = 'text/xml'\r
90     else\r
91       headers['Content-Type'] = 'text/html'\r
92     end\r
93   end\r
95   # Page that shows warning about RSS\r
96   # and the feed's authorization.\r
97   def feed_warning\r
98     render\r
99   end\r
101   # Shows the form where a user can enter the name for the a folder.\r
102   # The new folder will be stored in the 'current' folder.\r
103   def new\r
104     @folder = Folder.new\r
105   end\r
107   # Create a new folder with the posted variables from the 'new' view.\r
108   def create\r
109     if request.post?\r
110       @folder = Folder.new(params[:folder])\r
111       @folder.parent_id = folder_id\r
112       @folder.date_modified = Time.now\r
113       @folder.user = @logged_in_user\r
115       if @folder.save\r
116         # copy groups rights on parent folder to new folder\r
117         copy_permissions_to_new_folder(@folder)\r
119         # back to the list\r
120         redirect_to :action => 'list', :id => params[:id]\r
121       else\r
122         render_action 'new'\r
123       end\r
124     end\r
125   end\r
127   # Show a form with the current name of the folder in a text field.\r
128   def rename\r
129     render\r
130   end\r
132   # Update the folder attributes with the posted variables from the 'rename' view.\r
133   def update\r
134     if request.post?\r
135       if @folder.update_attributes(:name => params[:folder][:name], :date_modified => Time.now)\r
136         redirect_to :action => 'list', :id => folder_id\r
137       else\r
138         render_action 'rename'\r
139       end\r
140     end\r
141   end\r
143   # Delete a folder.\r
144   def destroy\r
145     @folder.destroy\r
146     redirect_to :action => 'list', :id => folder_id\r
147   end\r
149   # Saved the new permissions given by the user\r
150   def update_permissions\r
151     if request.post? and @logged_in_user.is_admin?\r
152       # update the create, read, update, delete right for this folder:\r
153       update_group_permissions(folder_id, params[:create_check_box], 'create', params[:update_recursively][:checked] == 'yes' ? true : false)\r
154       update_group_permissions(folder_id, params[:read_check_box], 'read', params[:update_recursively][:checked] == 'yes' ? true : false)\r
155       update_group_permissions(folder_id, params[:update_check_box], 'update', params[:update_recursively][:checked] == 'yes' ? true : false)\r
156       update_group_permissions(folder_id, params[:delete_check_box], 'delete', params[:update_recursively][:checked] == 'yes' ? true : false)\r
157     end\r
159     # Return to the folder\r
160     redirect_to :action => 'list', :id => folder_id\r
161   end\r
163   # These methods are private:\r
164   # [#update_group_permissions]        Update the group folder permissions\r
165   # [#copy_permissions_to_new_folder]  Copy the GroupPermissions of the parent folder to the given folder\r
166   # [#authorize_reading]               Allows/disallows the current user to read the current folder\r
167   # [#authorize_deleting]              Check logged in user's delete permissions for a particular folder\r
168   # [#authorize_deleting_for_children] Check delete permissions for subfolders recursively\r
169   private\r
170     # Update the group permissions for a given group, folder and field.\r
171     # If <i>recursively</i> is true, update the child folders of the given folder too. \r
172     def update_group_permissions(folder_id_param, group_check_box_list, field, recursively)\r
173       # iteratively update the GroupPermissions\r
174       group_check_box_list.each do |group_id, can_do_it|\r
175         # get the GroupPermissions\r
176         group_permission = GroupPermission.find_by_group_id_and_folder_id(group_id, folder_id_param)\r
178         # Do the actual update if the GroupPermission exists;\r
179         # do not update the permissions of the admins group\r
180         # (it should always be able to do everything)\r
181         unless group_permission.blank? or group_permission.group.is_the_administrators_group?\r
182           case field\r
183           when 'create':\r
184             group_permission.can_create = can_do_it\r
185           when 'read':\r
186             group_permission.can_read = can_do_it\r
187           when 'update':\r
188             group_permission.can_update = can_do_it\r
189           when 'delete':\r
190             group_permission.can_delete = can_do_it\r
191           end\r
192           group_permission.save\r
193         end\r
194       end\r
196       # The recursive part...\r
197       if recursively\r
198         # Update the child folders\r
199         folder = Folder.find_by_id(folder_id_param)\r
200         if folder\r
201           folder.children.each do |child_folder|\r
202             update_group_permissions(child_folder.id, group_check_box_list, field, true)\r
203           end\r
204         end\r
205       end\r
206     end\r
208     # Copy the GroupPermissions of the parent folder to the given folder\r
209     def copy_permissions_to_new_folder(folder)\r
210       # get the 'parent' GroupPermissions\r
211       GroupPermission.find_all_by_folder_id(folder_id).each do |parent_group_permissions|\r
212         # create the new GroupPermissions\r
213         group_permissions = GroupPermission.new\r
214         group_permissions.folder = folder\r
215         group_permissions.group = parent_group_permissions.group\r
216         group_permissions.can_create = parent_group_permissions.can_create\r
217         group_permissions.can_read = parent_group_permissions.can_read\r
218         group_permissions.can_update = parent_group_permissions.can_update\r
219         group_permissions.can_delete = parent_group_permissions.can_delete\r
220         group_permissions.save\r
221       end\r
222     end\r
224     # Redirect to the Root folder and show an error message\r
225     # if current user cannot read in current folder.\r
226     def authorize_reading\r
227       # First check if the folder exists, if it doesn't: show an appropriate message.\r
228       # If the folder does exist, only authorize the read-rights if it's not the Root folder.\r
229       unless Folder.find_by_id(folder_id)\r
230         flash.now[:folder_error] = 'Someone else deleted the folder you are using. Your action was cancelled and you have been taken back to the root folder.'\r
231         redirect_to(:controller => 'folder', :action => 'list', :id => nil) and return false\r
232       else\r
233         super unless folder_id == 1\r
234       end\r
235     end\r
237     # Redirect to the Root folder and show an error message\r
238     # if current user cannot delete in current folder\r
239     def authorize_deleting\r
240       folder = Folder.find_by_id(folder_id)\r
241       unless @logged_in_user.can_delete(folder.id)\r
242         flash.now[:folder_error] = "You don't have delete permissions for this folder."\r
243         redirect_to :controller => 'folder', :action => 'list', :id => folder_id and return false\r
244       else\r
245         authorize_deleting_for_children(folder)\r
246       end\r
247     end\r
249     # Check the delete permissions for all the child folders of the given folder\r
250     def authorize_deleting_for_children(folder)\r
251       folder.children.each do |child_folder|\r
252         unless @logged_in_user.can_delete(child_folder.id)\r
253           error_msg = "Sorry, you don't have delete permissions for one of the subfolders."\r
254           if child_folder.parent.id == folder_id\r
255             flash.now[:folder_error] = error_msg\r
256           else\r
257             flash[:folder_error] = error_msg\r
258           end\r
259           redirect_to :controller => 'folder', :action => 'list', :id => folder_id and return false\r
260         else\r
261           authorize_deleting_for_children(child_folder) # Checks the permissions of a child's children\r
262         end\r
263       end\r
264     end\r