10377 Posts in 2192 Topics by 1709 members
| Go to End | Next > | |
| Author | Topic: | 1977 Views |
-
Re: Secure Files: securing personal files

5 October 2010 at 9:36am Last edited: 5 October 2010 9:38am
Hi,
It might be a bit risky trying to replicate the behaviour of CanViewSecured - better just to call it directly, but the solution will depend on a few things, like how many files there are and how much traffic you're likely to get.
The easiest way would be to simply return an object with all Files to the template and call CanView (CanViewSecured is really an internal API method), eg (these examples are untested):
// MODEL:
<?php
function getAllFiles() {
return DataObject::get('File');
}
?>// TEMPLATE:
<% if AllFiles %>
<% control AllFiles %>
<% if CanView %>
<p>Download <a href="$URL">$Name</a></p>
<% end_if %>
<% end_control %>
<% end_if %>However this is going to be database intensive, especially if you have lots of files or folders.
Another solution would be to test Folders instead of Files, then return the Files in Folders that the current Member can view:
// MODEL:
function getViewableFiles() {
$files = new DataObjectSet();
$folders = DataObject::get('Folder');
if(!$folders) return $files;
foreach($folders as $folder)
if($folder->CanView())
if($subFiles = DataObject::get('File', "ClassName != 'Folder' && ParentID = {$folder->ID}"))
$files->merge($subFiles);
return $files; // Should contain all files that the member can view.
}This will be more efficient that the first option, but it's still pretty hard on the database if there are a lot of folders.
The best option would probably be an extension that cached view permissions somehow, but that would be an advanced option if the above options were not suitable.
Hope this helps.
Hamish
-
Re: Secure Files: securing personal files

7 October 2010 at 11:01pm
Hamish, second solution didn't work (haven't tried first one). Something goes wrong with if($folder->canView()), because all available files in the Uploads folder are added tot $files. Have tried canView, CanView and canViewSecured.
-
Re: Secure Files: securing personal files

8 October 2010 at 11:48am
Ah, well you can use the property Secured to check if the current folder is marked secure and the method "InheritSecured()" to test if the and parent is secured, so modify:
...
foreach($folders as $folder)
if(!$folder->Secured && !$folder->InheritSecured())
continue;
if($folder->CanView())
.... -
Re: Secure Files: securing personal files

27 October 2010 at 4:59am
Jumping into this thread as it seems right up my alley. (Thanks for the link Hamish)
I have uncommented the line below:
// Assign file security by individual member:
DataObject::add_extension('File', 'SecureFileMemberPermissionDecorator');I have then gone into the backend and assigned the appropriate user permissions to the files. So far so good.
Then in my template I inserted this (InvestorPage.ss):
<% if AllFiles %>
<% control AllFiles %>
<% if CanView %>
<p>Download <a href="$URL">$Name</a></p>
<% end_if %>
<% end_control %>
<% end_if %>And into my php file i now have:
<?php
/**
* Defines the InvestorPage page type
*/
class InvestorPage extends Page {
static $db = array(
);
static $has_one = array(
'BannerImage' => 'Image',
);
static $has_many = array (
'File' => 'File',
);
function getAllFiles() {
return DataObject::get('File');
}
function getCMSFields() {
$fields = parent::getCMSFields();
$fields->removeFieldFromTab('Root.Content.Main','PagePhoto');
$fields->removeFieldFromTab('Root.Content.Main','Content');
return $fields;
}
}
class InvestorPage_Controller extends Page_Controller {
}It does sucessfully filter out other users files, but it shows every other file uploaded included site imagery etc. How can i remove all the excess and just show the contents of files within certain (secured) folders?
Sorry this is a Noob question, but im really learning quite rapidly here (bear with me!!!)
Thanks
Cano -
Re: Secure Files: securing personal files

27 October 2010 at 10:13pm Last edited: 27 October 2010 10:15pm
I have a feeling it has something to do with the CanView element...
<div class="typography">
<% if AllFiles %>
<% control AllFiles %>
<% if CanView %>
<p>Download <a href="$URL">$Name</a></p>
<% end_if %>
<% end_control %>
<% end_if %>
</div>Should it be...
<% if canViewSecured %>
rather than...???
<% if CanView %>
Cheers,
Hope this extra info shows that I'm at least trying! -
Re: Secure Files: securing personal files

29 October 2010 at 12:41pm
canView just calls canViewSecured (they operate slightly differently when extended, hence the seperation). Sounds like a solution be to additionally filter by files that are in secure folders, e.g. building on what you already have:
<% if AllFiles %>
<% control AllFiles %>
<% if InheritSecured %><% if CanView %>
<p>Download <a href="$URL">$Name</a></p>
<% end_if %><% end_if %>
<% end_control %>
<% end_if %>Basically it just checks the folder stack to see if it is in a tree that has been marked secure. That should filter out any other site assets that are sitting around in other folders.
-
Re: Secure Files: securing personal files

29 October 2010 at 11:56pm Last edited: 30 October 2010 12:15am
Perfect, you genuinly made me jump for joy with that one!
One last thing...if the files that the user has access to are in a variety of folders, is there a way to orgainse the files by these different folders? i.e. the attatched/linked screenshot? http://screencast.com/t/ouG5IX0LN
Here is my Investor Page...
class InvestorPage extends Page {
static $db = array(
);
static $has_one = array(
'BannerImage' => 'Image',
);
static $has_many = array (
'File' => 'File',
);
function getAllFiles() {
return DataObject::get('File');
}
function getCMSFields() {
$fields = parent::getCMSFields();
$fields->removeFieldFromTab('Root.Content.Main','PagePhoto');
$fields->removeFieldFromTab('Root.Content.Main','Content');
return $fields;
}
}
class InvestorPage_Controller extends Page_Controller {
}And the template (thanks to you!)...
<% if AllFiles %>
<% control AllFiles %>
<% if InheritSecured %><% if CanView %>
<p><a href="$URL">$Name</a></p>
<% end_if %><% end_if %>
<% end_control %>
<% end_if %>My file heirarchy is also attached.
Is there a way to say if in x folder - show files?
Ideally, the client may wish to add other folders so it would be good if the solution didnt rely on absolute paths (which is the method ive been trying)
-
Re: Secure Files: securing personal files

30 October 2010 at 1:48pm Last edited: 30 October 2010 1:49pm
You should probably build the data before pushing it to your template if you need sorting / nesting etc. Ie, a method on the page that does similar checks to those described above, but returns files in DataObjectSets that have the name of the folder. Something like:
function getFilesUserCanAccess() {
$result = new DataObjectSet();
$folders = array();
$files = DataObject::get('Files');
foreach($files as $file) {
if(empty($folders[$file->ParentID]))
$folders[$file->ParentID] = array(
'Folder' => $file->Parent(), // I think Parent() gets the file folder?
'Files' => array()
);
if($file->canView() && $file->InheritSecured())
$folders[$file->ParentID]['Files'][] = $file;
}
foreach($folders as $folder) {
$files = new DataObjectSet();
foreach($folder['Files'] as $file)
$files->push($file);
$result->push(new ArrayData(array('Folder' => $folder['Folder'], $files => $files));
}
return $result;
}Should be able to use it a template like:
<% control FilesUSerCanAccess %>
<p>$Folder.Name</p>
<% control Files %>
<p>$URL</p> // etc
<% end_if %>
<% end_control %>None of the above is tested.
| 1977 Views | ||
| Go to Top | Next > |


