DrQuincy Posted November 13 Posted November 13 In a template you can enable: Prevent direct access to file assets owned by pages using this template? And in site/assets the folder of that page has a minus prefix added so Apache tells PW to handle the file request. I have a situation where I want the top level page to have no access control but I also have a series of files where I need access control. I.e. it's a mix. I'm just wondering if I make the files be part of a repeater, can I set access control for the repeater only since it has its own ID. Will this work? I would guess that it does but I wanted to see if anyone has used this approach in production.
monollonom Posted November 13 Posted November 13 2 hours ago, DrQuincy said: I'm just wondering if I make the files be part of a repeater, can I set access control for the repeater only since it has its own ID. Will this work? Funnily I tried exactly this yesterday and no unfortunately it doesn’t work because the repeater will check the access control of the page holding it. However it could a request to add a line to check if its access control is on, something like: public function getAccessTemplate($type = 'view') { if($this->template->useRoles) return $this->template; $p = $this->getForPageRoot(); return $p->id ? $p->getAccessTemplate($type) : parent::getAccessTemplate($type); } I tried and it worked but it wasn’t a fit in the end for what I was trying to achieve. 1
DrQuincy Posted November 14 Author Posted November 14 Thanks for that, and what a happy coincidence! I'm not sure I want to edit the core at this point but I appreciate your code snippet. I think my other idea is going to take a bit more work but can be done with hooks: Create a child template with access control and file field Add Integer Unique field to store parent page ID Add Pages::save hook to create and save child page (check for its existance first and create a new one if needed) Add a ProcessPageEdit::buildForm on the parent template to add the access controlled field to the edit form Add a Pages::delete hook to delete the child page when the parent page is deleted I think that should do it. I'll have to try it out though. I was hoping there'd be a simpler solution!
Robin S Posted November 15 Posted November 15 @DrQuincy, responding to the title of the topic: PW allows for access control at the field level as well as the template level. I don't think you need to do anything special with repeaters or child pages to achieve what you're describing. In your template settings: Do you want to manage view and edit access for pages using this template? > Yes Allow view access for "guest", seeing as you generally want the page to be viewable by everyone. Prevent direct access to file assets owned by pages using this template? > Yes always, regardless of page status or access control In the fields listing for the template, click to edit the files field in template context. Enable access control for the field and remove view access for "guest" (and any other roles who are not allowed to view the files). Now guest users will be able to view the page, but not access the files. 2
DrQuincy Posted November 16 Author Posted November 16 Thanks @Robin S I will try this and report back. It might not be for a week or so as I have another project to finish first. To be honest, in all my years of using ProcessWire, I have never really worked with access control at the field level, only the template. But it seems like this is the kind of quick, simple and elegant solution you would expect from ProcessWire. I'm glad I posted here as my solution was way too convoluted! 😉
DrQuincy Posted Monday at 09:11 AM Author Posted Monday at 09:11 AM I've now tried this out. Quote Now guest users will be able to view the page, but not access the files. @Robin S This is true but it seems to apply to all image and file fields assigned to the template. In this template I have an images field and a files field. I want the template and everything in it to be accessible by all roles except the files field. I have followed the instructions above. Template: everyone has view access, Prevent direct access… is set to Yes always… Files field: Access set to view for everyone except guest Image field: I tried this as is (manage acess control = No) but that didn't work so I explicitly set everyone to View What happens is PW adds a minus to the site/assets/files folder indicating access control but it seems to be doing it to all fields regardless of how the individual file and image fields are set. Is this expected or have I missed something out? Thanks.
Robin S Posted Monday at 09:24 PM Posted Monday at 09:24 PM @DrQuincy, for the image field that you want everyone to be able to view you should enable access control and grant view access to guest. It's normal for the folder to have the hyphen prefix - that is how PW knows to manage access control for the files on that page via PHP rather than allowing direct file access. If you've given view access to a role for a files/images field then PW will take care of serving the files to that role even though the URL (deliberately) does not match the real file path. If by any chance you are using the Delayed Image Variations module you'll need to upgrade to v0.1.6 to get support for secure Pagefiles.
DrQuincy Posted Tuesday at 03:51 PM Author Posted Tuesday at 03:51 PM Thank you @Robin S I'm pretty sure I did as you said and it didn't work but I have just gone back through. Template set to full access control Images field set to access control but View checked on all roles inc. guest Files field set to access control but View checked on all roles excl. guest And I have accessed the assets in a different browser not logged in and the images can be accessed but not the files. Perfect! My next question is, some of these pages will have a lot of images (20+) and each one of this will now create a new PHP/ProcessWire thread. Now I have got this working, I am worried about overloading the server. Has anyone much experience with this? I wonder if I should: Load the images one-by-one using JavaScript Each time a page is loaded for the first time after being saved copy the images to a public folder before the page is rendered Any other ideas? EDIT: I'm actually thinking make all assets public, prefix restricted ones with “restricted--” or something, block files with that prefix using .htaccess and then create a PHP file (restricted-file.php?file=foo.pdf&page-id=9999) that bootstraps PW and loads the file. I think that would be fairly simple and as light as can be on resources.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now