Encrypt PDF

Contrib type: 
Module
Status: 
Uploaded for testing
Latest version: 
5.x-0.2

Downloads

Compatibility: 
Ubercart 1.x

This module encrypts PDF file download products.

This is more of a proof of concept than a fully-fledged module, but it does work and is live on my own Ubercart site.

When enabled, this module intercepts the download of any file product with a '.pdf' extension and substitutes an encrypted version.

The encryption is set as follows:

1) All PDF restrictions are enabled (i.e. no printing, changing, copying, commenting etc.)
2) Title metadata is set to the Description field of the file
3) Author metadata is set to the name of your Drupal site
4) Keywords metadata is set as follows: "Copyright held by *your Drupal sitename*. This document may not be amended, copied or distributed without express written permission. Originally downloaded from *your Drupal site URL* via IP address *IP address of downloader* at time *time and date of download* by user *username of downloader* with email address *email address of downloader*"
5) A page is prepended to the PDF with the same data as the Keywords metadata.

Current issues:

1) It's currently all or nothing. When enabled all PDF file products are encrypted. Would like to introduce per-product optionality.
2) No optionality on how the PDF is encrypted. There could be many options, such as setting a PDF user password, setting a PDF admin password (currently randomly generated), what exactly to put in the PDF metatdata fields, whether or not to include the prepended copyright page and what the text should be, printing enabled/disabled, etc. etc. It's hard coded right now to give the strongest protection possible but eventually this should all be configurable by the user.
3) You have to manually create a temp directory to write the encrypted PDFs into prior to download, and a cron job to clear them up. I assume I could bypass all this using tempnam() somehow. Thoughts welcome on that please, I'm not that clear on how persistent files written by tempnam() are (do they automatically get deleted after a while?)
4) Since it uses PHP classes rather than libraries, it will be memory intensive when encrypting large PDFs. I have no idea how big a PDF can be encrypted or how many simultaneous encrytion operations can occur before you max out the memory limit of a typical webhost server. I have successfully tested this on PDFs up to 10mb but that was one at a time...

PreviewAttachmentSize
uc_pdf_encrypt-5.x-0.2.tar.gz49.28 KB
Shawn Conn's picture
Offline
Administrator
Joined: 08/07/2007
Juice: 916
Function Declaration

From line 15:

<?php
function uc_pdf_encrypt_file_transfer_alter (){
?>

The problem you're encountering with $file_user being empty is that you do not have the arguments declared in the function declaration. Change line 15 to:

<?php
function uc_pdf_encrypt_file_transfer_alter($file_user, $ip, $fid, $file) {
?>

This will make sure you can use all the arguments that hook_file_transfer lets you use. Refer to the API page for more information on its use.

-Shawn Conn: If the Name Don't Rhyme It Ain't Mine

strikedo's picture
Offline
Joined: 02/06/2008
Juice: 45
Re: Function Declaration

Thanks Shawn. I'd already caught and fixed that in the interim, but still no dice.

The FPDF function requires a string to be passed. I tried this:

$$encrypted_path = variable_get('uc_file_base_dir', NULL) . strval(time()) . $file_user;
$pdf->Output($encrypted_path, 'F');

No dice. The file is just called TIMESTAMP. Tried to force a string conversion:

$$encrypted_path = variable_get('uc_file_base_dir', NULL) . strval(time()) . strval($file_user);
$pdf->Output($encrypted_path, 'F');

And still no joy. But if I do this:

$$encrypted_path = variable_get('uc_file_base_dir', NULL) . strval(time()) . 'TESTTESTTEST';
$pdf->Output($encrypted_path, 'F');

Then the file is out put as TIMESTAMPTESTTESTTEST

Which seems to suggest that somehow $file_user is empty?

Works fine passing IP address and FID.... I'm a real PHP amateur and I'm wondering what kind of variable $file_user is? Is it an array, a string or...? Sorry for the nooby questions....

Cheers,

Marco

Shawn Conn's picture
Offline
Administrator
Joined: 08/07/2007
Juice: 916
Re: Re: Function Declaration

Another glance at the API doc made me realize the documentation was incorrect on the $file_user, it has been updated. The $file_user variable is a database row object from the uc_file_users table that corresponds with the user download being transfered. You can view its fields by viewing the structure of the uc_file_users table in phpMyAdmin or by doing a print_r($file_user) in PHP. Trying to concatenate a object in a string should result in some sort of PHP error, though depending on your PHP setup, the error might not be showing itself.

-Shawn Conn: If the Name Don't Rhyme It Ain't Mine

strikedo's picture
Offline
Joined: 02/06/2008
Juice: 45
Re: Re: Re: Function Declaration

OK got it, so I get the user id using:

$file_user->uid

Thanks!

drupalmind's picture
Offline
Joined: 01/06/2009
Juice: 46
Port Drupal 6 for this module?

Drupal 6 port for this module is available

Ki@drupal.org's picture
Offline
Joined: 02/19/2009
Juice: 2
Re: Port Drupal 6 for this module?

Could you tell where I can get the Drupal 6 port?

Thanks.

ñull@drupal.org's picture
Offline
Joined: 01/26/2009
Juice: 114
D6 UC2 version?

Interesting that this project was never created at drupal.org. This would make this module exposed to a wider group of developers with a higher chance that someone would continue with it or port it to UC2.

greenbeans's picture
Offline
Joined: 04/09/2009
Juice: 31
Re: Encrypt PDF

I'll need something like this for an upcoming project. If someone could point out some tips on porting modules from UC1 to UC2, I'd be interested in working on the port.

TR
TR's picture
Offline
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3424
Re: Re: Encrypt PDF
<tr>.
greenbeans's picture
Offline
Joined: 04/09/2009
Juice: 31
Thanks, TR: I understand

Thanks, TR:

I understand how to port modules between Drupal versions. But I'm not familiar enough with Ubercart's internals and hooks to be comfortable porting modules between UC versions.

TR
TR's picture
Offline
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3424
Re: Thanks, TR: I understand

I don't think you'll encounter any Ubercart-specific issues in porting this module. A partial list of UC 1.x -> UC2.x changes can be found at http://www.ubercart.org/docs/developer/6866/converting_modules_ubercart_...

<tr>.
greenbeans's picture
Offline
Joined: 04/09/2009
Juice: 31
Re: Re: Thanks, TR: I understand

Awesome, that looks very useful. Thank you.

BTW, I'm not likely to get to this for a couple more months, so if anyone else wants to give this a crack, please don't wait for me.