Is it possible to integrate this function to the CCK FileField Module?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

starbow’s picture

this should probably be a feature request on the filefield queue.

1kenthomas’s picture

+1 subscribing.

Why an issue on filefield? What would it take to achieve compatibility?

ggr88’s picture

I'd like this too. Installed and moved files to private, but uploaded files on filefield are getting 403 forbidden.

ron_s’s picture

I'm also interested in this.

@starbow -- You mentioned on #1 that it should be shifted to the filefield module queue. Can you please explain why? Thanks!

blueskiwi’s picture

For anyone else who was scratching their head how to actually get the 'private' checkbox to show...

If you have D6 and FileField... this module doesn't work with those fields (I figured "I want to upload a file, I'll make a file field" and spent ages wondering why there was no option).

You don't make any extra field in your content type, you use the 'File Attachment' field available automatically on all content types if you have the Upload module installed.

It'd be great if this was integrated with the file field module...

ron_s’s picture

blueskiwi: You don't make any extra field in your content type, you use the 'File Attachment' field available automatically on all content types if you have the Upload module installed.

Well, this works fine if the File Attachment is a viable solution for you. However it's not the case for us.

The problem with File Attachment is it takes on the access permissions of the node. We provide all users with access to the node, but some content items on the node are available to all users, and other content items are only available to paid members. This is done using CCK field permissions.

The File Attachment is one example of an item which is only available to paid members. If we just attached it to the node as you are suggesting, it would be available to everyone. We need Filefield module for this, and we need Private Upload as an option integrated with Filefield. I'm not interested in converting our entire file system from public to private just to support these attachments.

attiks’s picture

FYI: http://drupal.org/node/353817

I just uses .htaccess files on a directory and works with filefield.

ron_s’s picture

@attiks: I'm confused how this solves the problem. First of all, Protected Download is a completely different module than Private Upload. As it states on the Protected Download project page:

Private Upload is designed to empower the editors to have full control over which files to be public or private. Protected Download is designed to work with Upload Path to "automagically" make attached files public or private depending on the node type. The two modules don't compete with each other, but provide two different solutions on two different needs.

I need the ability for editors to have full control over setting files to be private or public, and it *cannot* be dependent on node type. Private Upload is a better fit for this problem. Also the workaround being suggested, I'm not sure how it's related to this conversation. It is an Apache rewrite to gain access to files stored in a private directory. Can you explain how this provides the level of granular control available through Private Upload? Thanks.

attiks’s picture

@ron_s: You're absolutely right, my work-around only protects files based on directory, there's no way for an editor to control which file is private and which isn't, but for the moment it's the easiest method to make some files private when using filefield.

blueskiwi’s picture

@ron_s I am no expert on this module and am just sharing what I discovered in trying to get it to work...

Forgive me if I'm wrong but in my case with Private Upload it seems like what you want may be possible, ie the node is set to public but the attachment is set to private with the checkbox provided by PU.

My overall file system is set to 'public'. The node is public. The attachment link is visible, but the link goes to an 'access denied' page if you click it when not authorised.

In my case I also edited the node.tpl to hide the link for unauthorised users.

I've actually found since posting above I'm not too fussed about FileField integration, though if I was already using the attachments for some other purpose then I guess it would become necessary.

ron_s’s picture

@blueskiwi -- I have played around with this a bit and I think I have a solution that may offer the right level of granular control.

The missing piece of the puzzle for Protected Download is to use it along with CCK Field Permissions. This allowed me to put three FileField fields on my content type, one called "anonymous user file", a second called "registered user file", and a third called "subscriber file". I then created in the files directory a folder called report (for our unique content type), then subfolders within this called anonymous, registered, and subscriber. I set up the .htaccess files as noted in the Protected Download module.

In the Access Control, I'm then able to set permissions to the fields by role. It is somewhat of a pain because if we want to move a file from being only available for registered to being available for anonymous, we have to delete it from the registered FileField and re-attach it to the anonymous FileField. However at least it gives us the level of access that we want to share with various types of users.

It would be great if there was a way to change role access of a field on the content type, but this is probably for the owners of CCK to ponder.

k3vin’s picture

+1 subscribing.

jvieille’s picture

Not sure I get well the proposed solutions:

1) blueskiwi : using Private Upload
You said "... the node is set to public but the attachment is set to private with the checkbox provided by PU.
My overall file system is set to 'public'. The node is public. The attachment link is visible, but the link goes to an 'access denied' page if you click it when not authorised."

How do you get this bahaviour? When a file is ticked "Private", this means that its access will respect the node access itself: if the node is accessible, the file also is. So if the node is "public", i.e. made accessible to everyone, everyone can get the file, even if the file is ticked "Private".

2) ron_s : using filefield and .htaccess
- I suppose that you would use FileField Paths to manage your directories.
- You said "I set up the .htaccess files as noted in the Protected Download module"
So, the .htaccess just contains "Deny from all"
Is that enough to have Drupal allowing to access the file for anyone who is allowed to view the CCK FileField where the file is attached?

burningdog’s picture

Category: support » feature

I'm using a combination of upload, private_upload, upload_perm_per_type and ec_file to sell files on my site. I'd like to have the option of using either the normal "upload" way, or using FileField integrated with private_upload, because that way I can restrict uploads to a single file, rather than many (unless anyone knows if there's a module which restricts the number of files which can be attached to a content type? I think you have to hack core to get this right).

This is a feature request for private_upload, not for Filefield.

ron_s’s picture

2) ron_s : using filefield and .htaccess
- I suppose that you would use FileField Paths to manage your directories.
- You said "I set up the .htaccess files as noted in the Protected Download module"
So, the .htaccess just contains "Deny from all"
Is that enough to have Drupal allowing to access the file for anyone who is allowed to view the CCK FileField where the file is attached?

@jvieille: No need to use FileField Paths to manage directories, but you can if you like. All that is necessary is a simple .htaccess file with "Deny from all", and place it in the directory where you are going to regulate access using FileField and CCK Field Permissions.

You say, "Is that enough to have Drupal allowing to access the file for anyone who is allowed to view the CCK FileField where the file is attached?". I'm not sure what you are attempting to do. If you want to restrict the file access to specific Drupal roles, you need to use CCK Field Permissions module as I mentioned in #11.

ron_s’s picture

@Roger Saner: If you're selling files on your site, why not just use Ubercart's file download functionality? I've used it on other sites and works well. Even if you don't want to use Ubercart, the functionality you are requesting already exists. Maybe I'm misunderstanding your question, but I'm not sure how this is a feature request. Just follow what I did in #11 and it should meet your needs, without the need for private_upload.

As for restricting the number of files to be uploaded for a given CCK on a content type, I'm fairly certain FileField does this already. When you add a FileField CCK field to your content type, one of the options is to allow "Multiple values." If you do not have this selected, only one file can be added for that given field.

I think there is some functionality that could be added to FileField (not private_upload) which would help to enhance the capabilities. However right now there is a perfectly good solution on #11 that will achieve the granularity you wish for your site.

burningdog’s picture

Version: 5.x-1.0-rc2 » 6.x-1.0-rc2

@ron_s: Yes, I could use Ubercart's file download functionality, but I'm the maintainer of the file download module for the e-Commerce package and I'm figuring out out to extend its functionality to make it more useful for different use cases. How it's been built is on top of the upload module + private_upload, so it integrates into how Drupal normally handles file attachments. If I'd like to upload files using FileField I can't sell them, since private_upload doesn't integrate with FileField. And since Drupal's core upload module is a little...limited for certain use cases (like limiting the amount of uploaded files per node to 1, say) I'd like to provide options.

So your solution in #11 doesn't work for me, since that doesn't involve selling files. I'll take a look at how Ubercart implements file downloads - the last time I looked (about a year ago) it didn't allow for products to be CCK types, although I've heard that's changed.

So yes, this is still a feature request for Private Upload! And I can imagine other use cases where people would like to mark files as "Private" when uploaded with FileField.

burningdog’s picture

Version: 6.x-1.0-rc2 » 6.x-1.x-dev

@ron_s: your solution in #11 works if you'd like to permit access to a file based on a user's role, but I need to allow it per node.

ron_s’s picture

@Roger Saner: Well, technically you could have #11 work on a per node basis, although it would be rather messy. Would be necessary to create a separate user role per product node. Of course I wouldn't recommend doing this, but it is possible.

Another possible option you may want to investigate is similar to what Ubercart does with UC Node Access. Not sure if something like this already exists in eC? When a user pays and UC Node Access is in place, they gain access to a specified node. At the same time you could assign the user a special "download" role, which allows them to access the file from the FileField.

If someone does not have access to a specific node and the special download role, they will not be able to access the file. Just a thought.

burningdog’s picture

Title: Compatiblity to "FileField" » Compatiblity with FileField

Thanks ron_s, but UC Node Access doesn't grant any access to the node until it's bought, and I want to give the user access to the node, and any attached files, *except* files that are private and sellable. Only once the user has purchased the file can they download it - even though they have view permissions for that node all along.

SaxxIng’s picture

@jvieille: No need to use FileField Paths to manage directories, but you can if you like. All that is necessary is a simple .htaccess file with "Deny from all", and place it in the directory where you are going to regulate access using FileField and CCK Field Permissions.

I'm also really interested on this solution, but I can't reproduce your results!
I'm using filefield 3.1 and I have created two kind of fileds: one private_file (in sites/default/myfiles/private) and one public_file (in sites/default/myfiles/public). I have configured opportunely the field access permissions.
But, what I have to write in .htaccess?
On private directory I must insert an .htaccess and on your post I can understand you suggest to write only "Deny from all". But in this case also authorized users can't reach the file (Error 401 - Forbidden).
Have you really write only "Deny from all" on your .htaccess? Are you using some other modules other than filefild+cck_field_permissions ?
Thanks a lot for your help.
Saxx

ron_s’s picture

Saxx, is "sites/default/myfiles" your "files" directory that has 777 access? Or is "myfiles" something special? This needs to be in whatever directory you have configured in Drupal as your file system (in "admin/settings/file-system").

All you need is to create a .htaccess file which has "Deny from all" in it, and place this file in the subdirectory location in your file system. In Drupal you need to create a FileField on the content type, use CCK Field Permissions to open the new field to permission settings, and then set the access accordingly in your permissions.

SaxxIng’s picture

Hi ron_s,
I have tried exactly (hope) what you suggest, but on my system it doesn't work.
Perhaps I have tried another way (mixing various tips founded on the net) and it seems work quite well (it only use an .htaccess with a RewriteRule, and without Deny from all). Permissions to see are respected, as also are respected the permission to download when clicking on the link. More important, the permissions are respected also if someone known the correct url for a private url but has not permission to download. I have tested this on some browsers and on some conditions, and it seems to work well.
Perhaps, if possible, I really prefer to use a "deny from all" clause on the private directory because if drupal system temporary "dead" on site host, all protections are immediately null.
So, my situation is this:
- file system (as configured in "admin/settings/file-system")= sites/default/files (777)
- directory container for my filefield files: sites/default/files/myfiles
- directory for filefield file_private: sites/default/files/myfiles/private
- directory for filefield file_public: sites/default/files/myfiles/public
Permissions to view file_private only to registered users, and to view file_public to anonymous and registered users.
You suggest to insert an .htaccess with "Deny from all" in sites/default/files/myfiles/private correct?
And nothing other? Some special configuration on .htaccess on Drupal root?
Thanks a lot and regards,
Saxx

jwaxman’s picture

Did you ever solve this?
I don't seem to get this to work on my site either.

josepvalls’s picture

Jody Lynn’s picture

Status: Active » Closed (fixed)

Thanks josepvalis, that page gives good advice.

burningdog’s picture

Status: Closed (fixed) » Active

I fail to see how http://drupal.org/node/540754 solves this issue, which is about having Private Uploads being compatible with File Field, so that a "private" checkbox can be checked when a user uploads a file.

josepvalls’s picture

It really doesn't.
I had to face a similar issue myself.
What I did is to use the .htaccess in certain folders to restrict the access to certain files.
Requests to those files will be handled by drupal and then you could implement the hook_file_download to deny acces based on roles or checkboxes or whatever.
I wanted to allow individual permissions on certain files (similarly to your checkbox) and I had some problems in the beginning with the previous methof, so what I did is a module that allows the download of certain files through a special url (hook_menu), checking your criteria and then sending the file to the browser. There is an API for that.

hosais’s picture

Title: Compatiblity with FileField » Title: After Granted in Filefield module, the file still not authorzied.
Version: 6.x-1.x-dev » 6.x-1.0-rc2
Category: feature » support
Priority: Normal » Critical

Hi,

Title: After Granted in Filefield module, the file still not authorzied.

I am using private upload. I uploaded a file through filefield module. The file was directing to private directory by field-path. The file was saved correctly. However, when I try to download the file. I am not authorized to access.

I traced the hook_download() in filefield.module (with echo and die method). The file is actually granted the access. However, after return the file info/header..., the file is still NOT authorized in the end???

The user is admin. All the permmissions are allowed. Durpal 6.16 and filefield 6.x-3.2.

How can I check further what is the problem?

thanks.

hosais

Note: I also post this at book page: http://drupal.org/node/540754

hosais’s picture

Title: Title: After Granted in Filefield module, the file still not authorzied. » Compatiblity with FileField: private_upload cannot work with filefield without modification of code.
Priority: Critical » Normal

I finally found the problem.

It is because in Private_upload.module the hook of download. If I change "return -1" to "return", then it works perfectly for the files uploaded by CCK-filefield into the priavte area (directory). Of course, this is not a solusion since all the attached file will not have access control at all.

With a little more code tracking, I realized that there is no information related to filefield upload in the Database, if I upload files with CCK-filefield. Therefore, with

$result = db_query("SELECT DISTINCT(u.nid) FROM {upload} u INNER JOIN {files} f ON u.fid = f.fid ".
"WHERE f.filepath = '%s'", $filepath);

$result will be empty and hence all the downloading is blocked no matter who is the user (even admin).

With this conclusion, private upload cannot work with filefield without modification of code. Since paivate file attachment is not importatn to me, to have access control for file of the filefield. My solusion right now is disable private upload and:

1) Put an .htaccess in a private directory to give access control to Drupal.
2) Use filefield_path to set private directory of the protected filefield so that the upload files of the protected filefield go to the private direcotry.

If anyone thinks something wrong about the solusion, please let me know.

hosais

============================
The hock of file download() in private upload module.
============================

function private_upload_file_download($file) {
$private_dir = variable_get('private_upload_path', 'private');
if(_private_upload_starts_with($file, $private_dir)) {
$filepath = file_create_path($file);
$result = db_query("SELECT DISTINCT(u.nid) FROM {upload} u INNER JOIN {files} f ON u.fid = f.fid ".
"WHERE f.filepath = '%s'", $filepath);

while($row = db_fetch_array($result)) {
$node = node_load($row['nid']);

if (node_access('view', $node)) {
return; // Access is ok as far as we are concerned.
}
}

return -1; // No nodes are granting access, so veto download. <--- CHANGE THIS to return;
}
}

mayerwin’s picture

Subscribing

pumpkinkid’s picture

So what is the status of this?

Does private_upload work with filefield?

hus-’s picture

I am wondering the same thing.

YesCT’s picture

subscribing

tbenice’s picture

Hi All,

I'm sure that we can address this. I'll work on the checkbox part later because I don't use the checkbox. But for the file access part, I suggest downloading/activating private_downloads and setting the private directory to the same as used in private_uploads (it's actually default). Saving configuration in the former adds the needed htaccess to the private dir, and you can set which roles have permission to access private files at all.

Then, for the upload module, the private_upload module works fine for checking on files attached to nodes via upload module. For Filefield, the Filefield module does a fine job of access checking in private mode ( see filefield_file_download($file) ) which is the same as files in the private dir with the htaccess (private_downloads) in place. So, all we have to do is make sure that private_upload doesn't send -1 in the file_download hook indiscriminately. #30 is almost on the mark, but the problem is it seems to negate any access check for private_upload.

I've attached a patch that does the job for me. I check the query result in private_upload_file_download to see if there were any results. This lets us know if the file was attached with the upload module. If there were no results then we simply return to pass access check on to Filefield etc.

To so recap:
1) download and install/configure private_download
2) patch private_upload to fix indescriminate return of -1 in the file_download hook
3) set any 'private' filefields to save files in the private dir (default just type 'private' into the path field of the filefield config form)

---- since they go together, I wonder if anyone would be interested in merging file download and file upload. I bet there's a thread out there on that subject.

tbenice’s picture

Hang on, that patch was messed up. Here it is again.