assign($params['assign'], $content) : $content; return $ret; } else { $protected_msg = ( # we add ability to override protected_msg from {protect protected_msg='some message'} isset($params['protected_msg']) ? $params['protected_msg'] : cms_utils::get_app_data('_PP_Prot_Msg') ); if (isset($protected_msg)) { $ret = isset($params['assign']) ? $smarty->assign($params['assign'], $protected_msg) : $protected_msg; return $ret; } } } } } function smarty_cms_function_page_protect($params, &$template) { # initialize a few vars $smarty = $template->smarty; $gCms = cmsms(); $current_page_alias = cms_utils::get_current_alias(); $logout_alias = isset($params['logout_alias']) ? $params['logout_alias'] : $current_page_alias; # some of the params have to be persistent through all the page request # so we use the same method as ModuleHint i.e. cms_utils Data Storage # flag to check if current user is authenticated $allow = cms_utils::get_app_data('_PP_Allow'); if (!isset($allow)) { $allow = false; } # timeout in minutes (cookie lifecycle). Null or 0 (zero) means off $timeout = cms_utils::get_app_data('_PP_TOut'); $use_timeout = cms_utils::get_app_data('_PP_useTOut'); if (!isset($timeout)) { $timeout = ( isset($params['timeout']) ? ($params['timeout'] == 0 ? 0 : time() + $params['timeout'] * 60) # if $params['timeout'] use it : 0 # else 0 ); $use_timeout = ( $timeout != 0 ); cms_utils::set_app_data('_PP_TOut', $timeout); cms_utils::set_app_data('_PP_useTOut', $use_timeout); } $cookie_name = cms_utils::get_app_data('_PP_CookieN'); if (!isset($cookie_name)) { $cookie_name = isset($params['cookie_name']) ? $params['cookie_name'] : 'pp_auth'; cms_utils::set_app_data('_PP_CookieN', $cookie_name ); } ##### messages ##### $protected_msg = cms_utils::get_app_data('_PP_Prot_Msg'); if (!isset($protected_msg)) { $protected_msg = isset($params['protected_msg']) ? $params['$protected_msg'] : $protected_msg; cms_utils::set_app_data('_PP_Prot_Msg', $protected_msg ); } $error_msg = cms_utils::get_app_data('_PP_Error_Msg'); if (!isset($error_msg)) { $error_msg = isset($params['error_msg']) ? $params['error_msg'] : 'The password is not correct.'; cms_utils::set_app_data('_PP_Error_Msg', $error_msg ); } $welcome_msg = cms_utils::get_app_data('_PP_Welcome_Msg'); if (!isset($welcome_msg)) { $welcome_msg = isset($params['welcome_msg']) ? $params['welcome_msg'] : 'Please enter the password to access this page.'; cms_utils::set_app_data('_PP_Welcome_Msg', $welcome_msg ); } ##### messages end ##### $welcome_msg = cms_utils::get_app_data('_PP_Welcome_Msg'); if (!isset($welcome_msg)) { $welcome_msg = isset($params['welcome_msg']) ? $params['welcome_msg'] : 'Please enter the password to access this page.'; cms_utils::set_app_data('_PP_Welcome_Msg', $welcome_msg ); } #cms_utils::set_app_data('_PP_Allow' , $allow); if (!isset($params['passwords'])) { $passwords = cms_utils::get_app_data('_PP_Pass'); } else { $passwords = &$params['passwords']; } if (!is_array($passwords)) { if (strpos($passwords, ',') === false) { $passwords = array($passwords); } else { $passwords = explode(',', $passwords); } } cms_utils::set_app_data('_PP_Pass', $passwords); ##### process requests and Cookies ##### $cookie_found = false; # logout if(isset($_POST['pp_logout'])) { # clear pass from cookie and redirect setcookie($cookie_name, '', 0, '/'); $allow = false; redirect_to_alias($logout_alias); } # process pass if (isset($_POST['pp_password'])) { $pass = $_POST['pp_password']; if ( !in_array($pass, $passwords) ) { $msg = $error_msg; $allow = false; } else { if ($use_timeout) { # we set cookie here #setcookie($cookie_name, md5($username . '%pp%' . $pass), $timeout, '/'); # todo setcookie($cookie_name, md5($pass), $timeout, '/'); } $allow = true; } } else { if ($use_timeout) { # check if cookie exists and is set if (!isset($_COOKIE[$cookie_name])) { $msg = ''; $allow = false; } foreach($passwords as $one) { if ($_COOKIE[$cookie_name] == md5($one)) { $cookie_found = true; $allow = true; # so we have a valid request: extend timeout setcookie($cookie_name, md5($one), $timeout, '/'); break; } } if (!$cookie_found) { $allow = false; # may very well be redundant but hey!!! we clear any pending messages anyway $msg = ''; } } } ##### end process requests and Cookies ##### cms_utils::set_app_data('_PP_Allow', $allow); ##### actions ##### switch ($params['action']) { case 'form': { # common to both buttons $button_id = isset($params['button_id']) ? 'id="' . $params['button_id'] . '" ' : ''; $button_class = isset($params['button_class']) ? 'class="' . $params['button_class'] . '" ' : ''; if (!$allow) { $login_btn = isset($params['login_btn']) ? $params['login_btn'] : 'Login'; $form_id = isset($params['form_id']) ? 'id="' . $params['form_id'] . '" ' : ''; $form_class = isset($params['form_class']) ? 'class="' . $params['form_class'] . '" ' : ''; $in_pass_id = isset($params['in_pass_id']) ? 'id="' . $params['in_pass_id'] . '" ' : ''; $in_pass_class = isset($params['in_pass_class']) ? 'class="' . $params['in_pass_class'] . '" ' : ''; $html = ''; $html .= '
'; $html .= '

'. $welcome_msg . '

'; $html .= '

' . $msg . '

'; $html .= ''; $html .= ''; $html .= '
'; $ret = isset($params['assign']) ? $smarty->assign($params['assign'], $html) : $html; return $ret; } else { $logout_btn = isset($params['logout_btn']) ? $params['logout_btn'] : 'Logout'; $html = ''; $html .= '
'; $html .= ''; $html .= ''; $ret = isset($params['assign']) ? $smarty->assign($params['assign'], $html) : $html; return $ret; } } break; # default usage: has to be located on top of the template # OR preferably on the "Smarty data or logic that is specific to this page" field # otherwise you'll get smarty error: {protect} tag is unknown # also has to be the top-most tag of any sequence of calls case 'set': { # dummy action: so one can set persistent parameters without triggering other actions } break; # default actions: just register the smarty plugin case 'default': default: { # register with smarty # usage: {protect}Content you want to protect {/protect} $smarty->registerPlugin("block", "protect", "pp_protect"); } } } ##### Docs ##### function smarty_cms_help_function_page_protect() { $txt = <<<'EOT'

What does this do?

This plugin allows you to protect a page with one or more passwords.

This plugin can be used on any number of pages. It has however to be set once for each page you want to protect.

How to use it?

This plugin needs to be set once for every page. You can set any number of passwords, by using commas to separate them. You can also use a Smarty array to set a list of passwords.

This plugin needs three calls in order to work properly:

The first tag should have most of the needed parameters set. These will be persistent through all the duration of the request, but can be overriden by subsequent calls with one exception: the {protect}{/protect} tags which only accept one optional parameter: protected_msg.

The order by which the tags are called is extremely important: the default action (parameter action='default' which can be omitted) cannot be set on the same content block as all other tags, and should be called on the topmost block of the template. This tag registers a smarty block plugin {protect} which won't be recongnised before being parsed once (and registered) by the Smarty engine. After this first call, all other calls don't have a specific order other than, of course, the opening and closing {protect}{/protect} tags.

Default Action

This should be placed on the topmost block of the template: the most suited place would be the Smarty data or logic that is specific to this page* found on each page options tab.

* Note: this only works if the tag {process_pagedata} is present on the template and is called before any other content block.

  • use {page_protect passwords='pass1[,pass2]...[,passn]'} or {page_protect action='default' passwords='pass1[,pass2]...[,passn]'}

If you need to protect several pages and are going to use the same passwords in all of them, you can use the default tag on the top of your template, right after the {process_pagedata} tag, if it exists. This tag registers a Smarty block plugin that can be called by using {protect}{/protect} for the duration of the request, that is to say, the current rendered page;

Passwords

The passwords parameter can accept a range of values, from a single password, a comma separated list of passwords, or an array of values:

{page_protect passwords='pass1'}

{page_protect passwords='pass1,'pass2,pass3}

{* Use smarty syntax to create an array *}
{$passwords[]='pass1'}
{$passwords[]='pass2'}
{$passwords[]='pass3'}
{* and use it as the value for the parmeter passwords *}
{page_protect passwords=$passwords}

You can also use an User Defined Tag to create an array and assign it to a smarty variable.

Note: Unless you use an array to set the passwords, avoid the use of commas (,) and of vertical slashes (|) as password symbols as these are reserved to internal use and will unavoidably lead to passwords not being recognised by the plugin.

Form Action

Although you can set parameters here, you should set them all only once and at the initial default tag. Other than that just place the tag where you want a login/logout form.

  • use {page_protect action='form'}

{* Do you really need all this?!!! A complete form call *}
{page_protect action='form' login_btn='Let Me In!' logout_btn='Bye Bye!' form_class='css_form' form_id='css_my_form' in_pass_id='css_passwrdid' in_pass_class='css_passwrd_class' button_id='css_btn_id' button_class='css_btn_class'}

The Content Wrapping Tags

These tags are block smarty tags, and can be used several times on the page, by pairs i.e an opening tag and a closing tag. The opening tag accepts only one parameter, the protected_msg which overrides the default one if set. This is a per occurence tag, meaning that if it is set on the default or set actions it is persistent, but if set on a {protect} tag it affects only the tag where it is used and doesn't persist to the next ocurrence.

  • use {protect}whatever content you want protected.{/protect} or {protect protected_msg='well, you really should be logged in if you what to see the content'}whatever content you want protected.{/protect}

Set Action

This is a special action with the sole purpose of allowing you to set persistent parameters on different tag calls, helping a bit with the readability of the tags: just keep in mind that if you call it using the same parameter with different values, the last value will override the previous.

{* Using the 'set' action to spread parameters through multiple calls *}
{* redirect Home *}
{page_protect action='set' logout_alias='home'}
{* set the time before a login expires *} 
{page_protect action='set' timeout=10}
{* set the message to show in case the authentication fails *}
{page_protect action='set' error_msg='Oops! Wrong pass, mate! Check your notes...'}
{* setting all the above in a single tag call could lead to errors *}

What parameters does it take?

Exclusive to form action:
Protect tag accepts only one parameter:

Additional Notes:

This is a weak protection measure if compared with .htacess methods or with a proper Front End User management module, but as long as you keep the passwords private and the access to the backend restricted and well organized, it should keep the pages where it is used protected.

If the timeout parameter is used, this plugin will generate a frontend cookie. By using this parameter you may be violating some countries laws of user privacy. Please make sure you provide a fair warning on the front pages if needed, or avoid using the timeout parameter, thus disabling the use of cookies. The only drawback of not using cookies is that the authentication only lasts for a single page request.

This plugin may need PHP version 5.3.

EOT; echo $txt; } function smarty_cms_about_function_page_protect() { $txt = <<<'EOT'

About

Version: 1.0

Author: Jo Morg (Fernando Morgado)

Another pluging made out of need. Enjoy!

History

To Do List

EOT; echo $txt; } ?>