adrian

Page Protector

Recommended Posts

Hi @adrian, this seems to work now!

But I didn't need the include '_main.php'; -line. When having that, I got the _main.php content rendered twice. 

 

 

Share this post


Link to post
Share on other sites
1 minute ago, lpa said:

Hi @adrian, this seems to work now!

But I didn't need the include '_main.php'; -line. When having that, I got the _main.php content rendered twice. 

Great that it's working for you now.

Your _main.php must be included automatically somewhere - probably in config.php. That's why you'd get it twice.

Mine needs to be included manually with the way I have things set up in my sandbox install.

Share this post


Link to post
Share on other sites

@lpa - I have just committed another update - turns out my initial fix broke the standard form approach. The new version works with both.

Because of the breaking changes, I have committed it to the dev branch (https://github.com/adrianbj/PageProtector/tree/dev) for now. I would really appreciate it if others using this module could please try this new version. The only change you should need to make is if you are using the custom Login Template option - you will need to change $loginForm to $page->loginForm

I'll push this dev version to master once there's been a little time for others to test it.

 

  • Like 2

Share this post


Link to post
Share on other sites
12 hours ago, adrian said:

I'll push this dev version to master once there's been a little time for others to test it.

I do not use loginForm so I cannot really test it but after updating I had no issues at all.

  • Like 1

Share this post


Link to post
Share on other sites

Anyone following this thread have any issues with the dev version before I merge to master?

I'll merge later today if I don't hear anything.

Thanks!

  • Like 1

Share this post


Link to post
Share on other sites

OK, v2 has been merged to master.

Be warned about the breaking changes!

  • Like 1

Share this post


Link to post
Share on other sites

Hello,

I have setup a login template but cant seem to stop the head and foot loading, I've disabled auto prepend/append in the template but the they still load any ideas?

Cheers

Jon

Share this post


Link to post
Share on other sites

@Jon on mobile right now, but just wondering if the chosen template file is actually connected to a PW template. It doesn't need to be and maybe that is the issue but I'll have to check when I'm back at my desk in the morning. 

Share this post


Link to post
Share on other sites

@Jon - just took a look and can't seem to reproduce.

What version of the module are you running?

Can you please details of the code in the template file, and your auto prepend/append settings please?

Share this post


Link to post
Share on other sites

@adrian - Iam using version 2.0.1 and PW 3.0.15

the code in the template is just the login form for testing.

echo $page->loginForm;

 My prepend/append setup within the config is

$config->prependTemplateFile = 'head.inc';
$config->appendTemplateFile = 'foot.inc';

I also check the disable prepend/append within the template setup.

Jon

Share this post


Link to post
Share on other sites

Hi @Jon - thanks for the details, but I guess I am not sure what you are expecting to have happen.

If you don't want the head.inc and foot.inc to be loaded, why not just use the standard (no login template) way of adding the login form. That's how it's designed to work. maybe if you could provide a mockup of how you expect it to look I might be able to get a better idea?

Share this post


Link to post
Share on other sites

I have pages like this:

Page1
  - page1.1
  - page1.2

Page1 has been given access to roles: musician, assistant. Page1.2 has been given access to role musician only. 

When logged out, both pages ask to be logged in. When logged in as the user with only assistant role, I still can see the page1.2. I can't figure out why the roles based restrictions don't work at the moment. How should I debug this?

Second question: can I hide the page1.2 from the user with assistant role in my navigation somehow? What should I do in my navigation script to hide the pages that the used doesn't have view access to?

Third question: I need to customize the login-form by including some content from PW, but now when the customized login-form is not a PW form, I can't run any functions from the PW templates. How should I customize the login-form content when I need something more than just the form?

Edited by lpa

Share this post


Link to post
Share on other sites

@adrian Thanks for your reply, I just wanted to customise the login page a bit to match my site a bit more. I have managed to do this with the standard template now. One thing I cant seem change is the default Login Message Ive set this in the module settings but the changes arent reflected in the frontend?

Cheers

Jon 

Share this post


Link to post
Share on other sites
2 hours ago, Jon said:

One thing I cant seem change is the default Login Message Ive set this in the module settings but the changes arent reflected in the frontend?

I expect you are changing the main default in the module settings. This populates the value on the Settings tab of the page that is being protected, but if a page has already been protected, you will need to change the value for that page. It allows for different messages for different pages. Does that make sense?

 

  • Thanks 1

Share this post


Link to post
Share on other sites

@lpa 

1) I'll look at the hierarchy you described in a minute

2) You can check if a page is protected by checking $page->protected eg:

if(!$page->protected) {
	//show in navigation
}

3) I have just made the message function hookable, so you will be able to put this is your ready.php file:

$this->addHookAfter("PageProtector::getMessage", function($event) {
    $event->return = 'My custom message';
});

I'll commit this once I look at your first issue.

  • Like 1

Share this post


Link to post
Share on other sites

@lpa - I am not seeing the issues you are regarding access to the child. My thought is that you might have checking the "protect children" checkbox for Page 1. If you are separately protecting child pages, I think you don't want that checked. Can you try that and see if it works as expected?

I have committed the change that makes that hook available. Please let me know how you go with that also.

Share this post


Link to post
Share on other sites

@adrian Thanks for that works prefect :)

1 hour ago, adrian said:

I expect you are changing the main default in the module settings. This populates the value on the Settings tab of the page that is being protected, but if a page has already been protected, you will need to change the value for that page. It allows for different messages for different pages. Does that make sense?

 

 

  • Like 1

Share this post


Link to post
Share on other sites

1. No, the protection is not taking in account the role at all. Even if I change just one page without child protection to be protected, I can access that page after login with a user account that does not have the required role!

2. Yes, $page->protected works, but it does not make any difference on who is accessign the page. Should it give different results based on the users roles? I would like to make it to not show the navigation item if the page is protected for that particular user. 

3. What is actually the message the hook returns? I would like something like this:

// Give me a random picture to the login page
$image = getRandomPict($homepage);
$content = "
<div class='row'>
	$page->loginForm
	<div class='large-12 columns'>
	$image
	</div>
</div>
";
$event->return = $content;

 

Share this post


Link to post
Share on other sites

@lpa - just heading to bed here, but 

1) I am not seeing any problems like that here - any chance this site is live and you could give me a login to check things out?

2) I'll need to confirm the role stuff in the morning - you might be onto something though - I might need protected vs prohibited?

3) The part I made hookable is just the message before the username/password fields. I think if you want custom classes around the login form you should just put them in your template file you as want - no need for a hook for that. Does that make sense?

Share this post


Link to post
Share on other sites

@lpa - for now I am going to attach the new version here. This adds support for the new "prohibited" property so now you can check if a page is protected and then also check if it's prohibited for the current user.

I refactored a few things so don't want to commit the changes just yet.

Can you please test this for your needs. I would also like to help you with Issue 1, but will might need some access to test that. As for Issue 3, did you try my suggestion?

PageProtector.zip

Share this post


Link to post
Share on other sites

1. I'll send you a private message on this. 

2. Thanks, the $page->prohibited works just as I wanted based on  a quick test. 

3. At the moment I have a login.php file that is included on every page in _init.php. That page has my own logic without PageProtector. There, if I need the login form, I can format it just like I want and even use the getRandomPict()-function which is in _func.php. But if I use the PageProtector I use the $page->loginForm, as show above, where I can't use my getRandomPict()-function, because it is not a PW template. I get errors like: "Call to undefined function getRandomPict()". I don't want to add the image to every template.

Share this post


Link to post
Share on other sites

@adrian has a great support on his modules! All the problems solved with his help a long time ago! Thank you very much! 

And this module is great for cases where the PW template based access rights scheme is not so flexible.

  • Like 2

Share this post


Link to post
Share on other sites
3 minutes ago, lpa said:

@adrian has a great support on his modules! All the problems solved with his help a long time ago! Thank you very much! 

And this module is great for cases where the PW template based access rights scheme is not so flexible.

Thanks for your help @lpa in fixing those issues.

FYI for everyone else - all the changes that were included in that zip posted above are now in the master repo on github.

  • Like 2

Share this post


Link to post
Share on other sites

A feature request for the future: allow login only with a password. As a workaround I used a simple str_replace and added hardcoded "value=USERNAME" attribute to the username input, plus a good old display: none to it. This way it doesn't show up but contains the username pre-filled.

The same could be perhaps achieved if there was a per-page setting where we could enter one username. Then the module could add a hidden input with an encrypted username (instead of a text type username input). But maybe you have a better idea.

I needed this because the client needed a password protected page without asking for a username. Fortunately the protection doesn't need to be bulletproof so my workaround is fine for now, but in the future it would be nice having this built-in.

  • Like 1

Share this post


Link to post
Share on other sites

I get an 500 error after the third failed login attempt:

Please wait at least 10 seconds before attempting another login. (in /wire/modules/Session/SessionLoginThrottle/SessionLoginThrottle.module line 97)

SessionLoginThrotte settings are the default ones, 5 sec and 60 sec, no IP throttle. I'll disable the SLT module for now but I'm curious whether this happens for others too. 

Using PW 3.0.100 and PageProtector 2.0.4, but just checked on another site running on 3.0.52 / 0.2.1 and it happens there too.

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   0 members

    No registered users viewing this page.

  • Similar Content

    • By joshuag
      Hey guys, 
      Thought I would share a quick preview of Designme. A module we (Eduardo @elabx and I) are building for visually laying out your templates/edit screens. 🙂
      This is a really quick, zero polish screen grab. FYI. 
      Video #2 - UPDATE
      This new video shows the following features in Designme:
      Re-arranging fields via Drag & Drop Re-sizing fields via Dragging. Adjusting field settings - with live refresh. Working on "hidden" fields while Designme is active. Creating New fields. Deleting fields. Creating/Deleting Tabs. Dragging fields between tabs. Creating fieldsets. Tagging/Un-tagging fields. Fields without headers expand when hovered (like checkboxes). Live filtering of fields in the sidebar. Ability to adjust (all) Template settings without leaving Designme. Template File Tree Editing Template files source code with ACE Editor. Editing Multiple files with ACE Editor. (New Tabs) Saving files. Techie stuff Fields load their own js/css dependancies. *ready to use on creation (*most fields)  Everything happens via Ajax to ProcessPageEdit (via module + hooks). Designme has a JS api that you can use.  All actions trigger events.  We would love any detailed feedback on what you see so far. If you are interested in testing Designme. Let me know below. 🙂
       
       
      Video #1. 
       
    • By dreerr
      TemplateEnginePug (formally TemplateEngineJade)
       
      This module adds Pug templates to the TemplateEngineFactory. It uses https://github.com/pug-php/pug to render templates.
      doctype html html(lang='en') head meta(http-equiv='content-type', content='text/html; charset=utf-8') title= $page->title link(rel='stylesheet', type='text/css', href=$config->urls->templates . 'styles/main.css') body include header.pug h1= $page->title if $page->editable() p: a(href=$page->editURL) Edit Project on GitHub: github.com/dreerr/TemplateEnginePug
      Project in modules directory: modules.processwire.com/modules/template-engine-pug/
       
      For common problems/features/questions about the Factory, use the TemplateEngineFactory thread.
       
    • By tpr
      ProcessNetteTester
      Run Nette Tester tests within ProcessWire admin.
      (continued from here)

      Features
      AJAX interface for running Nette Tester tests, in bulk or manually display counter, error message and execution time in a table run all tests at once or launch single tests show formatted test error messages and report PHP syntax errors stop on first failed test (optional) hide passed tests (optional) display failed/total instead passed/total (optional) re-run failed tests only (optional) auto scroll (optional) include or exclude tests based on query parameters start/stop all tests with the spacebar reset one test or all tests (ctrl+click) https://modules.processwire.com/modules/process-nette-tester/
      https://github.com/rolandtoth/ProcessNetteTester
    • By bernhard
      Some of you might have followed the development of this module here: https://processwire.com/talk/topic/15524-previewdiscussion-rockdatatables/ . It is the successor of "RockDataTables" and requires RockFinder to get the data for the grid easily and efficiently. It uses the open source part of agGrid for grid rendering.
       
      WHY?
      ProcessWire is awesome for creating all kinds of custom backend applications, but where it is not so awesome in my opinion is when it comes to listing this data. Of course we have the built in page lister and we have ListerPro, but none of that solutions is capable of properly displaying large amounts of data, for example lists of revenues, aggregations, quick and easy sorts by the user, instant filter and those kind of features. RockGrid to the rescue 😉 
       
      Features/Highlights:
      100k+ rows Instant (client side) filter, search, sort (different sort based on data type, eg "lower/greater than" for numbers, "contains" for strings) extendable via plugins (available plugins at the moment: fullscreen, csv export, reload, batch-processing of data, column sum/statistics, row selection) all the agGrid features (cell renderers, cell styling, pagination, column grouping etc) vanilla javascript, backend and frontend support (though not all plugins are working on the frontend yet and I don't plan to support it as long as I don't need it myself)  
      Limitations:
      While there is an option to retrieve data via AJAX the actual processing of the grid (displaying, filtering, sorting) is done on the client side, meaning that you can get into troubles when handling really large datasets of several thousands of rows. agGrid should be one of the most performant grid options in the world (see the official example page with a 100k row example) and does a lot to prevent problems (such as virtual row rendering), but you should always have this limitation in mind as this is a major difference to the available lister options that do not have this limitation.
      Currently it only supports AdminThemeUikit and I don't plan to support any other admin theme.
       
      Download: https://gitlab.com/baumrock/RockGrid
      Installation: https://gitlab.com/baumrock/RockGrid/wikis/Installation
      Quikckstart: https://gitlab.com/baumrock/RockGrid/wikis/quickstart
      Further instructions: https://gitlab.com/baumrock/RockGrid/wikis/quickstart#further-instructions
       
      Module status: alpha, License: MIT
      Note that every installation and uninstallation sends an anonymous google analytics event to my google analytics account. If you don't want that feel free to remove the appropriate lines of code before installation/uninstallation.
       
      Contribute:
      You can contribute to the development of this and other modules or just say thank you by
      testing, reporting issues and making PRs at gitlab liking this post buying me a drink: paypal.me/baumrock/5 liking my facebook page: facebook.com/baumrock hiring me for pw work: baumrock.com  
      Support: Please note that this module might not be as easy and plug&play as many other modules. It needs a good understanding of agGrid (and JavaScript in general) and it likely needs some looks into the code to get all the options. Please understand that I can not provide free support for every request here in the forum. I try to answer all questions that might also help others or that might improve the module but for individual requests I offer paid support for 60€ per hour.
       
      Changelog
      180711 bugfix (naming issue) 180630 alpha realease  
      Use Cases / Examples:
      Colored grid cells, Icons, Links etc. The Grid also has a "batcher" feature built in that helps communicating with the server via AJAX and managing resource intensive tasks in batches:

      Filters, PW panel links and instant reload on panel close:

      You can combine the grid with a chart library like I did with the (outdated) RockDataTables module:

    • By tpr
      Update 2018-07-09: ProcessNetteTester module is available in the Modules Directory and on GitHub.

      This is a short tutorial on how to use Nette Tester with ProcessWire.
      As you will see it's very easy to setup and use and it's perfect for testing your code's functionality. With bootstrapping ProcessWire it's also possible to check the rendered markup of pages using the API, checking page properties, etc. It's also a great tool for module developers for writing better code. 
      While there will be nothing extraordinary here that you couldn't find in Tester's docs this can serve as a good starting point.
      Prerequisites: PHP 5.6+
      01 Download Tester
      Go to https://github.com/nette/tester/releases and download the latest release (currently 2.0.2). Download from the link reading "Source code (zip)". You can use composer also if you wish.
      02 Extract Tester files
      Create a new directory in your site root called "tester". Extract the zip downloaded here, so it should look like this:
      /site /tester/src /tester/tools /tester/appveyor.yml /tester/composer.json /tester/contributing.md /tester/license.md /tester/readme.md /wire ... 03 Create directory for test files
      Add a new directory in "/tester" called "tests". Tester recognizes "*.Test.php" and "*.phpt" files in the tests directory, recursively. 
      04 Create your first test
      In the "tests" directory create a new "MyTest.php" file.
      The first test is a very simple one that bootstraps ProcessWire and checks if the Home page name is "Home". This is not the smartest test but will show you the basics.
      Add this to "/tester/tests/MyTest.php":
      <?php namespace ProcessWire; use \Tester\Assert; use \Tester\DomQuery; use \Tester\TestCase; use \Tester\Environment; require __DIR__ . '/../src/bootstrap.php'; // load Tester require __DIR__ . '/../../index.php'; // bootstrap ProcessWire Environment::setup(); class MyTest extends TestCase {     // first test (step 04)     public function testHomeTitle()     {         $expected = 'Home'; // we expect the page title to be "Home"         $actual = wire('pages')->get(1)->title; // check what's the actual title Assert::equal($expected, $actual); // check whether they are equal     }     // second test will go here (step 06)     // third test will go here (step 07) } // run testing methods (new MyTest())->run(); I've added comment placeholders for the second and third tests that we will insert later.
      05 Run Tester
      Tester can be run either from the command line or from the browser. The command line output is more verbose and colored while in the browser it's plain text only (see later).
      Running from the command line
      Navigate to the "/tester" directory in your console and execute this:
      php src/tester.php -C tests This will start "/tester/src/tester.php" and runs test files from the "/tester/tests" directory. The "-C" switch tells Tester to use the system-wide php ini file, that is required here because when bootstrapping ProcessWire you may run into errors (no php.ini file is used by default). You may load another ini file with the "-c <path>" (check the docs).
      If the title of your Home page is "Home" you should see this:

      If it's for example "Cats and Dogs", you should see this:

      Running from the browser
      First we need to create a new PHP file in ProcessWire's root, let's call it "testrunner.php". This is because ProcessWire doesn't allow to run PHP files from its "site" directory.
      The following code runs two test classes and produces a legible output. IRL you should probably iterate through directories to get test files (eg. with glob()), and of course it's better not allow tests go out to production.
      <?php ini_set('html_errors', false); header('Content-type: text/plain'); echo 'Starting tests.' . PHP_EOL; echo '--------------------------' . PHP_EOL; $file = __DIR__ . '/PATH_TO/FirstTest.php'; echo basename($file) . ' '; require $file; echo '[OK]' . PHP_EOL; $file = __DIR__ . '/PATH_TO/SecondTest.php'; echo basename($file) . ' '; require $file; echo '[OK]' . PHP_EOL; echo '--------------------------' . PHP_EOL; echo 'Tests finished.'; exit; Navigate to "DOMAIN/testrunner.php" in your browser to execute the file. If every test succeeds you should get this:

      If there are failed tests the execution stops and you can read the error message. If there were more tests (eg. ThirdTest), those won't be displayed under the failed test.

      06 DOM test
      This test will check if a page with "basic-page" template has a "h1" element. We will create the page on the fly with ProcessWire's API. To keep things simple we will add the new test as a new method to our MyTest class.
      Add this block to the MyTest class:
      public function testBasicPageHeadline() {     $p = new Page();     $p->template = 'basic-page';     $html = $p->render();     $dom = DomQuery::fromHtml($html);     Assert::true($dom->has('h1')); } This will most likely be true but of course you can check for something more specific, for example "div#main". Note that we have used the DomQuery helper here (check the "use" statement on the top of the file).
      07 Custom function test
      You will probably want to make sure your custom functions/methods will work as they should so let's write a test that demonstrates this.
      I don't want to complicate things so I'll check if the built-in "pageName" sanitizer works as expected. Add this to the myTest class:
      public function testPageNameSanitizer() {     $expected = 'hello-world';     $actual = wire('sanitizer')->pageName('Hello world!', true);     Assert::equal($expected, $actual); } This should also be true. Try to change the expected value if you are eager to see a failure message.
       
      08 Next steps
      You can add more methods to the MyTest class or create new files in the "tests" directory. Check out the range of available Assertions and other features in the docs and see how they could help you writing more fail-safe code.
      Once you make a habit of writing tests you'll see how it can assist making your code more bulletproof and stable. Remember: test early, test often 🙂
      If you find out something useful or cool with Tester make sure to share.