Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

All other Modules /

Discuss all other Modules here.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Secure Files: securing personal files


Go to End


22 Posts   5942 Views

Avatar
Judge

Community Member, 79 Posts

11 July 2010 at 10:11pm

I am looking for a way to secure an individual's files, and am hoping the the Secure_Files module will do this.

I would like users to be able to upload their own files and have full, unrestricted, access to those files. Those files should not be available to any other user through the standard front-end. So the URL for a file uploaded by user A will allow user A to download that file at any time they are logged in. User B trying to access the file through the same URL would not be able to access that file.

So long as the files are stored in the standard SilverStripe back-end, then I can handle other access methods (moderators, administrators etc. can see and access various files through my own rules).

Is this the kind of thing the Secure_Files module can do out of the box? Or do I need to add my own customisations to achieve this? It is effectively linking a file to an owner and giving that owner full rights to that file, with no open back doors allowing other users to access those files.

-- Jason

Avatar
Judge

Community Member, 79 Posts

13 July 2010 at 8:18am

I haven't been able to get this module to work with my 2.4 yet, but looking at the screenshots in the information pages, it looks like it does not do what I want out of the box. This module is used to secure whole directories. While it can be used to prevent "back door" access to a directory where I have users store their files, I will still need to write my own module that provides a finer level of permissions within that directory, by automatically locking down *files* (not just directories) to their individual owners, i.e. uploaders.

-- Jason

Avatar
Hamish

Community Member, 712 Posts

14 July 2010 at 10:13pm

Hi there,

It is very easy to extend the module to do this. See the developer tips in the extension README, but in particular:

Create new access methods by decorating File and
implementing the canViewSecured method. If it returns
true access to the file is granted

So, basically all you need is a new decorator with a method canViewSecured that returns true if the logged in user is the uploader. All you have to do is mark the uploads folder (or a particular folder you have restricted uploads to) as secure and the module will do the uploader check when the file is requested.

Regards

Hamish

Avatar
Judge

Community Member, 79 Posts

14 July 2010 at 10:22pm

Edited: 14/07/2010 10:23pm

Sounds great - thanks Hamish.

Along with this I think I will need to extend one of the file upload widgets so that it is able to put the files into date-related folders (a bit like WordPress does). This is just to keep the number of files in each folder down to a reasonable size. Another approach would be to use the ID of the file as a directory e.g. file ID 12345 could be stored in folder 000/012/ (divide by 1000, pad to 6 digits, split the folder in the middle), which would give up to a thousand folders, each with a further thousand folders and each containing up to a thousand files. Space for a billion files should be enough ;-)

-- Jason

Avatar
Hamish

Community Member, 712 Posts

14 July 2010 at 10:24pm

Dated folders would be great for uploading media files, make sure you post us the code =)

Avatar
Judge

Community Member, 79 Posts

14 July 2010 at 10:28pm

Edited: 14/07/2010 10:29pm

Sure. I'll dig it out - managed it sometime last year, but then got side-tracked onto other things, but the code is around somewhere. From what I remember it was only a few lines of code, albeit in the core, because SS does all the magic of creating the directories, nested to whatever level is needed.

-- Jason

Avatar
klikhier

Community Member, 150 Posts

5 October 2010 at 6:44am

Hamish,

As I'm not familiar with DataObjectDecorators, hopefully you could help me out.

On a certain page page, I would like to show a list of all secure files that CurrentMember() is allowed to download. Could you please provide me with some more details on which files to create and how to approach this problem. I was thinking of something like (from my designers point-of-view):

1. Get all files from the database (DataObject::get)
2. Go through them one-by-one and check if CurrentMember() is allowed to see (canViewSecured())
3. Return DataObject to the template

Please help, many thanks in advance!

Avatar
klikhier

Community Member, 150 Posts

5 October 2010 at 7:08am

PS. This is what I've come up with sofar:


	public function getAvailableDownloads() {

		$memberid = Member::currentUserID();

		if($memberid) {
		
			// Get all groups containing this member
			$groups = DataObject::get("Group",
				"`MemberID` = $memberid",
				"",
				"LEFT JOIN `Group_Members` ON `Group_Members`.GroupID = `Group`.ID",
				""		
			);
			
			// Create filter to get all secured folders with current MemberID and GroupID(s)
			$filter = 'MemberID = ' . $memberid;
			foreach($groups as $group) {
				$filter .= ' OR GroupID = ' . $group->ID;
			}
			
			// Get applicable secured folders
			$folders = DataObject::get("File", 
	          $filter, 
	          "",
	          "
	          	LEFT JOIN `File_MemberPermissions` ON `File`.ID = `File_MemberPermissions`.FileID	
		          LEFT JOIN `File_GroupPermissions` ON `File`.ID = `File_GroupPermissions`.FileID
	          ",
	          ""
	         );
	    
	    if($folders) {

		    // Create filter to get all files within the secured folders
		    $i = 0;
		    $filter = '';
				foreach($folders as $folder) {
					if($i != 0) $filter .= ' OR ';
					$filter .= 'ParentID = ' . $folder->ID;
					$i++;
				}
			
				// Get all files in these folders
				$files = DataObject::get("File",
					$filter,
					"",
					"",
					""
				);
		
				// Return files
				return $files;

			}
		}
	}

Go to Top