Membership 2 (or other) protecting files

Hello,

So I've started using Membership 2 for a downloads section, problem is, you can still access the actual files directly, is there a way I can prevent this? So when a file is accessed and the user has not got a membership it will be taken to the protected content page?

Thanks.

  • Predrag Dubajic

    Hey @luciel_campbell,

    Hope you're doing well today :slight_smile:

    Membership 2 comes with Media Protection add-on that you can use to protect files that are uploaded to your media.
    Go to Membership > Add-ons and activate Media Protection add-on, you can also click on Details... link after activation for additional setting of this Add-on.

    This will enable you to protect your files.

    Best regards,
    Predrag

  • Luciel Campbell

    Humph, that's a shame, I'd do that in a normal scenario, problem is, files have been there for a long time so I know other websites are linking to them and would've liked to be able to forward those request to the protected content page, I guess my only option is to manually redirect all files?

    The download plugin I use requires to add the complete internal address of the file, being a media file, would that be an issue? (I.e. one uploaded through media, adding the file in downloads through address and not the add media option, as it's not an option in this plugin)

  • Adam Czajczyk

    Hey @luciel_campbell,

    I hope you're having a nice day!

    There's no good way known that would let you protect files that are outside your WP install by using WP-based tools. In this case I can only think of solution such as:

    1. Moving all these files to the Media Library
    2. Setting up a general redirect for these moved files from their original location to a page that would include a listing of these files; these could be achieved with .htaccess rules or (might be possible) with cPanel tools
    3. Using Media Protection add-on of Membership 2 to protect these files.

    This is because WP isn't capable of "reaching beyond" its install folders.

    You may want however try setting up some "external pages" by building simple pages upon "external WP" principle:

    http://codex.wordpress.org/Integrating_WordPress_with_Your_Website

    This will require a lot of development work but may work here.

    Cheers,
    Adam

  • Luciel Campbell

    Hi @Adam Czajczyk,

    I understand what you're saying though I think it's simpler than that. The idea would be to add the files through media (which may proove problematic depending on the size of the file...), then do redirection through httpaccess (simple enough).

    My concern is that, the downloads plugin I use needs me to tell it the final path of the file, it does not have an "add media" option. So, if I give it the final path of the uploaded to media file, would it protect it (since while it may have been uploaded through media, I did not use the "add media" option when specifying where the download is).

    Does that make sense?

  • Adam Czajczyk

    Hey @luciel_campbell!

    I understand what you're saying though I think it's simpler than that. The idea would be to add the files through media (which may proove problematic depending on the size of the file...), then do redirection through httpaccess (simple enough).

    It's surely the simpler solution :slight_smile:

    My concern is that, the downloads plugin I use needs me to tell it the final path of the file, it does not have an "add media" option. So, if I give it the final path of the uploaded to media file, would it protect it (since while it may have been uploaded through media, I did not use the "add media" option when specifying where the download is).

    Once you enable the "Media Protection" add-on for Membership 2, please make sure that you've also enabled the "Complete protection" or "Hybrid protection" method and "Protect Individual Media files" option for Media Protection add-on.

    Next step would be to upload the file to the "Media Library" (Dashboard -> "Media" -> "Add news"). Once this is done, please go back to Dashboard -> "Media" -> "Library", then find this freshly uploaded file, click on it and then select "Edit more details" option.

    The "edit" page for file will appear and inside the "Save" box (right column) there's a field named "File URL". You'll find the "protected" (masked) URL of the file there and you should be able to use this URL with your download plugin and keep it protected.

    This however needs to be tested, so could you please give it a try and let me know? You may also want to let me know what download plugin are you using so I could test it on my own :slight_smile:

    Cheers,
    Adam

  • Luciel Campbell

    Hey @Adam Czajczyk

    Thanks again for your continued replies :slight_smile:

    Ok so, I followed your steps and for some reason the website has slowed down to a crawl after this. In some case even throwing 500 errors.

    Could you try the procedure on your end so we can see what kind of results you get?

    The downloads plugin is https://wordpress.org/plugins/download-monitor/ + the page addon extension (which shouldn't matter in this case so don't worry about that).

    PS: After some testing, discovered the issue, the moment I activate the media protection addon, the site goes crazy slow + 500 errors o.O, if I deactivate it, site goes back to normal.

    PS2: Ok so that issue only seems to happen if I choose "complete protection", since your guide said I could also use hybrid, I'm trying that. So far the website seems fine, going to actually try the files now. Not sure what the difference between Hybrid and Complete are, will report asap.

    PS3: So, as I thought, the downloads plugin will not take a final address (i.e. the protected one) as its parth for the file, it needs an absolute path so by browsing for it, I added the absolute path of the media upload but as I though, by doing this the file is not protected and can be downloaded without an account.

    PS4: The downloads plugin itself has a "members only" function, but it's very crude and just takes you to a blank page with a "you do not have access to this" message. Going to see if I can replace this with the protected content page and if it'll work for hotlinking.

  • Luciel Campbell

    Conclusion (since it no longer allows me to edit the previous post):
    By editing /wp-content/plugins/download-monitor/includes/class-dlm-download-handler.php line 238:
    wp_die( wp_kses_post( get_option( 'dlm_no_access_error', '' ) ), __( 'Download Error', 'download-monitor' ), array( 'response' => 200 ) );
    changing it to:
    header("Location: /protected-content/");
    We forward non-members to the protected content page when they try to download any download set to "members only" achieving a sort of "crude" integration with the membership 2 plugin without the need of the media protection addon and allowing ftp uploads and usage of the download monitor plugin the way it was meant to be used (which is good because uploading big files through media upload could be problematic, even though we could use something like https://wordpress.org/plugins/add-from-server/ to circumvent that limitation). After, by enabling the "prevent hotlinking" option on the download monitor settings, we prevent acquiring an absolute path, so, paying members can't just copy the absolute download link and share it with non-paying visitors (by right clicking on the download button and copying link as it will just give it a generated link rather than the absolute path).

    There is one problem however. The issue is when you register, and choose not to pay, you've still created an account which means you can download the file. Obviously to prevent this you could just add the downloads section to the protected content list but by doing this you prevent non members from looking at the download descriptions, etc which would bring us back to the stage 1 (even if it at this point we now have hotlinking protection which was the main point of this, but it would be nice for visitors to see what they can get if the pay for the subscription, by not doing this, it is a lot less likely for them to go ahead and pay).

    So basically now I have to figure out how to show the download monitor plugin to distinguish paying members from normal members and I have absolutely no idea how to go about this.

    PS: If we figure this one out I'll be more than glad to compose a full step by step guide on how to use Membership 2 with Download Monitor (which at the time of writing is the most popular downloads plugin on wordpress) and share it with the wpmu community :slight_smile:

    PS2: I'm pretty sure the change would have to be on the same file mentioned earlier on line 46 to 62:

    public function check_access( $can_download, $download ) {
    
    		// Check if download is a 'members only' download
    		if ( $download->is_members_only() ) {
    
    			// Check if user is logged in
    			if ( ! is_user_logged_in() ) {
    				$can_download = false;
    			} // Check if it's a multisite and if user is member of blog
    			else if ( is_multisite() && ! is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
    				$can_download = false;
    			}
    
    		}
    
    		return $can_download;
    	}

    Would need to know what to change the refference to logged in user to.

    PS3: From what I can gather, the membership ON itself would be (according to the db): membership_id: 2664 but I really have no idea how to express that check within the php, plus we'd really need to make it more generic so anyone can use the guide, not just make it work for me if that makes sense.

  • Luciel Campbell

    Again, sorry for double-posting, can't seem to edit posts after a while...

    PS4: So, from looking at the membership code, I imagine I would have to declare this in the downloads plugin (the file specified earlier).

    else if ( $current_member->has_membership( $check_id ) ) {
    				$can_download = false;
    			}

    After the current checks:

    // Check if download is a 'members only' download
    		if ( $download->is_members_only() ) {
    
    			// Check if user is logged in
    			if ( ! is_user_logged_in() ) {
    				$can_download = false;
    			} // Check if it's a multisite and if user is member of blog
    			else if ( is_multisite() && ! is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
    				$can_download = false;
    			}

    But of course it doesn't work, there has to be more to it (my php skills are rather limited). The error log reports:

    PHP Fatal error: Call to a member function has_membership() on a non-object

    At this point I`m stuck, any ideas?

  • Adam Czajczyk

    Hey @luciel_campbell,

    I hope you're well today and thank you for this extensive explanation and great investigation!

    I've tested the Membership 2 Media Protection along the Download Monitor on my end, following your example, and I can confirm that this doesn't play well together. It seems than this isn't the way to go, indeed.

    However, inspired by your recent post I came across another idea that doesn't involve any plugin "hacking", therefore it shouldn't break upon Membership 2 or Download Monitor update. I believe you should be able to enhance it as you wish.

    1. Enable hotlinking protection for Download Monitor
    2. On "Downloads" -> "Settings" -> "Access" page modify the "No access message". Just include a link to your "Membership register/login" page there.
    User's will not be automatically redirected but you will not need to modify the plugin
    3. For each download enable the "Members only" option

    So far we've got a working "overall protection" with Download Monitor. Of course this means that every user that has logged in would be able to download the file.

    4. Go to "Downloads" -> "Settings" -> "General" page and select "Custom template" from the "Default Template" drop-down list
    5. In a "Custom Template" fields write "members" and save settings.

    From now on Download Monitor will use the "content-download-members.php" file as a "download button" template.

    6. create a file named "content-download-members.php" and put the following lines inside:

    <?php
    /**
     * Default output for a download via the [download] shortcode
     */
    
    global $dlm_download;
    ?>
    
    <?php 
    
    if ( ms_has_membership('XXX') ) {
     ?>
     <a class="download-link" title="<?php if ( $dlm_download->has_version_number() ) {
    	printf( __( 'Version %s', 'download-monitor' ), $dlm_download->get_the_version_number() );
    } ?>" href="<?php $dlm_download->the_download_link(); ?>" rel="nofollow">
    	<?php $dlm_download->the_title(); ?>
    	(<?php printf( _n( '1 download', '%d downloads', $dlm_download->get_the_download_count(), 'download-monitor' ), $dlm_download->get_the_download_count() ) ?>)
    </a>
    <?php
    }
    else {
     ?>
     Here goes "no access" message
     <?
    }
    ?>

    Of course replace "XXX" as a ms_has_membership() function parameter with a real ID number of selected membership.

    7. Upload the file to your current theme's folder.

    I've tested this on my setup and it seems to be working fine. It doesn't allow not-logged-in and logged-in-but-not-members users download the file but does allow them to view the download page (therefore the description etc). Furthermore, some other conditions (such as multiple memberships) can be added and this entire solution should easily survive plugins updates.

    What do you think about it? Let me know please!

    Cheers,
    Adam

  • Luciel Campbell

    Hi @Adam Czajczyk,

    Massive thanks for getting back to me and taking the time to investigate and helping me out. I apologize for the lateness in my reply, I had to wait a couple of days before I could afford renewing my quarterly subscription. If your reply where a party, it'd be suit etiquette; extremely elegant solution it would seem (makes mine look like shorts, sandals, socks and a dirty tshirt :stuck_out_tongue:). I will try it asap, I'm having some issues with membership causing high load though, you can have a look here:

    https://premium.wpmudev.org/forums/topic/membership-2-causing-high-load

  • Adam Czajczyk

    Hey luciel_campbel!

    If your reply where a party, it'd be suit etiquette; extremely elegant solution it would seem (makes mine look like shorts, sandals, socks and a dirty tshirt :stuck_out_tongue:). I will try it asap,

    Thanks for your kind words! Just let me know how it worked for you and in case you need any further assistance on this, just let me know. I'll be glad to help!

    I'm having some issues with membership causing high load though, you can have a look here:

    I can see that my colleague Vaughan is working on this with you. He's a highly competent person and since he just ask you to grant him a support access, let's let him take a look around first. I'm sure he'll deal with it in no time!

    Have a nice day!
    Adam

  • Luciel Campbell

    Hi @Adam Czajczyk,

    Hope you are doing well :slight_smile:

    I got round to giving your fix a go and as I was reading it I realized it would not work, however, it's my fault and not yours. Your method actually works if (and only if) download monitor is used with no addons and each download is given a post (description) with the relative download button at the end (via shortcode).

    I should've specified more and I can see now that it does matter having the page addon. Ok so, here is my config.

    Download Monitor
    Download Monitor Page Addon

    I discovered an issue however, the page addon is poorly done, uses custom meta tags which make it impossible for any SEO to include anything but the page where the page addon is at in the sitemap (so no downloads included in the sitemap, which obviously is bad if you want them to appear in search engines).

    So, let's recap on a visual level. This is what it looks like to have JUST download monitor.
    http://www.cd-2-dvd.com/superorca-msi-editor/
    Which is basically a standard wordpress post with a shortcode at the end leading to a download we created through the downloads section in the dashboard (for the record, if you had just Download Monitor, the actual download button would just download the file, so your fix would work perfectly in that scenario).

    This is what it looks like when you also have the Page Addon:
    Page: http://www.cd-2-dvd.com/downloads/
    Actual Download: http://www.cd-2-dvd.com/downloads/download-info/superorca-msi-editor/

    That said, due to reasons I don't understand, page addon is just that, an addon and does not modify the behaviour of the original Download Monitor. So in order to fix that and also fix the fact that Page Addon doesn't get indexed I did the following.

    1: Every download I add has 2 pages. A wordpress post with the shortcode at the end (which fixes the being indexed issue).
    2: The very same content of that post is also used to create the non-indexed version, i.e. the download page without the page addon (which looks, in my oppinion, much better).
    3: In order to link both, I "hacked" download monitor so the shortcode takes you to the download page of said download instead of just directly serving you the file (as you can tell by clicking on the download button on the post previously posted here).

    So, in regards to our little issue, the post will always be avaliable to everyone, no matter membership or not. Everyone can, at all times also see the button created by the shortcode on that post. Everyone can also click on said button and see the actual download page (in the "page addon"). However, if they click the download button there they'll be taken to the protected page (or message, depending which way we follow) unless they are a member, so basically we need to apply something like your fix but, instead of applying it to the shortcode generated download button in posts (http://www.cd-2-dvd.com/superorca-msi-editor/), we need to do it to the download button in the actual download page (http://www.cd-2-dvd.com/downloads/download-info/superorca-msi-editor/) which as I mentioned before I managed to do, just have to make it distinguish between regular non paying members and paying members :slight_smile:

    I hope this wasn't all to confusing and my bad, I'm so used to using the page addon I almost forgot it's not actually included with the standard download monitor.

    So in case you need it, I've uploaded to this post a .rar file that has both the slightly modified download monitor plugin and the page addon (which works as if it was a separate plugin so you'll need to activate that one too. In order for the "hack" to work on your site once uploaded, you need to go to Downloads - Settings - Endpoint and write "download" as your Download Endpoint and choose Download Slug as the Endpoint Value. Furthermore, you'll need to make sure your Membership 2 protected content page is /protected-content/ (so the default basically).

    PS: I've actually uploaded it to my server as the upload function here does not seem to like .rar files.
    [download link removed by staff member]

    PS2: The page addon also has a couple of code changes but those won't affect anything. They basically change the order of display of content on the downloads index page and within each download page it adds a "back" button, that's all.

  • Adam Czajczyk

    Hey @Luciel Campbell!

    Thanks for this great description and explanation!

    I think I'll need another look, a bit deeper so it's really helpful that you've shared this modified version of your Download Monitor along with the Page Addon (which I do not have as it's a premium add-on and it would be quite difficult for me to gain access to all premium plugins and add-ons I have to deal with on daily basis). That said, let me take a look and I'm sure I can think of something with a little help of my colleagues.

    That being said, as the "Page Addon" is a premium add-on and this is a public forum, I've already downloaded it and removed the link from your post so nobody else would be able to access the file.

    Please keep an eye on this thread for further updates and information from me :slight_smile:

    Thanks,
    Adam

  • Adam Czajczyk

    Hey Luciel,

    I hope you're well today!

    Thanks for your patience, I'm really sorry I had to keep you waiting that long with this. Just one last question if you don't mind: I believe that you may need to stick to the "pre-defined" (I mean in terms of changes we're making here) settings/config so updates to DM and its page add-on may not be possible. I'm pretty sure that's not a case here however I suppose this may also kind-of require you to apply changes back again (or adjust them a bit) in case of serious template and/or Membership 2 updates.

    Will that be all right? Let me know please!

    Cheers,
    Adam

  • Luciel Campbell

    Hi @Adam Czajczyk,

    Seriously don't worry about it :slight_smile:

    As for your question, I have already done changes to the DM code to change how linking works on the shortcodes (normally the shortcode just straight up downloads the file while I've changed it so instead it takes you to the download page of said download so I already have to make changes when I update so it's not an issue whatsoever having to do other changes as long as I know what they are (obviously :stuck_out_tongue:).

    Thanks!

  • Adam Czajczyk

    Hello @Luciel Campbell,

    I hope you're well today!

    I'm sorry it took so long and I'm almost ashamed that the solution turned out to be much simpler than I previously though, hopefully though it will work for you now. I've attached the file to this post. The file is taken from your Download Page add-on so it should include all the mods you may have done to it.

    Please download it, extract the .zip archive and open "content-download-pa-single.php" file with a clean-text editor. You'll find that basically that's the same mod I've came up previously, so you will only want to change the membership ID (in "if ( ms_has_membership('2207') ) {" line) and the "no access" message below. Once this is done, upload the file to your current theme folder and it all should be good.

    Let me know please if it works as expected. And, once again, I sincerely apologize for the delay!

    Kind regards,
    Adam

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.