Jump to content
Wanze

FieldtypeSecureFile

Recommended Posts

The module is working quite nicely, but I cannot click on the file in the backend anymore even though I'm superuser and editor, which I gave download from admin rights.

Edit: Would it be possible to look at the ListerPro styling for the field? 

  • Like 1

Share this post


Link to post
Share on other sites
The module is working quite nicely, but I cannot click on the file in the backend anymore even though I'm superuser and editor, which I gave download from admin rights.

I can't reproduce this problem here locally, with the latest dev version. Could you tell me the Pw version and Browser? Thanks!

Edit: Would it be possible to look at the ListerPro styling for the field? 

Of course. I also fixed the bug with the help of your solution on GitHub. I'll add some more options to the module and will push everything on GitHub this evening or tomorrow.

Share this post


Link to post
Share on other sites

I've gone back to a normal file field by now, as the site needs to work fully on monday, but it was 2.6.17/19 and Chrome. 

Share this post


Link to post
Share on other sites

Another problem:

Cannot upload files with the latest version 1.0.1 of secure files.

I have detected that upload of files is no longer possible with this field type in my case. I cannot point out the exact time when this problem starts because I havent upload secure files for a longer time. In the meantime I have updated PW more times. The upload has worked in the past but now I get the error message, that the folder doesnt exist or is not writeable.

I store all the files in the folders var/securefiles and these folders exist:

post-2257-0-16116800-1449055064_thumb.pn

post-2257-0-00387700-1449055078_thumb.pn

All folders has the permission 777 for testing purposes

My settings of the input field:

post-2257-0-73767500-1449055134_thumb.pn

And this is what I got if I had tried to upload a file:

post-2257-0-22903500-1449055172_thumb.pn

Help would be appreciated

Best regards

Share this post


Link to post
Share on other sites

Hi Juergen,

v 1.0.1 works fine here on the latest dev. What version of ProcessWire are you using?

From your screenshots it looks like the "var" folder is inside the root folder of ProcessWire. You should create your folder "securefiles" inside /var/, which lies on the root of your harddisk, outside of the web-root. Not sure if this is the problem, as you pointed out that everything worked before. But the message you're seeing is an exception of my module, thrown here: https://github.com/wanze/FieldtypeSecureFile/blob/master/FieldtypeSecureFile.module#L69

This indicates that the folder does not exist or is not writable.

Cheers

Share this post


Link to post
Share on other sites

Hello Stefan,

I am using the latest dev 2.7.2 and PHP 5+. The var-folder is in the root, but this was not a problem at all.

Here are some screenshots of uploaded files in the past, which are still located in the folder:

post-2257-0-57066100-1449126130_thumb.pn

post-2257-0-70823700-1449126142_thumb.pn

As you can see the files are still there.

As I pointed out - the folders have permission 777 (only for testing) so they are writeable in any case and they are still there.

Best regards Jürgen

Share this post


Link to post
Share on other sites

Are you sure that you ftp program does show the full path? What's the output of $config->paths->root? I can hardly imagine a server to have the full filesystem in the webroot.

  • Like 2

Share this post


Link to post
Share on other sites

Hi Jürgen,

As LostKObrakai says, I guess your FTP programm shows the directory of your web-root as root, so the path you entered in the config is not correct.

The purpose of this module is that the files are stored outside of the web root. From your screenshot it looks like your "var" folder is beside ProcessWire's "site" folder, this would still be inside your web-root.

  • Like 1

Share this post


Link to post
Share on other sites

Thanks Wanze and LostKobrakai,

I changed the path to /home/.sites/24........ (absolute path) and now it works. It was a path problem. Why it works in the past with the old path - ?????

Problem solved! :)

Best regards

  • Like 1

Share this post


Link to post
Share on other sites

Hello together,

I´m a bit confused about doing the output of the securefile respectively securefiles...
 
Wanze wrote this code: 
if ($input->get->download == 1) {
  $yourSecureFile->download();
}

Now I'm a little overstrained and need your help.

I build a template at the frontend for secure files and I generate the current output with this code 

$content = $page->body;
$pdffiles = wire("page")->file;
foreach ($pdffiles as $pf) {
    $content .= "<a href='' title='{$pf->name}'>$pf->name</a>  ($pf->filesizeStr)<br />";
}

but how can I now tell this link which of the secure files the user wants?

This is the current output...

post-644-0-04013300-1457296196_thumb.png

 
 
Thank you for any hint
Ralf

Share this post


Link to post
Share on other sites

Hi Ralf,

I would do this by passing the internal position of the file in the array, e.g.

foreach ($pdffiles as $i => $pf) {
    $content .= "<a href='{$page->url}?fid={$i}' title='{$pf->name}'>$pf->name</a>  ($pf->filesizeStr)<br />";
}

Then you can grab the file with this ID:

if ($input->get->fid) {
  $file = $page->file->eq((int) $input->get->fid);
  if ($file) {
    $file->download();
  }
}

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

@Ralf

That's exactly the key of this module. There is no url associated with each file, hence the secure nature. You can only "request" the file to be sent to the browser by $file->download() in your code. How the user can request the file from the website is up to you, like Wanze showed above.

  • Like 1

Share this post


Link to post
Share on other sites

Hey Wanze,

Are the files for individual pages stored in a directory named the same as the page ID — like a core files field?

#lazyweb

Share this post


Link to post
Share on other sites

Yep. It's essentially moving the files folder to a non accessable folder. Everything inside the folder does stay the same.

  • Like 3

Share this post


Link to post
Share on other sites

@reno

Yep, it also respects the $config->pagefileExtendedPaths setting, e.g. it creates a folder for each page ID or a nested folder structure, if the setting is enabled.

Cheers

  • Like 4

Share this post


Link to post
Share on other sites

Perfect. I have a few different scenarios right now that need secure files.

I think this module will handle at least one of them seamlessly.

Much appreciated Wanze!

  • Like 1

Share this post


Link to post
Share on other sites
I think this module will handle at least one of them seamlessly.

You're welcome! Let me know if you need additional features that would fit into this module.

  • Like 2

Share this post


Link to post
Share on other sites

hi wanze,

would it be possible to change the markup a little bit? i got a message that my sorting module ( https://processwire.com/talk/topic/13064-inputfieldfile-image-sorting-autosorting/ ) does not work with your securefile fieldtype. the problem is, that my module sorts the files based on the selector:

tinysort(field.find('li.InputfieldFileItem'), {selector:'a.InputfieldFileName', attr:'title', order:direction}); 

and you are modifying this markup here: https://github.com/wanze/FieldtypeSecureFile/blob/master/FieldtypeSecureFile.module#L98

one solution would be to create a different selector for your fieldtype... i failed when trying to find a solution. would it be possible to modify your markup to an anchor:

<a class="InputfieldFileName" title="thefilename.ext">...</a>

thanks

  • Like 1

Share this post


Link to post
Share on other sites

This might be useful to anyone trying to convert a (single) existing file field to a secure one, while maintaining integrity of other file fields on the same pages.

Put a file with this content in pw's root directory and run it from the terminal:

<?php
include "index.php";

// allow for: $ php filename.php fieldName
$fieldName = !empty($argv[1]) ? $argv[1] : 'file';

$field = $fields->get($fieldName);
$usedInTemplates = $field->getTemplates();

$fp = fopen('files.txt', 'w');

// the use() statement allows for both pre and post pw 3.0 usage without change/compiler
$eachPageUncache = function($selector, callable $callback) use ($pages)
{
	$num = 0;
	$id = 0;
	while (true) {
		$p = $pages->get("{$selector}, id>$id");
		$id = $p->id;
		if(!$id) break;
		$callback($p);
		$pages->uncacheAll($p);
		$num++;
	}
	return $num;
};

try {
	// Alternatively use findMany and a foreach on PW 3.0.19+
	$eachPageUncache("template=$usedInTemplates, include=all, check_access=0", function($page) use($fp, $fieldName, $config) {
		$files = $page->getUnformatted($fieldName);
		foreach ($files as $file) {
			$path = str_replace($config->paths->files, '', $file->pathname);
			fwrite($fp, $path . PHP_EOL);
		}
	});
} finally { // PHP 5.5+
	fclose($fp);
}

Then you can use the created files.txt to copy files to their new location (add --remove-source-files to also remove the source files). 

rsync -v \
--files-from=PW_ROOT_PATH/files.txt \
PW_ROOT_PATH/site/assets/files NEW_LOCATION_PATH

Switch the file field to be a secure file field and all files should still work.

  • Like 5

Share this post


Link to post
Share on other sites

Is it possible to use relative paths in storageLocation? I have different environment on local/live servers and it would be nice to have same value.

Something like this:

//$storageLocation = rtrim($field->get('storageLocation'), '/') . '/';
$storageLocation = realpath($field->get('storageLocation')) . DIRECTORY_SEPARATOR;

 

  • Like 1

Share this post


Link to post
Share on other sites

@k07n

Makes sense, I will update this and release a new version tomorrow.

Cheers

  • Like 2

Share this post


Link to post
Share on other sites
On 03.03.2017 at 0:39 AM, Wanze said:

@k07n

Makes sense, I will update this and release a new version tomorrow.

Cheers

@Wanze any success on this?

  • Like 1

Share this post


Link to post
Share on other sites

@k07n

I tried to use realpath but it is failing to resolve my relative paths. How would you expect this to work, would you enter relative paths from the ProcessWire root or the document root?  Could you give an example? Thanks.

Cheers

Share this post


Link to post
Share on other sites

@Wanze I'm using 

$storageLocation = realpath(wire('config')->paths->root . $field->get('storageLocation')) . DIRECTORY_SEPARATOR;

and 

./../secure_files/

in Storage Location prefs.

And I get "D:\osp\domains\secure_files\" on dev env and "/var/www/sitename/secure_files/" on live.

  • Like 1

Share this post


Link to post
Share on other sites

@k07n

Thanks for the examples, i just pushed a commit to the master branch implementing this (version 1.0.2).

Cheers

  • Like 2

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   1 member

  • Similar Content

    • By bernhard
      --- Please use RockFinder3 ---
    • By MoritzLost
      Cacheable Placeholders
      This module allows you to have pieces of dynamic content inside cached output. This aims to solve the common problem of having a mostly cacheable site, but with pieces of dynamic output here and there.  Consider this simple example, where you want to output a custom greeting to the current user:
      <h1>Good morning, <?= ucfirst($user->name) ?></h1> This snippet means you can't use the template cache (at least for logged-in users), because each user has a different name. Even if 99% of your output is static, you can only cache the pieces that you know won't include this personal greeting. A more common example would be CSRF tokens for HTML forms - those need to be unique by definition, so you can't cache the form wholesale.
      This module solves this problem by introducing cacheable placeholders - small placeholder tokens that get replaced during every request. The replacement is done inside a Page::render hook so it runs during every request, even if the response is served from the template cache. So you can use something like this:
      <h1>Good morning, {{{greeting}}}</h1> Replacement tokens are defined with a callback function that produces the appropriate output and added to the module through a simple hook:
      // site/ready.php wire()->addHookAfter('CachePlaceholders::getTokens', function (HookEvent $e) { $tokens = $e->return; $tokens['greeting'] = [ 'callback' => function (array $tokenData) { return ucfirst(wire('user')->name); } ]; $e->return = $tokens; }); Tokens can also include parameters that are parsed and passed to the callback function. There are more fully annotated examples and step-by-step instructions in the README on Github!
      Features
      A simple and fast token parser that calls the appropriate callback and runs automatically. Tokens may include multiple named or positional parameters, as well as multi-value parameters. A manual mode that allows you to replace tokens in custom pieces of cached content (useful if you're using the $cache API). Some built-in tokens for common use-cases: CSRF-Tokens, replacing values from superglobals and producing random hexadecimal strings. The token format is completely customizable, all delimiters can be changed to avoid collisions with existing tag parsers or template languages. Links
      Github Repository & documentation Module directory (pending approval) If you are interested in learning more, the README is very extensive, with more usage examples, code samples and usage instructions!
    • By Craig
      I've been using Fathom Analytics for a while now and on a growing number of sites, so thought it was about time there was a PW module for it.
      WayFathomAnalytics
      WayFathomAnalytics is a group of modules which will allow you to view your Fathom Analytics dashboard in the PW admin panel and (optionally) automatically add and configure the tracking code on front-end pages.
      Links
      GitHub Readme & documentation Download Zip Modules directory Module settings screenshot What is Fathom Analytics?
      Fathom Analytics is a simple, privacy-focused website analytics tool for bloggers and businesses.

      Stop scrolling through pages of reports and collecting gobs of personal data about your visitors, both of which you probably don't need. Fathom is a simple and private website analytics platform that lets you focus on what's important: your business.
      Privacy focused Fast-loading dashboards, all data is on a single screen Easy to get what you need, no training required Unlimited email reports Private or public dashboard sharing Cookie notices not required (it doesn't use cookies or collect personal data) Displays: top content, top referrers, top goals and more
    • By daniels
      This is a lightweight alternative to other newsletter & newsletter-subscription modules.
      You can find the Module in the Modules directory and on Github
      It can subscribe, update, unsubscribe & delete a user in a list in Mailchimp with MailChimp API 3.0. It does not provide any forms or validation, so you can feel free to use your own. To protect your users, it does not save any user data in logs or sends them to an admin.
      This module fits your needs if you...
      ...use Mailchimp as your newsletter / email-automation tool ...want to let users subscribe to your newsletter on your website ...want to use your own form, validation and messages (with or without the wire forms) ...don't want any personal user data saved in any way in your ProcessWire environment (cf. EU data regulation terms) ...like to subscribe, update, unsubscribe or delete users to/from different lists ...like the Mailchimp UI for creating / sending / reviewing email campaigns *I have only tested it with PHP 7.x so far, so use on owners risk
      EDIT:
      Since 0.0.4, instructions and changelog can be found in the README only. You can find it here  🙂
      If you have questions or like to contribute, just post a reply or create an issue or pr on github, thanks!
    • By MoritzLost
      Sorry for the convoluted title. I have a problem with Process modules that define a custom page using the page key through getModuleInfo (as demonstrated in this excellent tutorial by @bernhard). Those pages are created automatically when the module is installed. The problem is that the title of the page only gets set in the current language. That's not a problem if the current language (language of the superuser who is installing the module) is the default language; if it isn't, the Process page is missing a title in the default language. This has the very awkward effect that a user using the backend in the default language (or any other language) will see an empty entry in the setup menu:

      This screenshot comes from my Cache Control module which includes a Process page. Now I realize the description sounds obscure, but for us it's a common setup: We a multiple bilingual sites where the default language is German and the second language is English. While the clients use the CMS in German, as a developer I prefer the English interface, so whenever I install a Process module I get this problem.
      As a module author, is there a way to handle this situation? I guess it would be possible to use post-installation hooks or create the pages manually, but I very much prefer the declarative approach. The page title is already translatable (through the __ function), but of course at the time of installation there is no translation, and as far as I'm aware it's not possible to ship translations with a module so they are used automatically. Could this situation be handled better in the core? I would prefer if the module installation process would always set the title of the Process page in the default language, instead of the language of the current user.
×
×
  • Create New...