├── doc ├── changelogs │ ├── 1.3 │ │ └── CHANGELOG-1.2.0-to-1.3.0 │ ├── 1.1 │ │ └── CHANGELOG-1.0.0-to-1.1.0 │ ├── 1.4 │ │ └── CHANGELOG-1.3.0-to-1.4.0 │ └── 1.2 │ │ └── CHANGELOG-1.1.0-to-1.2.0 └── INSTALL.txt ├── update └── database │ ├── oracle │ └── longer-regexp.sql │ ├── postgresql │ └── longer-regexp.sql │ └── mysql │ └── longer-regexp.sql ├── design ├── standard │ └── templates │ │ ├── class │ │ └── datatype │ │ │ ├── edit │ │ │ └── ezpaex.tpl │ │ │ └── view │ │ │ └── ezpaex.tpl │ │ ├── userpaex │ │ ├── expirynotificationmail.tpl │ │ ├── forgotpasswordmail.tpl │ │ ├── password.tpl │ │ └── forgotpassword.tpl │ │ └── content │ │ └── datatype │ │ ├── view │ │ └── ezpaex.tpl │ │ └── edit │ │ └── ezpaex.tpl └── admin │ ├── templates │ ├── toolbar │ │ └── full │ │ │ └── admin_current_user.tpl │ └── userpaex │ │ └── password.tpl │ └── override │ └── templates │ └── node │ └── view │ └── full_caching_disabled.tpl ├── settings ├── design.ini.append.php ├── dbschema.ini.append.php ├── module.ini.append.php ├── siteaccess │ └── admin │ │ └── override.ini.append.php ├── datatype.ini.append.php ├── content.ini.append.php ├── cronjob.ini.append.php ├── mbpaex.ini ├── site.ini.append.php └── audit.ini.append.php ├── README.md ├── dist.sh ├── ant └── ezmbpaex.properties ├── sql ├── oracle │ ├── mbpaex.sql │ └── schema.sql ├── mysql │ └── mbpaex.sql └── postgresql │ └── mbpaex.sql ├── CREDITS.txt ├── composer.json ├── extension.xml ├── tests ├── suite.php ├── datatypes │ └── ezpaex │ │ └── ezpaextype_test.php └── classes │ └── ezpaex_test.php ├── modules └── userpaex │ ├── module.php │ ├── password.php │ └── forgotpassword.php ├── share └── db_schema.dba ├── cronjobs ├── ezmbpaex_sendexpirynotifications.php └── ezmbpaex_updatechildren.php ├── login_handler └── ezpaexuser.php ├── install └── scripts │ └── setpasswordlastupdated.php ├── translations ├── untranslated │ └── translation.ts ├── por-BR │ └── translation.ts ├── cro-HR │ └── translation.ts ├── esl-ES │ └── translation.ts ├── ita-IT │ └── translation.ts ├── cat-ES │ └── translation.ts └── fre-FR │ └── translation.ts └── datatypes └── ezpaex └── ezpaextype.php /doc/changelogs/1.3/CHANGELOG-1.2.0-to-1.3.0: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /update/database/oracle/longer-regexp.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE ezx_mbpaex (passwordvalidationregexp varchar2(255)) -------------------------------------------------------------------------------- /design/standard/templates/class/datatype/edit/ezpaex.tpl: -------------------------------------------------------------------------------- 1 | {* DO NOT EDIT THIS FILE! Use an override template instead. *} -------------------------------------------------------------------------------- /design/standard/templates/class/datatype/view/ezpaex.tpl: -------------------------------------------------------------------------------- 1 | {* DO NOT EDIT THIS FILE! Use an override template instead. *} -------------------------------------------------------------------------------- /update/database/postgresql/longer-regexp.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE ezx_mbpaex ALTER COLUMN passwordvalidationregexp TYPE varchar(255); -------------------------------------------------------------------------------- /update/database/mysql/longer-regexp.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE ezx_mbpaex CHANGE passwordvalidationregexp passwordvalidationregexp VARCHAR(255); -------------------------------------------------------------------------------- /settings/design.ini.append.php: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /doc/changelogs/1.1/CHANGELOG-1.0.0-to-1.1.0: -------------------------------------------------------------------------------- 1 | Changes from 1.0.0 to 1.1.0 2 | 3 | *General: 4 | 5 | *Bugfixes: 6 | - Fixed wrong INI directives 7 | -------------------------------------------------------------------------------- /settings/dbschema.ini.append.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/changelogs/1.4/CHANGELOG-1.3.0-to-1.4.0: -------------------------------------------------------------------------------- 1 | Changes from 1.3.0 to 1.4.0 2 | 3 | *Bugs* 4 | 5 | - Fixed bug #017280: ezmbpaex template does not work with 4.3 6 | -------------------------------------------------------------------------------- /settings/module.ini.append.php: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /settings/siteaccess/admin/override.ini.append.php: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /settings/datatype.ini.append.php: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /settings/content.ini.append.php: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eZ MB Password Expiry 2 | ## Description 3 | 4 | Extension that provides functionality for password expiration and validation. 5 | 6 | The mbpaex extension allows you to define a lifetime for how long passwords should be valid. Once a password has expired it the extension will ask the user to create a new password. 7 | 8 | -------------------------------------------------------------------------------- /settings/cronjob.ini.append.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | EXTENSION_NAME="eZ Password Expiry" 3 | EXTENSION_IDENTIFIER="ezmbpaex" 4 | EXTENSION_SUMMARY="Extension providing password expiry functionality" 5 | EXTENSION_LICENSE="GNU General Public License v2.0" 6 | EXTENSION_VERSION="1.2.0" 7 | EXTENSION_PUBLISH_VERSION="4.2" 8 | EXTENSION_ARCHIVE_NAME="ezmbpaex" 9 | EXTENSION_PHP_VERSION="5.2" 10 | # EXTENSION_FILTER_FILES="" 11 | -------------------------------------------------------------------------------- /ant/ezmbpaex.properties: -------------------------------------------------------------------------------- 1 | 2 | ezmbpaex.version.major = 1 3 | ezmbpaex.version.minor = 2 4 | ezmbpaex.version.release = 0 5 | ezmbpaex.version.alias = ${ezmbpaex.version.major}.${ezmbpaex.version.minor} 6 | 7 | 8 | ezmbpaex.svn.url = http://svn.projects.ez.no/mbpaex/trunk/extension/ezmbpaex/ 9 | ezmbpaex.create.tarball = yes 10 | -------------------------------------------------------------------------------- /sql/oracle/mbpaex.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE ezx_mbpaex ( 2 | contentobject_id integer DEFAULT 0 NOT NULL, 3 | passwordvalidationregexp varchar2(255) DEFAULT '', 4 | passwordlifetime integer DEFAULT -1 NOT NULL, 5 | expirationnotification integer DEFAULT -1 NOT NULL, 6 | password_last_updated integer DEFAULT 0 NOT NULL, 7 | updatechildren integer DEFAULT 0 NOT NULL, 8 | expirationnotification_sent integer DEFAULT 0 NOT NULL, 9 | PRIMARY KEY (contentobject_id) 10 | ); 11 | 12 | -------------------------------------------------------------------------------- /sql/oracle/schema.sql: -------------------------------------------------------------------------------- 1 | 2 | CREATE TABLE ezx_mbpaex ( 3 | contentobject_id INTEGER DEFAULT 0 NOT NULL, 4 | expirationnotification INTEGER DEFAULT -1 NOT NULL, 5 | expirationnotification_sent INTEGER DEFAULT 0 NOT NULL, 6 | password_last_updated INTEGER DEFAULT 0 NOT NULL, 7 | passwordlifetime INTEGER DEFAULT -1 NOT NULL, 8 | passwordvalidationregexp VARCHAR2(255), 9 | updatechildren INTEGER DEFAULT 0 NOT NULL, 10 | PRIMARY KEY ( contentobject_id ) 11 | ); 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /sql/mysql/mbpaex.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE ezx_mbpaex ( 2 | contentobject_id int(11) NOT NULL default '0', 3 | passwordvalidationregexp varchar(255) NOT NULL default '', 4 | passwordlifetime int(11) NOT NULL default '-1', 5 | expirationnotification int(11) NOT NULL default '-1', 6 | password_last_updated int(11) NOT NULL DEFAULT 0, 7 | updatechildren int(2) NOT NULL DEFAULT 0, 8 | expirationnotification_sent int(2) NOT NULL DEFAULT 0, 9 | 10 | PRIMARY KEY (contentobject_id) 11 | ) ENGINE=InnoDB; 12 | -------------------------------------------------------------------------------- /CREDITS.txt: -------------------------------------------------------------------------------- 1 | ================================================================ 2 | Password Expiry extension for eZ Publish 4.1 and later - CREDITS 3 | ================================================================ 4 | 5 | Credits 6 | ------- 7 | 8 | We would like to specially thank Microblau ( http://www.microblau.net/ ) and Mitsue-Links Co. Ltd. ( http://www.mitsue.co.jp ), 9 | two dedicated eZ Partners, who developed this extension. 10 | This extension is available, as an Official eZ Publish Certified extension under http://projects.ez.no/mbpaex. -------------------------------------------------------------------------------- /sql/postgresql/mbpaex.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE ezx_mbpaex ( 2 | contentobject_id integer NOT NULL DEFAULT 0, 3 | passwordvalidationregexp character varying(255) DEFAULT '' NOT NULL, 4 | passwordlifetime integer DEFAULT -1 NOT NULL, 5 | expirationnotification integer DEFAULT -1 NOT NULL, 6 | password_last_updated integer DEFAULT 0 NOT NULL, 7 | updatechildren integer DEFAULT 0 NOT NULL, 8 | expirationnotification_sent integer DEFAULT 0 NOT NULL 9 | ); 10 | 11 | ALTER TABLE ONLY ezx_mbpaex ADD CONSTRAINT ezx_mbpaex_pkey PRIMARY KEY (contentobject_id); 12 | 13 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ezsystems/ezmbpaex-ls", 3 | "description": "eZ Publish Legacy Extension that provides functionality for password expiration and validation.", 4 | "type": "ezpublish-legacy-extension", 5 | "license": "GPL-2.0", 6 | "authors": [ 7 | { 8 | "name": "eZ Publish dev-team & eZ Community", 9 | "homepage": "https://github.com/ezsystems/ezmbpaex/contributors" 10 | } 11 | ], 12 | "minimum-stability": "dev", 13 | "require": { 14 | "ezsystems/ezpublish-legacy-installer": "*" 15 | }, 16 | "extra": { 17 | "ezpublish-legacy-extension-name": "ezmbpaex" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /design/standard/templates/userpaex/expirynotificationmail.tpl: -------------------------------------------------------------------------------- 1 | {* DO NOT EDIT THIS FILE! Use an override template instead. *} 2 | {def $site_url=ezini("SiteSettings","SiteURL")} 3 | {set-block scope=root variable=subject}{"%siteurl your password is about to expire"|i18n("mbpaex/userpaex",,hash('%siteurl',$site_url))}{/set-block} 4 | {"Your account information"|i18n('design/standard/user/forgotpassword')} 5 | {"Email"|i18n('design/standard/user/forgotpassword')}: {$user.email} 6 | 7 | {"Click here to set your new password"|i18n('mbpaex/userpaex/forgotpassword')}: 8 | 9 | http://{$site_url}{concat("userpaex/password/", $user.contentobject_id)|ezurl(no)} 10 | 11 | {undef $site_url} 12 | -------------------------------------------------------------------------------- /extension.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | eZ Password Expiry LS 5 | dev-master 6 | Copyright (C) eZ Systems AS. All rights reserved. 7 | For full copyright and license information view LICENSE file provided with this software. 8 | https://github.com/ezsystems/ezmbpaex 9 | <a href="http://www.microblau.net/">Microblau</a> and <a href="http://www.mitsue.co.jp">Mitsue-Links Co. Ltd.</a>, two dedicated eZ Partners. 10 | 11 | 12 | -------------------------------------------------------------------------------- /settings/mbpaex.ini: -------------------------------------------------------------------------------- 1 | [mbpaexSettings] 2 | # Regular expression used for password validation when 3 | # none is defined in the contentobject 4 | PasswordValidationRegexp= 5 | 6 | # Default lifetime for password in DAYS 7 | # 0 means no limit (passwords never expire) 8 | DefaultPasswordLifeTime=3 9 | 10 | # Number of seconds before password expiration to send a 11 | # mail notification to the user 12 | # Default 172800 (2 days) 13 | ExpirationNotification=172800 14 | 15 | # Number of seconds that the forgot password generated hash will be valid 16 | # Default 86400 (1 day) 17 | ForgotPasswordHashLifeTime=86400 18 | 19 | # Login of the eZ user used in the updatechildren cronjob, must have access to 20 | # read the Users section. 21 | UpdateChildrenUser=admin 22 | -------------------------------------------------------------------------------- /settings/site.ini.append.php: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /doc/changelogs/1.2/CHANGELOG-1.1.0-to-1.2.0: -------------------------------------------------------------------------------- 1 | Changes from 1.1.0 to 1.2.0 2 | 3 | *General: 4 | - Added sql file to install on Oracle 5 | 6 | 7 | *Cronjobs: 8 | - Unified cronjob scripts names: 9 | - Renamed sendexpirynotifications.php to ezmbpaex_sendexpirynotifications.php 10 | - Renamed updatechildren.php ezmbpaex_updatechildren.php 11 | - Reflected these changes in cronjob.ini. The parts are now named 12 | mbpaex_send_expiry_notifications and mbpaex_updatechildren 13 | 14 | *Bugfixes: 15 | 16 | *Tests: 17 | - Fixed issue #15407: ezmbpaex : update_children cronjob does not work 18 | - Fixed issue #15377: ezmbpaex extension can truncate ezuser table if installed slightly wrong 19 | - Added unit test suite for the extension, as well as a few tests for 1.2.0 -------------------------------------------------------------------------------- /design/standard/templates/userpaex/forgotpasswordmail.tpl: -------------------------------------------------------------------------------- 1 | {* DO NOT EDIT THIS FILE! Use an override template instead. *} 2 | {def $site_url=ezini("SiteSettings","SiteURL")} 3 | {set-block scope=root variable=subject}{"%siteurl forgot password"|i18n("mbpaex/userpaex/forgotpassword",,hash('%siteurl',$site_url))}{/set-block} 4 | {"Your account information"|i18n('design/standard/user/forgotpassword')} 5 | {"Email"|i18n('design/standard/user/forgotpassword')}: {$user.email} 6 | 7 | {"Click here to set your new password"|i18n('mbpaex/userpaex/forgotpassword')}: 8 | {concat("userpaex/forgotpassword/", $hash_key, '/')|ezurl(no)} 9 | 10 | {"This link is valid until %1, after that time you should generate a new one."|i18n('mbpaex/userpaex/forgotpassword',,hash('%1',$hash_key_lifetime))} 11 | {undef $site_url} 12 | -------------------------------------------------------------------------------- /tests/suite.php: -------------------------------------------------------------------------------- 1 | setName( "eZ Publish Password Expiry Test Suite" ); 18 | 19 | $this->addTestSuite( 'eZPaExTest' ); 20 | $this->addTestSuite( 'eZPaExTypeTest' ); 21 | } 22 | 23 | public static function suite() 24 | { 25 | return new self(); 26 | } 27 | } 28 | 29 | ?> -------------------------------------------------------------------------------- /tests/datatypes/ezpaex/ezpaextype_test.php: -------------------------------------------------------------------------------- 1 | setName( "eZ Password Expiry Datatype Unit Tests" ); 18 | } 19 | 20 | public function setUp() 21 | { 22 | parent::setUp(); 23 | } 24 | 25 | public function tearDown() 26 | { 27 | parent::tearDown(); 28 | } 29 | 30 | public function testA() 31 | { 32 | $this->markTestIncomplete( "placeholder" ); 33 | } 34 | } 35 | 36 | ?> -------------------------------------------------------------------------------- /settings/audit.ini.append.php: -------------------------------------------------------------------------------- 1 | ]= 19 | # Always clients IP address and user names(if exist) will be logged. 20 | 21 | # User changes another user password 22 | AuditFileNames[user-password-change]=password_change.log 23 | 24 | # User changes their own password 25 | AuditFileNames[user-password-change-self]=password_change_self.log 26 | 27 | # Failures changing own password 28 | AuditFileNames[user-password-change-self-fail]=failed_password_change_self.log 29 | 30 | # Password changes via forgot-password 31 | AuditFileNames[user-forgotpassword]=forgotpassword.log 32 | 33 | # Failures on forgot-password 34 | AuditFileNames[user-forgotpassword-fail]=failed_forgotpassword.log 35 | 36 | */ ?> 37 | -------------------------------------------------------------------------------- /modules/userpaex/module.php: -------------------------------------------------------------------------------- 1 | 'User with Password Expiry management', 11 | 'variable_params' => true ); 12 | 13 | $ViewList = array(); 14 | 15 | $ViewList['password'] = array( 16 | 'functions' => array( 'password' ), 17 | 'script' => 'password.php', 18 | 'ui_context' => 'administration', 19 | 'default_navigation_part' => 'ezmynavigationpart', 20 | 'params' => array( 'UserID' ) ); 21 | 22 | $ViewList['forgotpassword'] = array( 23 | 'functions' => array( 'password' ), 24 | 'script' => 'forgotpassword.php', 25 | 'params' => array( ), 26 | 'ui_context' => 'administration', 27 | 'single_post_actions' => array( 'GenerateButton' => 'Generate', 28 | 'ChangePasswdButton' => 'ChangePassword' ), 29 | 'post_action_parameters' => array( 'Generate' => array( 'Login' => 'UserLogin', 30 | 'Email' => 'UserEmail' ), 31 | 'ChangePassword' => array('NewPassword' => 'NewPassword', 32 | 'NewPasswordConfirm' => 'NewPasswordConfirm' ) ), 33 | 'params' => array( 'HashKey' ) ); 34 | 35 | $FunctionList = array(); 36 | $FunctionList['password'] = array(); 37 | $FunctionList['editpaex'] = array(); 38 | 39 | ?> 40 | -------------------------------------------------------------------------------- /share/db_schema.dba: -------------------------------------------------------------------------------- 1 | 5 | array ( 6 | 'name' => 'ezx_mbpaex', 7 | 'fields' => 8 | array ( 9 | 'contentobject_id' => 10 | array ( 11 | 'length' => 11, 12 | 'type' => 'int', 13 | 'not_null' => '1', 14 | 'default' => 0, 15 | ), 16 | 'expirationnotification' => 17 | array ( 18 | 'length' => 11, 19 | 'type' => 'int', 20 | 'not_null' => '1', 21 | 'default' => -1, 22 | ), 23 | 'expirationnotification_sent' => 24 | array ( 25 | 'length' => 2, 26 | 'type' => 'int', 27 | 'not_null' => '1', 28 | 'default' => 0, 29 | ), 30 | 'password_last_updated' => 31 | array ( 32 | 'length' => 11, 33 | 'type' => 'int', 34 | 'not_null' => '1', 35 | 'default' => 0, 36 | ), 37 | 'passwordlifetime' => 38 | array ( 39 | 'length' => 11, 40 | 'type' => 'int', 41 | 'not_null' => '1', 42 | 'default' => -1, 43 | ), 44 | 'passwordvalidationregexp' => 45 | array ( 46 | 'length' => 150, 47 | 'type' => 'varchar', 48 | 'not_null' => '1', 49 | 'default' => '', 50 | ), 51 | 'updatechildren' => 52 | array ( 53 | 'length' => 2, 54 | 'type' => 'int', 55 | 'not_null' => '1', 56 | 'default' => 0, 57 | ), 58 | ), 59 | 'indexes' => 60 | array ( 61 | 'PRIMARY' => 62 | array ( 63 | 'type' => 'primary', 64 | 'fields' => 65 | array ( 66 | 0 => 'contentobject_id', 67 | ), 68 | ), 69 | ), 70 | ), 71 | '_info' => 72 | array ( 73 | 'format' => 'generic', 74 | ), 75 | ); 76 | 77 | ?> -------------------------------------------------------------------------------- /cronjobs/ezmbpaex_sendexpirynotifications.php: -------------------------------------------------------------------------------- 1 | output( "eZPaEx: Send expiry notifications process start" ); 11 | 12 | ini_set( 'max_execution_time', 0); 13 | ini_set( 'memory_limit', '-1' ); 14 | 15 | eZDebug::addTimingPoint( 'Fetch notification pending list' ); 16 | 17 | $paexPendingList = eZPaEx::fetchExpiryNotificationPendingList(); 18 | $paexPendingListCount = count( $paexPendingList ); 19 | 20 | if ( !$paexPendingListCount ) 21 | { 22 | $cli->output( "No pending update notifications found" ); 23 | } 24 | else 25 | { 26 | $cli->output( "Found " . $paexPendingListCount . " objects pending notification, send notifications:" ); 27 | $totalNotificationsSent = 0; 28 | 29 | eZDebug::addTimingPoint( 'Send notifications' ); 30 | foreach ( $paexPendingList as $paexObject ) 31 | { 32 | $userID = $paexObject->attribute( 'contentobject_id' ); 33 | $userObject = eZUser::fetch( $userID ); 34 | if ( $userObject instanceof eZUser && $userObject->isEnabled() ) 35 | { 36 | if ( !$paexObject->sendExpiryNotification( $userObject ) ) 37 | { 38 | $cli->output( "Error sending notification. UserID: " . $userID ); 39 | } 40 | else 41 | { 42 | $cli->output( "Notification sent ok. UserID: " . $userID ); 43 | $paexObject->setExpiryNotificationSent(); 44 | $totalNotificationsSent++; 45 | } 46 | } 47 | else 48 | { 49 | $cli->output( "Error user_object disabled or not found. UserID: ". $userID ); 50 | } 51 | } 52 | $cli->output( "Sent " . $totalNotificationsSent . " notifications." ); 53 | } 54 | 55 | $cli->output( "eZPaEx: Send expiry notifications process end" ); 56 | 57 | ?> 58 | -------------------------------------------------------------------------------- /design/standard/templates/content/datatype/view/ezpaex.tpl: -------------------------------------------------------------------------------- 1 | {* View Template for ezpaex datatype *} 2 | 3 |
4 | 5 |
6 | 7 | {if $attribute.content.has_regexp} 8 | {$attribute.content.passwordvalidationregexp|wash( xhtml )} 9 | {else} 10 | {'undefined'|i18n( 'mbpaex/content/datatype' )} 11 | {/if} 12 |
13 | 14 |
15 | 16 | {if $attribute.content.has_lifetime} 17 | {$attribute.content.passwordlifetime|wash} 18 | {else} 19 | {'undefined'|i18n( 'mbpaex/content/datatype' )} 20 | {/if} 21 |
22 | 23 |
24 | 25 | {if $attribute.content.has_notification} 26 | {$attribute.content.expirationnotification|wash} 27 | {else} 28 | {'undefined'|i18n( 'mbpaex/content/datatype' )} 29 | {/if} 30 |
31 |
32 |
33 | 34 | {if $attribute.content.is_user} 35 |
36 |
37 | 38 | {if $attribute.content.is_expired} 39 | {'expired'|i18n( 'mbpaex/content/datatype' )} 40 | {else} 41 | {'active'|i18n( 'mbpaex/content/datatype' )} 42 | {/if} 43 |
44 |
45 |
46 | {elseif $attribute.content.is_updatechildrenpending} 47 |
48 |
49 | {'Children update pending, will be done in a few minutes...'|i18n( 'mbpaex/content/datatype' )} 50 |
51 |
52 |
53 | {/if} 54 | -------------------------------------------------------------------------------- /design/standard/templates/userpaex/password.tpl: -------------------------------------------------------------------------------- 1 | {* DO NOT EDIT THIS FILE! Use an override template instead. *} 2 | 3 |
4 |
5 | 6 |
7 | 8 |
9 |

{"Change password for user"|i18n("mbpaex/userpaex")}

10 |
11 | 12 | {if $message} 13 | {if or($oldPasswordNotValid,$newPasswordNotMatch,$newPasswordNotValidate,$newPasswordMustDiffer)} 14 | {if $oldPasswordNotValid} 15 |
16 |

{'Please retype your old password.'|i18n('mbpaex/userpaex')}

17 |
18 | {/if} 19 | {if $newPasswordNotMatch} 20 |
21 |

{"Password didn't match, please retype your new password."|i18n('mbpaex/userpaex')}

22 |
23 | {/if} 24 | {if $newPasswordNotValidate} 25 |
26 |

{"Password didn't validate, please retype your new password."|i18n('mbpaex/userpaex')}

27 |
28 | {/if} 29 | {if $newPasswordMustDiffer} 30 |
31 |

{"New password must be different from the old one. Please choose another password."|i18n('mbpaex/userpaex')}

32 |
33 | {/if} 34 | {else} 35 | 38 | {/if} 39 | {/if} 40 | 41 |
42 | {if $oldPasswordNotValid}*{/if} 43 |
44 | 45 |
46 | 47 |
48 |
49 | {if or($newPasswordNotMatch,$newPasswordNotValidate)}*{/if} 50 |
51 | 52 |
53 |
54 | {if or($newPasswordNotMatch,$newPasswordNotValidate)}*{/if} 55 |
56 | 57 |
58 |
59 |
60 | 61 |
62 | 63 | 64 |
65 | 66 |
67 | 68 |
69 |
70 | -------------------------------------------------------------------------------- /design/admin/templates/toolbar/full/admin_current_user.tpl: -------------------------------------------------------------------------------- 1 |
2 | 3 |
{if $first}
{/if} 4 | 5 |

{'Current user'|i18n( 'design/admin/pagelayout' )}

6 | 7 |
{if $first}
{/if} 8 | 9 | {if $last} 10 |
11 | {else} 12 |
13 | {/if} 14 | 15 | {let basket=fetch( shop, basket )} 16 | 17 | {if and( ne( $ui_context, 'edit' ), ne( $ui_context, 'browse' ) )} 18 | 19 | {let current_user_link=$current_user.contentobject.main_node.url_alias|ezurl} 20 |

 {$current_user.contentobject.name|wash}

21 | {/let} 22 | 23 | 40 | {else} 41 |

{$current_user.contentobject.name|wash}

42 |
    43 |
  • {'Change user info'|i18n( 'design/admin/pagelayout' )}
  • 44 |
  • {'Change password'|i18n( 'design/admin/pagelayout' )}
  • 45 | {if $basket.is_empty|not} 46 |
  • {'Shopping basket (%basket_count)'|i18n( 'design/admin/pagelayout',, hash( '%basket_count', $basket.items|count ) )}
  • 47 | {/if} 48 |
  • {'Logout'|i18n( 'design/admin/pagelayout' )}
  • 49 |
50 | {/if} 51 | {/let} 52 |
{if $last}
{/if} 53 | 54 |
55 | -------------------------------------------------------------------------------- /design/admin/templates/userpaex/password.tpl: -------------------------------------------------------------------------------- 1 | {* DO NOT EDIT THIS FILE! Use an override template instead. *} 2 | 3 |
4 | {* DESIGN: Header START *}
5 |

{"Change password for user"|i18n("mbpaex/userpaex")}

6 | {* DESIGN: Mainline *}
7 | {* DESIGN: Header END *}
8 | 9 | {* DESIGN: Content START *}
10 | 11 |
12 | 13 | {if $message} 14 | {if or($oldPasswordNotValid,$newPasswordNotMatch,$newPasswordNotValidate,$newPasswordMustDiffer)} 15 | {if $oldPasswordNotValid} 16 |
17 |

{'Please retype your old password.'|i18n('mbpaex/userpaex')}

18 |
19 | {/if} 20 | {if $newPasswordNotMatch} 21 |
22 |

{"Password didn't match, please retype your new password."|i18n('mbpaex/userpaex')}

23 |
24 | {/if} 25 | {if $newPasswordNotValidate} 26 |
27 |

{"Password didn't validate, please retype your new password."|i18n('mbpaex/userpaex')}

28 |
29 | {/if} 30 | {if $newPasswordMustDiffer} 31 |
32 |

{"New password must be different from the old one. Please choose another password."|i18n('mbpaex/userpaex')}

33 |
34 | {/if} 35 | {else} 36 | 39 | {/if} 40 | {/if} 41 | 42 |
43 | {if $oldPasswordNotValid}*{/if} 44 |
45 | 46 |
47 | 48 |
49 |
50 | {if or($newPasswordNotMatch,$newPasswordNotValidate)}*{/if} 51 |
52 | 53 |
54 |
55 | {if or($newPasswordNotMatch,$newPasswordNotValidate)}*{/if} 56 |
57 | 58 |
59 |
60 |
61 | {* DESIGN: Content END *}
62 | 63 |
64 | {* DESIGN: Control bar START *}
65 |
66 | 67 | 68 |
69 | {* DESIGN: Control bar END *}
70 |
71 | 72 |
-------------------------------------------------------------------------------- /design/standard/templates/content/datatype/edit/ezpaex.tpl: -------------------------------------------------------------------------------- 1 | {* Edit Template for ezpaex datatype *} 2 | 3 | {if is_set($attribute_base)|not} 4 | {def $attribute_base=ContentObjectAttribute} 5 | {/if} 6 | 7 |
8 | {* Validation Regexp. *} 9 |
10 | 11 | 12 |
13 | 14 | {* Password LifeTime. *} 15 |
16 | 17 | 18 |
19 | 20 | {* Expiration Notification *} 21 |
22 | 23 | 24 |
25 | 26 |
27 |
28 | 29 | {* If we are editing a user, show password status, if not and the current user 30 | have permissions, show a checkbox to choose update children *} 31 | {if $attribute.content.is_user} 32 |
33 |
34 | 41 |
42 |
43 |
44 | {elseif $attribute.content.can_edit} 45 |
46 |
47 | 48 | 49 |
50 |
51 |
52 | {/if} 53 | -------------------------------------------------------------------------------- /cronjobs/ezmbpaex_updatechildren.php: -------------------------------------------------------------------------------- 1 | variable( 'mbpaexSettings','UpdateChildrenUser' ); 13 | // Default to admin if user is not found in the ini 14 | if ( !trim( $updateChildrenUser ) ) 15 | $updateChildrenUser = 'admin'; 16 | 17 | $user = eZUser::fetchByName( $updateChildrenUser ); 18 | eZUser::setCurrentlyLoggedInUser( $user, $user->attribute( 'contentobject_id' ) ); 19 | 20 | if ( $user->isLoggedIn() ) 21 | { 22 | $cli->output( "eZPaEx: Update children process start" ); 23 | 24 | ini_set( 'max_execution_time', 0 ); 25 | ini_set( 'memory_limit', '-1' ); 26 | 27 | eZDebug::addTimingPoint( 'Fetch update pending list' ); 28 | // Get list of paex objects marked to updatechildren 29 | $pendingList = eZPaEx::fetchUpdateChildrenPendingList(); 30 | $pendingListCount = count( $pendingList ); 31 | 32 | if ( !$pendingListCount ) 33 | { 34 | $cli->output( "No pending update subtrees found" ); 35 | } 36 | else 37 | { 38 | $cli->output( "Found " . $pendingListCount . " ezpaex objects with pending updatechildren" ); 39 | $pendingIdList = array(); 40 | foreach ($pendingList as $pendingObject) 41 | { 42 | $pendingIdList[] = $pendingObject->attribute( 'contentobject_id' ); 43 | } 44 | 45 | // Fetch array of nodes corresponding to objects in the pendingIDList to sort them by depth 46 | $nodeArray = eZContentObjectTreeNode::findMainNodeArray( $pendingIdList, false ); 47 | 48 | // Make an array of objects ids with its deph based on the corresponding node 49 | $objectDepthList = array(); 50 | foreach ($nodeArray as $key => $node) 51 | { 52 | $objectDepthList[0][$key] = $node["depth"]; 53 | $objectDepthList[1][$key] = $node["contentobject_id"]; 54 | } 55 | // Sort objectDepthList by depth to apply updatechildren in the right order 56 | if ( !array_multisort( $objectDepthList[0], SORT_ASC, $objectDepthList[1], SORT_ASC ) ) 57 | { 58 | eZDebug::writeError( 'Error in array_multisort', 'ezmbpaex_updatechildren.php' ); 59 | } 60 | else 61 | { 62 | // Generate array of paex objects to update 63 | $paexObjectArray = array(); 64 | foreach ( $objectDepthList[1] as $contentobjectId ) 65 | { 66 | if ( isset( $pendingList[$contentobjectId] ) ) 67 | { 68 | // Generate update children data for every pending object in pendingIDList 69 | $paexObjectArray = $pendingList[$contentobjectId]->generateUpdateChildren( $paexObjectArray ); 70 | } 71 | else 72 | { 73 | eZDebug::writeError( 'Found contentobject_id [' . $contentobjectId . '] not present in the pendingIDList', 'ezmbpaex_updatechildren.php' ); 74 | } 75 | } 76 | 77 | // Reset pending object updatechildren attribute in pendingIDList objects and add to the array of paex objects to update 78 | foreach ( $pendingList as $pendingObject ) 79 | { 80 | $pendingObject->setAttribute( 'updatechildren', 0 ); 81 | $paexObjectArray[$pendingObject->attribute( 'contentobject_id' )] = $pendingObject; 82 | } 83 | 84 | // Store updated paex objects in the DB 85 | $db = eZDB::instance(); 86 | $db->begin(); 87 | 88 | foreach ( $paexObjectArray as $paexObject ) 89 | { 90 | $paexObject->store(); 91 | eZContentCacheManager::clearContentCacheIfNeeded( $paexObject->attribute( 'contentobject_id' ) ); 92 | } 93 | $db->commit(); 94 | } 95 | } 96 | 97 | $cli->output( "eZPaEx: Update children process end" ); 98 | } 99 | 100 | ?> -------------------------------------------------------------------------------- /login_handler/ezpaexuser.php: -------------------------------------------------------------------------------- 1 | attribute( 'contentobject_id' ); 60 | $paex = eZPaEx::getPaEx( $userID, true ); 61 | 62 | if ( $paex instanceof eZPaEx && $paex->isExpired() ) 63 | { 64 | self::passwordHasExpired( $user ); 65 | return false; 66 | } 67 | else 68 | { 69 | self::loginSucceeded( $user ); 70 | return $user; 71 | } 72 | } 73 | else 74 | { 75 | self::loginFailed( $user, $login ); 76 | return false; 77 | } 78 | 79 | return $user; 80 | } 81 | 82 | /** 83 | * Writes audit information and redirects the user to the password change form. 84 | * 85 | * @param eZUser $user 86 | */ 87 | protected static function passwordHasExpired( $user ) 88 | { 89 | $userID = $user->attribute( 'contentobject_id' ); 90 | 91 | // Password expired 92 | eZDebugSetting::writeDebug( 'kernel-user', $user, 'user password expired' ); 93 | 94 | // Failed login attempts should be logged 95 | $userIDAudit = isset( $userID ) ? $userID : 'null'; 96 | $loginEscaped = eZDB::instance()->escapeString( $user->attribute( 'login' ) ); 97 | eZAudit::writeAudit( 'user-failed-login', array( 'User id' => $userIDAudit, 98 | 'User login' => $loginEscaped, 99 | 'Comment' => 'Failed login attempt: Password Expired. eZPaExUser::loginUser()' ) ); 100 | 101 | // Redirect user to password change form 102 | self::redirectToChangePasswordForm( $userID ); 103 | } 104 | 105 | /** 106 | * Performs a redirect to the password change form 107 | * 108 | * @param int $userID 109 | */ 110 | protected static function redirectToChangePasswordForm( $userID ) 111 | { 112 | $http = eZHTTPTool::instance(); 113 | $url = self::$changePasswordFormURL . $userID; 114 | eZURI::transformURI( $url ); 115 | $http->redirect( $url ); 116 | } 117 | } 118 | 119 | ?> 120 | -------------------------------------------------------------------------------- /design/standard/templates/userpaex/forgotpassword.tpl: -------------------------------------------------------------------------------- 1 | {* DO NOT EDIT THIS FILE! Use an override template instead. *} 2 | 3 |
4 |
5 | 6 | {if $link} 7 |

8 | {"A mail has been sent to the following email address: %1. This email contains a link you need to click so that we can confirm that the correct user is getting the new password."|i18n('mbpaex/userpaex/forgotpassword',,array($email))} 9 |

10 | {else} 11 | {if $wrong_email} 12 |
13 |

{"There is no registered user with that email address."|i18n('mbpaex/userpaex/forgotpassword')}

14 |
15 | {/if} 16 | {if $password_form} 17 | {if $password_changed} 18 |

19 | {"The password has been changed successfully."|i18n('mbpaex/userpaex/forgotpassword')} 20 |

21 | {else} 22 | {if $newPasswordNotMatch} 23 |
24 |

{"The passwords do not match. Please, be sure to enter the same password in both fields."|i18n('mbpaex/userpaex/forgotpassword')}

25 |
26 | {/if} 27 | {if $newPasswordNotValidate} 28 |
29 |

{"The new password is invalid, please choose new one."|i18n('mbpaex/userpaex/forgotpassword')}

30 |
31 | {/if} 32 | {if $newPasswordMustDiffer} 33 |
34 |

{"New password must be different from the old one. Please choose another password."|i18n('mbpaex/userpaex')}

35 |
36 | {/if} 37 | 38 |
39 |
40 |

{"Choose a new password"|i18n('mbpaex/userpaex/forgotpassword')}

41 |
42 | 43 |

44 | {"Enter your desired new password in the form below."|i18n('mbpaex/userpaex/forgotpassword')} 45 |

46 | 47 |
48 | 49 |
50 | 51 | 52 |
53 | 54 |
55 | 56 |
57 | 58 | 59 |
60 |
61 | {/if} 62 | {else} 63 | {if $wrong_key} 64 |
65 |

{"The key is invalid or has been used. "|i18n('mbpaex/userpaex/forgotpassword')}

66 |
67 | {else} 68 |
69 |
70 |

{"Have you forgotten your password?"|i18n('mbpaex/userpaex/forgotpassword')}

71 |
72 | 73 |

74 | {"If you have forgotten your password we can generate a new one for you. All you need to do is to enter your email address and we will create a new password for you."|i18n('mbpaex/userpaex/forgotpassword')} 75 |

76 | 77 |
78 | 79 |
80 | 81 |
82 | 83 |
84 | 85 |
86 |
87 | {/if} 88 | {/if} 89 | {/if} 90 | 91 |
92 |
93 | -------------------------------------------------------------------------------- /install/scripts/setpasswordlastupdated.php: -------------------------------------------------------------------------------- 1 | '', 17 | 'use-session' => true, 18 | 'use-modules' => false, 19 | 'use-extensions' => true ) ); 20 | 21 | $script->startup(); 22 | 23 | $endl = $cli->endlineString(); 24 | $webOutput = $cli->isWebOutput(); 25 | 26 | $debugOutput = false; 27 | $allowedDebugLevels = false; 28 | $useDebugAccumulators = false; 29 | $useDebugTimingpoints = false; 30 | $useIncludeFiles = false; 31 | $showSQL = false; 32 | 33 | function help() 34 | { 35 | $argv = $_SERVER['argv']; 36 | $cli = eZCLI::instance(); 37 | $cli->output( "Usage: " . $argv[0] . "\n" . 38 | "Update password_last_updated field to current time in ALL existing users.\n\n" . 39 | "General options:\n" . 40 | " -h,--help display this help and exit \n" . 41 | " --sql display sql queries\n" ); 42 | } 43 | 44 | for ( $i = 1; $i < count( $argv ); ++$i ) 45 | { 46 | $arg = $argv[$i]; 47 | if ( strlen( $arg ) > 0 and 48 | $arg[0] == '-' ) 49 | { 50 | if ( strlen( $arg ) > 1 and 51 | $arg[1] == '-' ) 52 | { 53 | $flag = substr( $arg, 2 ); 54 | if ( $flag == 'debug' ) 55 | { 56 | $debugOutput = true; 57 | } 58 | else if ( $flag == 'sql' ) 59 | { 60 | $showSQL = true; 61 | } 62 | else 63 | { 64 | help(); 65 | exit(); 66 | } 67 | } 68 | else 69 | { 70 | $flag = substr( $arg, 1, 1 ); 71 | if ( $flag == 'd' ) 72 | { 73 | $debugOutput = true; 74 | if ( strlen( $arg ) > 2 ) 75 | { 76 | $levels = explode( ',', substr( $arg, 2 ) ); 77 | $allowedDebugLevels = array(); 78 | foreach ( $levels as $level ) 79 | { 80 | if ( $level == 'all' ) 81 | { 82 | $useDebugAccumulators = true; 83 | $allowedDebugLevels = false; 84 | $useDebugTimingpoints = true; 85 | break; 86 | } 87 | if ( $level == 'accumulator' ) 88 | { 89 | $useDebugAccumulators = true; 90 | continue; 91 | } 92 | if ( $level == 'timing' ) 93 | { 94 | $useDebugTimingpoints = true; 95 | continue; 96 | } 97 | if ( $level == 'include' ) 98 | { 99 | $useIncludeFiles = true; 100 | } 101 | if ( $level == 'error' ) 102 | $level = eZDebug::LEVEL_ERROR; 103 | else if ( $level == 'warning' ) 104 | $level = eZDebug::LEVEL_WARNING; 105 | else if ( $level == 'debug' ) 106 | $level = eZDebug::LEVEL_DEBUG; 107 | else if ( $level == 'notice' ) 108 | $level = eZDebug::LEVEL_NOTICE; 109 | else if ( $level == 'timing' ) 110 | $level = eZDebug::LEVEL_TIMING; 111 | $allowedDebugLevels[] = $level; 112 | } 113 | } 114 | } 115 | else 116 | { 117 | help(); 118 | exit(); 119 | } 120 | } 121 | } 122 | else 123 | { 124 | help(); 125 | exit(); 126 | } 127 | } 128 | $script->setUseDebugOutput( $debugOutput ); 129 | $script->setAllowedDebugLevels( $allowedDebugLevels ); 130 | $script->setUseDebugAccumulators( $useDebugAccumulators ); 131 | $script->setUseDebugTimingPoints( $useDebugTimingpoints ); 132 | $script->setUseIncludeFiles( $useIncludeFiles ); 133 | 134 | $script->setDebugMessage( "\n\n" . str_repeat( '#', 36 ) . $cli->style( 'emphasize' ) . " DEBUG " . $cli->style( 'emphasize-end' ) . str_repeat( '#', 36 ) . "\n" ); 135 | 136 | $script->initialize(); 137 | if ( !$script->isInitialized() ) 138 | { 139 | $cli->error( 'Error initializing script: ' . $script->initializationError() . '.' ); 140 | $script->shutdown(); 141 | exit(); 142 | } 143 | 144 | 145 | $cli->output( "eZPaEx: Set password last updated to current time in all existing users" ); 146 | 147 | $db = eZDB::instance(); 148 | $db->setIsSQLOutputEnabled( $showSQL ); 149 | $db->begin(); 150 | 151 | $def = eZPaEx::definition(); 152 | 153 | $table = $def['name']; 154 | 155 | $current_time = time(); 156 | 157 | $query = "UPDATE $table SET password_last_updated = $current_time"; 158 | 159 | $db->query( $query ); 160 | $db->commit(); 161 | 162 | // The transaction check 163 | $transactionCounterCheck = eZDB::checkTransactionCounter(); 164 | if ( isset( $transactionCounterCheck['error'] ) ) 165 | $cli->error( $transactionCounterCheck['error'] ); 166 | 167 | $cli->output( "eZPaEx: Done." ); 168 | 169 | $script->shutdown(); 170 | exit(); 171 | 172 | ?> 173 | -------------------------------------------------------------------------------- /design/admin/override/templates/node/view/full_caching_disabled.tpl: -------------------------------------------------------------------------------- 1 | {set-block scope=root variable=cache_ttl}0{/set-block} 2 | 3 |
4 |
5 | 6 | {include uri='design:infocollection_validation.tpl'} 7 | 8 |
9 | 10 | {* Content window. *} 11 |
12 | 13 | {* DESIGN: Header START *}
14 | 15 | {def $js_class_languages = $node.object.content_class.prioritized_languages_js_array 16 | $disable_another_language = cond( eq( 0, count( $node.object.content_class.can_create_languages ) ),"'edit-class-another-language'", '-1' ) 17 | $disabled_sub_menu = "['class-createnodefeed', 'class-removenodefeed']" 18 | $hide_status = ''} 19 | 20 | {if $node.is_invisible} 21 | {set $hide_status = concat( '(', $node.hidden_status_string, ')' )} 22 | {/if} 23 | 24 | {* Check if user has rights and if there are any RSS/ATOM Feed exports for current node *} 25 | {if is_set( ezini( 'RSSSettings', 'DefaultFeedItemClasses', 'site.ini' )[ $node.class_identifier ] )} 26 | {def $create_rss_access = fetch( 'user', 'has_access_to', hash( 'module', 'rss', 'function', 'edit' ) )} 27 | {if $create_rss_access} 28 | {if fetch( 'rss', 'has_export_by_node', hash( 'node_id', $node.node_id ) )} 29 | {set $disabled_sub_menu = "'class-createnodefeed'"} 30 | {else} 31 | {set $disabled_sub_menu = "'class-removenodefeed'"} 32 | {/if} 33 | {/if} 34 | {/if} 35 | 36 |

{$node.class_identifier|class_icon( normal, $node.class_name )} {$node.name|wash} [{$node.class_name|wash}] {$hide_status}

37 | 38 | {undef $js_class_languages $disable_another_language $disabled_sub_menu $hide_status} 39 | 40 | {* DESIGN: Mainline *}
41 | 42 | {* DESIGN: Header END *}
43 | 44 | 45 | {* DESIGN: Content START *}
46 | 47 |
48 |

{'Last modified'|i18n( 'design/admin/node/view/full' )}: {$node.object.modified|l10n(shortdatetime)}, {$node.object.current.creator.name|wash} ({'Node ID'|i18n( 'design/admin/node/view/full' )}: {$node.node_id}, {'Object ID'|i18n( 'design/admin/node/view/full' )}: {$node.object.id})

49 |

{$node.object.current_language_object.locale_object.intl_language_name} {$language_code|wash()}

50 |
51 |
52 | 53 |
54 | 55 | {include uri='design:window_controls.tpl'} 56 | 57 |
58 | 59 | {* DESIGN: Content END *}
60 | 61 |
62 | {* DESIGN: Control bar START *} 63 | 64 |
65 | 66 | 67 | 68 | 69 |
70 |
71 | {* Edit button. *} 72 | {def $can_create_languages = $node.object.can_create_languages 73 | $languages = fetch( 'content', 'prioritized_languages' )} 74 | {if $node.can_edit} 75 | {if and(eq( $languages|count, 1 ), is_set( $languages[0] ) )} 76 | 77 | {else} 78 | 86 | {/if} 87 | 88 | {else} 89 | 92 | 93 | {/if} 94 | {undef $can_create_languages} 95 | 96 | {* Move button. *} 97 | {if $node.can_move} 98 | 99 | {else} 100 | 101 | {/if} 102 | 103 | {* Remove button. *} 104 | {if $node.can_remove} 105 | 106 | {else} 107 | 108 | {/if} 109 |
110 |
111 | 112 |
113 |

114 | {* Link to manage versions *} 115 | {'Manage versions'|i18n( 'design/admin/content/edit' )} 116 |

117 |
118 | 119 |
120 |
121 | {* DESIGN: Control bar END *} 122 |
123 | 124 | 125 |
126 | 127 | {* Children window.*} 128 |
129 | {if $node.is_container} 130 | {include uri='design:children.tpl'} 131 | {else} 132 | {include uri='design:no_children.tpl'} 133 | {/if} 134 |
135 | 136 |
137 | 138 |
139 |
140 | -------------------------------------------------------------------------------- /modules/userpaex/password.php: -------------------------------------------------------------------------------- 1 | attribute( "contentobject_id" ); 13 | $http = eZHTTPTool::instance(); 14 | $Module = $Params["Module"]; 15 | $message = 0; 16 | $oldPasswordNotValid = 0; 17 | $newPasswordNotMatch = 0; 18 | $newPasswordTooShort = 0; 19 | $newPasswordNotValidate = 0; 20 | $newPasswordMustDiffer = 0; 21 | $userRedirectURI = ''; 22 | 23 | $userRedirectURI = $Module->actionParameter( 'UserRedirectURI' ); 24 | 25 | if ( $http->hasSessionVariable( "LastAccessesURI" ) ) 26 | $userRedirectURI = $http->sessionVariable( "LastAccessesURI" ); 27 | 28 | $redirectionURI = $userRedirectURI; 29 | if ( $redirectionURI == '' ) 30 | $redirectionURI = $ini->variable( 'SiteSettings', 'DefaultPage' ); 31 | 32 | if( !isset( $oldPassword ) ) 33 | $oldPassword = ''; 34 | 35 | if( !isset( $newPassword ) ) 36 | $newPassword = ''; 37 | 38 | if( !isset( $confirmPassword ) ) 39 | $confirmPassword = ''; 40 | 41 | if ( is_numeric( $Params["UserID"] ) ) 42 | $UserID = $Params["UserID"]; 43 | else 44 | $UserID = false; 45 | 46 | $user = eZUser::fetch( $UserID ); 47 | 48 | if ( $http->hasPostVariable( "OKButton" ) && $user) 49 | { 50 | if ( $http->hasPostVariable( "oldPassword" ) ) 51 | { 52 | $oldPassword = $http->postVariable( "oldPassword" ); 53 | } 54 | if ( $http->hasPostVariable( "newPassword" ) ) 55 | { 56 | $newPassword = $http->postVariable( "newPassword" ); 57 | } 58 | if ( $http->hasPostVariable( "confirmPassword" ) ) 59 | { 60 | $confirmPassword = $http->postVariable( "confirmPassword" ); 61 | } 62 | 63 | $login = $user->attribute( "login" ); 64 | $type = $user->attribute( "password_hash_type" ); 65 | $hash = $user->attribute( "password_hash" ); 66 | $site = $user->site(); 67 | 68 | if ( $user->authenticateHash( $login, $oldPassword, $site, $type, $hash ) ) // Old password is correct 69 | { 70 | if ( $newPassword == $confirmPassword ) 71 | { 72 | if ( !$user->validatePassword($newPassword) ) 73 | { 74 | // if audit is enabled password changes should be logged 75 | eZAudit::writeAudit( 'user-password-change-self-fail', array( 'UserID: ' => $UserID, 'Login: ' => $login, 76 | 'Comment: ' => 'Password not pass standard validation' ) ); 77 | 78 | $newPasswordNotValidate = 1; 79 | } 80 | else 81 | { 82 | // Patch for use mbpaex::validatePassword 83 | $paex = eZPaEx::getPaEx( $UserID ); 84 | if (!$paex->validatePassword($newPassword)) 85 | { 86 | // if audit is enabled password changes should be logged 87 | eZAudit::writeAudit( 'user-password-change-self-fail', array( 'UserID: ' => $UserID, 'Login: ' => $login, 88 | 'Comment: ' => 'Password not pass PAEX validation' ) ); 89 | $newPasswordNotValidate = 1; 90 | } 91 | else 92 | { 93 | $oldHash = $user->createHash( $login, $oldPassword, $site, $type ); 94 | $newHash = $user->createHash( $login, $newPassword, $site, $type ); 95 | if ($oldHash == $newHash) 96 | { 97 | // if audit is enabled password changes should be logged 98 | eZAudit::writeAudit( 'user-password-change-self-fail', array( 'UserID: ' => $UserID, 'Login: ' => $login, 99 | 'Comment: ' => 'New and old password are the same' ) ); 100 | $newPasswordMustDiffer = 1; 101 | } 102 | else 103 | { 104 | // if audit is enabled password changes should be logged 105 | eZAudit::writeAudit( 'user-password-change-self', array( 'UserID: ' => $UserID, 'Login: ' => $login ) ); 106 | 107 | $user->setAttribute( "password_hash", $newHash ); 108 | $user->store(); 109 | $paex->resetPasswordLastUpdated(); 110 | $oldPassword = ''; 111 | 112 | eZUser::setCurrentlyLoggedInUser( $user, $UserID ); 113 | eZUser::updateLastVisit( $UserID, true ); 114 | 115 | if ( $http->hasPostVariable( "RedirectOnChange" ) ) 116 | { 117 | return $Module->redirectTo( $http->postVariable( "RedirectOnChange" ) ); 118 | } 119 | eZRedirectManager::redirectTo( $Module, $redirectionURI ); 120 | return; 121 | } 122 | } 123 | } 124 | $newPassword = ''; 125 | $confirmPassword = ''; 126 | $message = true; 127 | } 128 | else 129 | { 130 | // if audit is enabled password changes should be logged 131 | eZAudit::writeAudit( 'user-password-change-self-fail', array( 'UserID: ' => $UserID, 'Login: ' => $login, 132 | 'Comment: ' => 'Password not match password confirmation' ) ); 133 | $newPassword = ""; 134 | $confirmPassword = ""; 135 | $newPasswordNotMatch = 1; 136 | $message = true; 137 | } 138 | } 139 | else 140 | { 141 | // if audit is enabled password changes should be logged 142 | eZAudit::writeAudit( 'user-password-change-self-fail', array( 'UserID: ' => $UserID, 'Login: ' => $login, 143 | 'Comment: ' => 'Old password incorrect' ) ); 144 | $oldPassword = ""; 145 | $oldPasswordNotValid = 1; 146 | $message = true; 147 | } 148 | } 149 | 150 | if ( $http->hasPostVariable( "CancelButton" ) || !$user ) 151 | { 152 | if ( $http->hasPostVariable( "RedirectOnCancel" ) ) 153 | { 154 | return $Module->redirectTo( $http->postVariable( "RedirectOnCancel" ) ); 155 | } 156 | eZRedirectManager::redirectTo( $Module, $redirectionURI ); 157 | return; 158 | } 159 | 160 | $Module->setTitle( "Edit user information" ); 161 | // Template handling 162 | $tpl = eZTemplate::factory(); 163 | $tpl->setVariable( "module", $Module ); 164 | $tpl->setVariable( "http", $http ); 165 | $tpl->setVariable( "userID", $UserID ); 166 | $tpl->setVariable( "userAccount", $user ); 167 | $tpl->setVariable( "oldPassword", $oldPassword ); 168 | $tpl->setVariable( "newPassword", $newPassword ); 169 | $tpl->setVariable( "confirmPassword", $confirmPassword ); 170 | $tpl->setVariable( "oldPasswordNotValid", $oldPasswordNotValid ); 171 | $tpl->setVariable( "newPasswordNotMatch", $newPasswordNotMatch ); 172 | $tpl->setVariable( "newPasswordTooShort", $newPasswordTooShort ); 173 | $tpl->setVariable( "newPasswordNotValidate", $newPasswordNotValidate ); 174 | $tpl->setVariable( "newPasswordMustDiffer", $newPasswordMustDiffer ); 175 | $tpl->setVariable( "message", $message ); 176 | 177 | $Result = array(); 178 | $Result['path'] = array( array( 'text' => ezpI18n::tr( 'kernel/user', 'User' ), 179 | 'url' => false ), 180 | array( 'text' => ezpI18n::tr( 'kernel/user', 'Change password' ), 181 | 'url' => false ) ); 182 | $Result['content'] = $tpl->fetch( "design:userpaex/password.tpl" ); 183 | 184 | $currentuser = eZUser::currentUser(); 185 | if ( !$currentuser->isLoggedIn() ) 186 | { 187 | if ( $ini->variable( 'SiteSettings', 'LoginPage' ) == 'custom' ) 188 | { 189 | $Result['pagelayout'] = 'loginpagelayout.tpl'; 190 | } 191 | } 192 | ?> 193 | -------------------------------------------------------------------------------- /doc/INSTALL.txt: -------------------------------------------------------------------------------- 1 | Password Expiration Extension (v1.0RC1) 2 | ================================================ 3 | 4 | 0) Release Info 5 | 1) Install 6 | 2) Brief usage instructions 7 | 3) Forgot password procedure 8 | 4) UpdateChildren feature 9 | 5) "Password about to Expire" notification 10 | 6) Audit logs 11 | 7) Hook for mbtoken usage 12 | 8) TODO list 13 | 9) RFE 14 | 10) About 15 | 16 | 0. Release Info 17 | ------------ 18 | 19 | Current version: mbPaEx_1.4 20 | Release Date: March 29th 2011. 21 | 22 | Compatible with eZ Publish v4.x 23 | 24 | 25 | 1. Install 26 | ------- 27 | 28 | - Put the ezmbpaex folder inside your extension folder 29 | 30 | - Update the ezpublish database, execute from , replacing 31 | with the database system you're running eZ Publish on (mysql, oracle or postgresql): 32 | 33 | $ mysql -u -p < extension/ezmbpaex/sql//mbpaex.sql 34 | 35 | - Customize default settings in 36 | extension/ezmbpaex/settings/mbpaex.ini (or an override): 37 | 38 | [mbpaexSettings] 39 | # Regular expression used for password validation when 40 | # none is defined in the contentobject 41 | PasswordValidationRegexp= 42 | 43 | # Default lifetime for password in DAYS 44 | # 0 means no limit (passwords never expire) 45 | DefaultPasswordLifeTime=0 46 | 47 | # Number of seconds before password expiration to send a 48 | # mail notification to the user 49 | # Default 172800 (2 days) 50 | ExpirationNotification=172800 51 | 52 | # Number of seconds that the forgot password generated hash will be valid 53 | # Default 86400 (1 day) 54 | ForgotPasswordHashLifeTime=86400 55 | 56 | # Login of the eZ user used in the ezmbpaex_updatechildren cronjob, must 57 | # have access to read the Users section. 58 | UpdateChildrenUser=admin 59 | 60 | - Activate the extension in your site.ini 61 | 62 | ActiveExtensions[]=ezmbpaex 63 | 64 | - To prevent undesired access to default user module views that don't take care about the 65 | password expiration settings there should only be enabled the views needed, then standard 66 | ones will get access denied. These changes should be added to the global override of 67 | site.ini: 68 | 69 | [SiteAccessSettings] 70 | AnonymousAccessList[] 71 | AnonymousAccessList[]=user/success 72 | AnonymousAccessList[]=user/activate 73 | AnonymousAccessList[]=userpaex/password 74 | AnonymousAccessList[]=userpaex/forgotpassword 75 | 76 | [RoleSettings] 77 | PolicyOmitList[] 78 | PolicyOmitList[]=user/login 79 | PolicyOmitList[]=user/logout 80 | PolicyOmitList[]=userpaex/password 81 | PolicyOmitList[]=userpaex/forgotpassword 82 | 83 | - Setup override template used in replacement of node/view/full.tpl to display 84 | users and users groups in admin interface: 85 | 86 | Inside /extension/ezmbpaex/settings/siteaccess you will find a folder 87 | that will be used in the "admin" siteaccess. If your admin siteaccess has a 88 | different name, the content of the override.ini.append.php file must be added 89 | to the override.ini of your custom admin siteaccess. 90 | 91 | - Re-generate autoloads array to include new classes present in mbPaEx extension: 92 | 93 | $ bin/php/ezpgenerateautoloads.php --extension 94 | 95 | - Clear all caches 96 | 97 | - After installation, a new datatype would be available to add as an attribute in 98 | the User and User Group classes, "Password Expiration". You must add this datatype 99 | to all your User group and User content classes if you want to use the extension. 100 | 101 | 102 | 2. Brief usage instructions 103 | ------------------------ 104 | 105 | When the attribute gets created it takes the values set in the ini file as default 106 | values. 107 | 108 | To prevent that all existing users are forced to change their passwords, there is 109 | a script available to reset the password_last_updated value of all users to current 110 | time. You can run this script with the following command: 111 | 112 | $ php extension/ezmbpaex/install/scripts/setpasswordlastupdated.php 113 | 114 | When you customize the values in a user group, a checkbox would appear to update 115 | children nodes with the values of the current group, this way you can customize 116 | the password lifetime and validation regexp per group easily. (See point 4) 117 | 118 | There is a new function to restrict if a user can edit the paex data, editpaex. 119 | If anyone other than admin should be able to update the paex data, a new policy 120 | with this function should be added to his role. 121 | 122 | When someone changes the password for another user, the password last update time 123 | is set to 0 to force the user change his password the next time he tries to log in. 124 | 125 | NOTE: There must be a password lifetime defined in order to force the user 126 | change his password. If PasswordLifeTime is set to 0 the user never gets 127 | forced to change its password (the password never expires). 128 | 129 | When the password for a user is expired, the user never gets logged in, he only 130 | can access the change password view from userpaex module to change his password. 131 | 132 | When a user changes their password, the system prevents to enter the same 133 | password currently set, this way a new different one must be used. 134 | 135 | When a user or group is published the first time, if the current user don't have 136 | "editpaex" permission set in their roles, the system automatically obtains the 137 | actual paex data set in parent. 138 | If the user have "editpaex" permission, the values entered in the form will be used, 139 | to use values set in parent, these fields must be cleared. 140 | 141 | 142 | 3. Forgot password procedure 143 | ------------------------- 144 | 145 | There is a new view in the userpaex module, forgotpassword, to manage the forgot 146 | password function. 147 | 148 | Has small modifications from the eZ one, to note: 149 | 150 | - The user is required to enter his email address 151 | - A new hash key is generated, and the user receives an email with a link pointing 152 | to a form to choose a new password. Also in this email, there is an expiration 153 | datetime to inform the user that this link should be removed. 154 | - When the user clicks the link and sets a new password, the hash key is removed 155 | from the forgot password table. 156 | - The time the hash key remains valid is defined in the ini value 157 | ForgotPasswordHashLifeTime in seconds, with a default value of 86400 (24 hours) 158 | - If a second hash key is requested without having used the previous one, they 159 | will be removed, so only the last key generated is valid. 160 | 161 | 162 | 4. UpdateChildren feature 163 | ---------------------- 164 | 165 | In order to prevent failures during the process and to make the user edit process 166 | quicker, the update children has moved to a cronjob, so a new cronjob task has to 167 | be set for the update be actually done. 168 | The cronjob part defined to do the actual update of the children is 169 | "ezmbpaex_updatechildren" 170 | 171 | The cronjob can be manually run with the following command from folder: 172 | 173 | $php runcronjobs.php ezmbpaex_updatechildren 174 | 175 | When a node is marked to update his children, a notification text will be shown 176 | in the admin view template for that node. 177 | 178 | Only group nodes have the updatechildren checkbox displayed in the edit template. 179 | 180 | The updates are applied from outer to inner nodes, so, if you have a node set to 181 | update his chidren, and then one of the children nodes also set to update his ones, 182 | that children node will not be updated with the data from parent, instead, their 183 | children will be updated with his data. 184 | 185 | It's ok to set up the cronjob to be run in the frequent cronjob part. 186 | 187 | 188 | 5. "Password about to Expire" notification 189 | --------------------------------------- 190 | 191 | Optionally if you want your users get notified when their password is about to 192 | expire, a new cronjob can be set up to search users based on their password last 193 | updated time and password lifetime, and if it results in a password remain time 194 | less that configured expiration notification time, a mail will be generated and 195 | sent to the users so they can change their password prior to expiration. 196 | 197 | The cronjob can be manually run with the following command from folder: 198 | 199 | $ php runcronjobs.php ezmbpaex_send_expiry_notifications 200 | 201 | Only one notification sent to each user, and no more notifications are sent until 202 | the user changes his password and it expires again. 203 | 204 | 205 | 6. Audit logs 206 | ---------- 207 | 208 | In order to enhance security new audit functions have been defined for ezmbpaex operations 209 | that can be enabled in an override for the audit.ini settings file: 210 | 211 | - user-password-change 212 | 213 | Logs pasword changes made to third party accounts (admin changing password for a 214 | user) 215 | 216 | - user-password-change-self 217 | 218 | Logs when users change their own password 219 | 220 | - user-password-change-self-fail 221 | 222 | Logs when users try to change their own password and send wrong current password 223 | 224 | - user-forgotpassword 225 | 226 | User has made use of the forgotpassword function of userpaex module 227 | 228 | - user-forgotpassword-fail 229 | 230 | User tries to made use of the forgotpassword function of userpaex module but 231 | some error occurred (the actual error is also logged) 232 | 233 | 7. Hook for mbtoken usage 234 | ---------------------- 235 | 236 | The loginhandler has been updated to include the possibility to use the mbtoken extension, 237 | that will add extra security to the login process by the use of a security token. 238 | More info available in mbtoken extension. 239 | 240 | 241 | 8. TODO list 242 | --------- 243 | 244 | - Prevent user enter same password that have set, when editting user contentobject 245 | from admin interface (I think that password history has to be implemented to do 246 | this). 247 | 248 | 249 | 9. Request for enhancement 250 | ------------------------ 251 | 252 | - Password history 253 | 254 | 255 | 10. About ezmbpaex 256 | -------------- 257 | 258 | This extension was developed by Microblau with eZ Systems support. 259 | -------------------------------------------------------------------------------- /modules/userpaex/forgotpassword.php: -------------------------------------------------------------------------------- 1 | setVariable( 'generated', false ); 12 | $tpl->setVariable( 'wrong_email', false ); 13 | $tpl->setVariable( 'link', false ); 14 | $tpl->setVariable( 'wrong_key', false ); 15 | $tpl->setVariable( 'password_form', false ); 16 | $tpl->setVariable( 'newPasswordNotValidate', false ); 17 | $tpl->setVariable( 'newPasswordMustDiffer', false ); 18 | $tpl->setVariable( 'password_changed', false ); 19 | $tpl->setVariable( 'newPasswordNotMatch', false ); 20 | 21 | $http = eZHTTPTool::instance(); 22 | $module = $Params["Module"]; 23 | $hashKey = $Params["HashKey"]; 24 | $hashKeyValidated = false; 25 | $mbpaex_ini = eZINI::instance('mbpaex.ini'); 26 | $forgotPasswdHashLifeTime = $mbpaex_ini->variable( "mbpaexSettings", "ForgotPasswordHashLifeTime" ); 27 | $ini = eZINI::instance(); 28 | 29 | if ( strlen( $hashKey ) == 32 ) 30 | { 31 | $currentTime = time(); 32 | 33 | $forgotPasswdObj = eZForgotPassword::fetchByKey( $hashKey ); 34 | if (!is_object($forgotPasswdObj)) // HashKey not found 35 | { 36 | // if audit is enabled password changes should be logged 37 | eZAudit::writeAudit( 'user-forgotpassword-fail', array( 'HashKey' => $hashKey, 38 | 'Comment' => 'HashKey not found' ) ); 39 | 40 | $tpl->setVariable( 'wrong_key', true ); 41 | } 42 | elseif (($currentTime - $forgotPasswdObj->attribute('time')) > $forgotPasswdHashLifeTime) // HashKey expired 43 | { 44 | // if audit is enabled password changes should be logged 45 | eZAudit::writeAudit( 'user-forgotpassword-fail', array( 'HashKey' => $hashKey, 46 | 'Comment' => 'HashKey expired, proceed to remove' ) ); 47 | 48 | $forgotPasswdObj->remove(); // Remove expired hash 49 | $tpl->setVariable( 'wrong_key', true ); 50 | } 51 | else // HashKey OK -> show/process change password form 52 | { 53 | $tpl->setVariable( 'password_form', true ); 54 | $tpl->setVariable( 'HashKey', $hashKey ); 55 | $hashKeyValidated = true; 56 | } 57 | } 58 | else if ( strlen( $hashKey ) > 4 ) 59 | { 60 | // if audit is enabled password changes should be logged 61 | eZAudit::writeAudit( 'user-forgotpassword-fail', array( 'HashKey' => $hashKey, 62 | 'Comment' => 'HashKey not found' ) ); 63 | 64 | $tpl->setVariable( 'wrong_key', true ); 65 | } 66 | 67 | if ( $module->isCurrentAction( "Generate" ) ) 68 | { 69 | $passwordLength = $ini->variable( "UserSettings", "GeneratePasswordLength" ); 70 | $password = eZUser::createPassword( $passwordLength ); 71 | $passwordConfirm = $password; 72 | 73 | if ( $module->hasActionParameter( "Email" ) && eZMail::validate($module->actionParameter( "Email" )) ) 74 | { 75 | $email = $module->actionParameter( "Email" ); 76 | if ( trim( $email ) != "" ) 77 | { 78 | $users = eZPersistentObject::fetchObjectList( eZUser::definition(), 79 | null, 80 | array( 'email' => $email ), 81 | null, 82 | null, 83 | true ); 84 | } 85 | if ( !empty( $users ) ) 86 | { 87 | $user = $users[0]; 88 | $time = time(); 89 | $hashKey = md5( $time . ":" . mt_rand() ); 90 | 91 | $db = eZDB::instance(); 92 | $db->begin(); 93 | 94 | // Remove previous generated hash keys for same user 95 | eZForgotPassword::removeByUserID($user->id()); 96 | 97 | $forgotPasswdObj = eZForgotPassword::createNew( $user->id(), $hashKey, $time ); 98 | $forgotPasswdObj->store(); 99 | 100 | $userToSendEmail = $user; 101 | $receiver = $email; 102 | 103 | $mail = new eZMail(); 104 | if ( !$mail->validate( $receiver ) ) 105 | { 106 | } 107 | $tpl = eZTemplate::factory(); 108 | $tpl->setVariable( 'user', $userToSendEmail ); 109 | $tpl->setVariable( 'object', $userToSendEmail->attribute( 'contentobject' ) ); 110 | $tpl->setVariable( 'password', $password ); 111 | $tpl->setVariable( 'link', true ); 112 | $tpl->setVariable( 'hash_key', $hashKey ); 113 | $tpl->setVariable( 'hash_key_lifetime', date("d/m/Y H:i",time() + $forgotPasswdHashLifeTime)); 114 | 115 | $http = eZHTTPTool::instance(); 116 | $http->UseFullUrl = true; 117 | $templateResult = $tpl->fetch( 'design:userpaex/forgotpasswordmail.tpl' ); 118 | $http->UseFullUrl = false; 119 | $emailSender = $ini->variable( 'MailSettings', 'EmailSender' ); 120 | if ( !$emailSender ) 121 | $emailSender = $ini->variable( 'MailSettings', 'AdminEmail' ); 122 | $mail->setSender( $emailSender ); 123 | $mail->setReceiver( $receiver ); 124 | $subject = ezpI18n::tr( 'kernel/user/register', 'Registration info' ); 125 | if ( $tpl->hasVariable( 'subject' ) ) 126 | $subject = $tpl->variable( 'subject' ); 127 | $mail->setSubject( $subject ); 128 | $mail->setBody( $templateResult ); 129 | $mailResult = eZMailTransport::send( $mail ); 130 | $tpl->setVariable( 'email', $email ); 131 | $db->commit(); 132 | 133 | // if audit is enabled password changes should be logged 134 | eZAudit::writeAudit( 'user-forgotpassword', array( 'Email' => $email, 135 | 'Comment' => 'Forgotpassword email sent' ) ); 136 | 137 | } 138 | else 139 | { 140 | // if audit is enabled password changes should be logged 141 | eZAudit::writeAudit( 'user-forgotpassword-fail', array( 'Email' => $email, 142 | 'Comment' => 'Email address not found' ) ); 143 | 144 | $tpl->setVariable( 'wrong_email', $email ); 145 | } 146 | } 147 | } 148 | else if ( $module->isCurrentAction( "ChangePassword" ) && $hashKeyValidated ) 149 | { 150 | if ( $module->hasActionParameter( "NewPassword" ) ) 151 | $newPassword = $module->actionParameter( "NewPassword" ); 152 | else 153 | $newPassword = false; 154 | 155 | if ( $module->hasActionParameter( "NewPasswordConfirm" ) ) 156 | $confirmPassword = $module->actionParameter( "NewPasswordConfirm" ); 157 | else 158 | $confirmPassword = false; 159 | 160 | // The forgotPasswdObj was previously validated, fetch the corresponding user object 161 | $UserID = $forgotPasswdObj->attribute( 'user_id' ); 162 | $user = eZUser::fetch($UserID); 163 | $login = $user->attribute( "login" ); 164 | $type = $user->attribute( "password_hash_type" ); 165 | $hash = $user->attribute( "password_hash" ); 166 | $site = $user->site(); 167 | 168 | if ( $newPassword == $confirmPassword ) 169 | { 170 | if ( !$user->validatePassword($newPassword) ) // Password must meet "old" validation rules 171 | { 172 | // if audit is enabled password changes should be logged 173 | eZAudit::writeAudit( 'user-forgotpassword-fail', array( 'UserID' => $UserID, 'Login' => $login, 174 | 'Comment: ' => 'Password not pass standard validation' ) ); 175 | 176 | $tpl->setVariable( 'newPasswordNotValidate', true); 177 | } 178 | else 179 | { 180 | // Patch for use mbpaex::validatePassword 181 | $paex = eZPaEx::getPaEx($UserID); 182 | if (!$paex->validatePassword($newPassword)) 183 | { 184 | // if audit is enabled password changes should be logged 185 | eZAudit::writeAudit( 'user-forgotpassword-fail', array( 'UserID' => $UserID, 'Login' => $login, 186 | 'Comment: ' => 'Password not pass PAEX validation' ) ); 187 | 188 | $tpl->setVariable( 'newPasswordNotValidate', true); 189 | } 190 | else 191 | { 192 | $newHash = $user->createHash( $login, $newPassword, $site, $type ); 193 | if ($newHash == $user->attribute('password_hash')) 194 | { 195 | // if audit is enabled password changes should be logged 196 | eZAudit::writeAudit( 'user-forgotpassword-fail', array( 'UserID' => $UserID, 'Login' => $login, 197 | 'Comment: ' => 'New and old password are the same' ) ); 198 | 199 | $tpl->setVariable( 'newPasswordMustDiffer', true); 200 | } 201 | else 202 | { 203 | // if audit is enabled password changes should be logged 204 | eZAudit::writeAudit( 'user-forgotpassword', array( 'UserID' => $UserID, 'Login' => $login, 205 | 'Comment: ' => 'Password changed successfully' ) ); 206 | 207 | $user->setAttribute( "password_hash", $newHash ); 208 | $user->store(); 209 | $paex->resetPasswordLastUpdated(); 210 | 211 | $forgotPasswdObj->remove(); 212 | $tpl->setVariable( 'password_changed', true); 213 | } 214 | } 215 | } 216 | } 217 | else 218 | { 219 | // if audit is enabled password changes should be logged 220 | eZAudit::writeAudit( 'user-forgotpassword-fail', array( 'UserID' => $UserID, 'Login' => $login, 221 | 'Comment: ' => 'Password not match password confirmation' ) ); 222 | 223 | $tpl->setVariable( 'newPasswordNotMatch', true); 224 | } 225 | } 226 | 227 | $Result = array(); 228 | $Result['content'] = $tpl->fetch( 'design:userpaex/forgotpassword.tpl' ); 229 | $Result['path'] = array( array( 'text' => ezpI18n::tr( 'kernel/user', 'User' ), 230 | 'url' => false ), 231 | array( 'text' => ezpI18n::tr( 'kernel/user', 'Forgot password' ), 232 | 'url' => false ) ); 233 | 234 | if ( $ini->variable( 'SiteSettings', 'LoginPage' ) == 'custom' ) 235 | { 236 | $Result['pagelayout'] = 'loginpagelayout.tpl'; 237 | } 238 | 239 | ?> 240 | -------------------------------------------------------------------------------- /translations/untranslated/translation.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | design/admin/content/edit 6 | 7 | View and manage (copy, delete, etc.) the versions of this object. 8 | 9 | 10 | 11 | Manage versions 12 | 13 | 14 | 15 | 16 | design/admin/node/view/full 17 | 18 | Last modified 19 | 20 | 21 | 22 | Node ID 23 | 24 | 25 | 26 | Object ID 27 | 28 | 29 | 30 | Another language 31 | 32 | 33 | 34 | Edit 35 | 36 | 37 | 38 | Edit the contents of this item. 39 | 40 | 41 | 42 | Not available 43 | 44 | 45 | 46 | You do not have permission to edit this item. 47 | 48 | 49 | 50 | Move 51 | 52 | 53 | 54 | Move this item to another location. 55 | 56 | 57 | 58 | You do not have permission to move this item to another location. 59 | 60 | 61 | 62 | Remove 63 | 64 | 65 | 66 | Remove this item. 67 | 68 | 69 | 70 | You do not have permission to remove this item. 71 | 72 | 73 | 74 | Preview 75 | 76 | 77 | 78 | New translation 79 | 80 | 81 | 82 | 83 | design/admin/pagelayout 84 | 85 | Current user 86 | 87 | 88 | 89 | Change name, email, password, etc. 90 | 91 | 92 | 93 | Change information 94 | 95 | 96 | 97 | Change user info 98 | 99 | 100 | 101 | Change password for <%username>. 102 | 103 | 104 | 105 | Change password 106 | 107 | 108 | 109 | There is %basket_count item in the shopping basket. 110 | 111 | 112 | 113 | Shopping basket (%basket_count) 114 | 115 | 116 | 117 | There are %basket_count items in the shopping basket. 118 | 119 | 120 | 121 | Logout from the system. 122 | 123 | 124 | 125 | Logout 126 | 127 | 128 | 129 | 130 | design/standard/user/forgotpassword 131 | 132 | Your account information 133 | 134 | 135 | 136 | Email 137 | 138 | 139 | 140 | 141 | kernel/user 142 | 143 | User 144 | 145 | 146 | 147 | Forgot password 148 | 149 | 150 | 151 | Change password 152 | 153 | 154 | 155 | 156 | kernel/user/register 157 | 158 | Registration info 159 | 160 | 161 | 162 | 163 | mbpaex/classes/datatypes 164 | 165 | Password Expiration 166 | Datatype name 167 | 168 | 169 | 170 | The password lifetime must be an integer >= 0 171 | 172 | 173 | 174 | The expiration notification time must be an integer >= 86400 175 | 176 | 177 | 178 | The password doesn't match the validation rule. 179 | 180 | 181 | 182 | Wrong value in updatechildren field 183 | 184 | 185 | 186 | 187 | mbpaex/content/datatype 188 | 189 | Validation Regexp 190 | 191 | 192 | 193 | Password LifeTime (DAYS) 194 | 195 | 196 | 197 | Expiration Notification (SECONDS) 198 | 199 | 200 | 201 | Current password status: 202 | 203 | 204 | 205 | expired 206 | 207 | 208 | 209 | active 210 | 211 | 212 | 213 | Update children nodes? 214 | 215 | 216 | 217 | undefined 218 | 219 | 220 | 221 | Password status 222 | 223 | 224 | 225 | Children update pending, will be done in a few minutes... 226 | 227 | 228 | 229 | 230 | mbpaex/userpaex 231 | 232 | Change password for user 233 | 234 | 235 | 236 | Please retype your old password. 237 | 238 | 239 | 240 | Password didn't match, please retype your new password. 241 | 242 | 243 | 244 | Password didn't validate, please retype your new password. 245 | 246 | 247 | 248 | New password must be different from the old one. Please choose another password. 249 | 250 | 251 | 252 | Password successfully updated. 253 | 254 | 255 | 256 | Old password 257 | 258 | 259 | 260 | New password 261 | 262 | 263 | 264 | Retype password 265 | 266 | 267 | 268 | OK 269 | 270 | 271 | 272 | Cancel 273 | 274 | 275 | 276 | %siteurl your password is about to expire 277 | 278 | 279 | 280 | Your password is about to expire 281 | 282 | 283 | 284 | 285 | mbpaex/userpaex/forgotpassword 286 | 287 | Click here to set your new password 288 | 289 | 290 | 291 | A mail has been sent to the following email address: %1. This email contains a link you need to click so that we can confirm that the correct user is getting the new password. 292 | 293 | 294 | 295 | There is no registered user with that email address. 296 | 297 | 298 | 299 | The password has been changed successfully. 300 | 301 | 302 | 303 | The passwords do not match. Please, be sure to enter the same password in both fields. 304 | 305 | 306 | 307 | The new password is invalid, please choose new one. 308 | 309 | 310 | 311 | Choose a new password 312 | 313 | 314 | 315 | Enter your desired new password in the form below. 316 | 317 | 318 | 319 | Password 320 | 321 | 322 | 323 | Password Confirm 324 | 325 | 326 | 327 | Change password 328 | 329 | 330 | 331 | The key is invalid or has been used. 332 | 333 | 334 | 335 | Have you forgotten your password? 336 | 337 | 338 | 339 | If you have forgotten your password we can generate a new one for you. All you need to do is to enter your email address and we will create a new password for you. 340 | 341 | 342 | 343 | Email 344 | 345 | 346 | 347 | Generate new password 348 | 349 | 350 | 351 | %siteurl forgot password 352 | 353 | 354 | 355 | This link is valid until %1, after that time you should generate a new one. 356 | 357 | 358 | 359 | 360 | -------------------------------------------------------------------------------- /translations/por-BR/translation.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | design/admin/content/edit 6 | 7 | View and manage (copy, delete, etc.) the versions of this object. 8 | Ver e gerenciar (copiar, deletar, etc.) as versões deste objeto. 9 | 10 | 11 | Manage versions 12 | Gerenciar versões 13 | 14 | 15 | 16 | design/admin/node/view/full 17 | 18 | Last modified 19 | Última modificação 20 | 21 | 22 | Node ID 23 | ID do nó 24 | 25 | 26 | Object ID 27 | ID do objeto 28 | 29 | 30 | Another language 31 | Outro idioma 32 | 33 | 34 | Edit 35 | Editar 36 | 37 | 38 | Edit the contents of this item. 39 | Editar os conteúdos deste item. 40 | 41 | 42 | Not available 43 | Não disponível 44 | 45 | 46 | You do not have permission to edit this item. 47 | Você não possue permissão para editar este item. 48 | 49 | 50 | Move 51 | Mover 52 | 53 | 54 | Move this item to another location. 55 | Mover este item para outro local. 56 | 57 | 58 | You do not have permission to move this item to another location. 59 | Você não possue permissão para mover este para outro local. 60 | 61 | 62 | Remove 63 | Remover 64 | 65 | 66 | Remove this item. 67 | Remover este item. 68 | 69 | 70 | You do not have permission to remove this item. 71 | Você não possue permissão para remover este item. 72 | 73 | 74 | Preview 75 | Pré-visualizar 76 | 77 | 78 | New translation 79 | Nova tradução 80 | 81 | 82 | 83 | design/admin/pagelayout 84 | 85 | Current user 86 | Usuário atual 87 | 88 | 89 | Change name, email, password, etc. 90 | Mudar nome, email, senha, etc. 91 | 92 | 93 | Change information 94 | Mudar informação 95 | 96 | 97 | Change user info 98 | Mudar informação de usuário 99 | 100 | 101 | Change password for <%username>. 102 | Mudar senha para <%username>. 103 | 104 | 105 | Change password 106 | Mudar senha 107 | 108 | 109 | There is %basket_count item in the shopping basket. 110 | Existe %basket_count item na cesta de compras. 111 | 112 | 113 | Shopping basket (%basket_count) 114 | Cesta de compras (%basket_count) 115 | 116 | 117 | There are %basket_count items in the shopping basket. 118 | Existem %basket_count itens na cesta de compras. 119 | 120 | 121 | Logout from the system. 122 | Sair do sistema. 123 | 124 | 125 | Logout 126 | Sair 127 | 128 | 129 | 130 | design/standard/user/forgotpassword 131 | 132 | Your account information 133 | Informações da sua conta 134 | 135 | 136 | Email 137 | Email 138 | 139 | 140 | 141 | kernel/user 142 | 143 | User 144 | Usuário 145 | 146 | 147 | Forgot password 148 | Esqueci minha senha 149 | 150 | 151 | Change password 152 | Mudar senha 153 | 154 | 155 | 156 | kernel/user/register 157 | 158 | Registration info 159 | Informações do cadastro 160 | 161 | 162 | 163 | mbpaex/classes/datatypes 164 | 165 | Password Expiration 166 | Datatype name 167 | Expiração de senha 168 | 169 | 170 | The password lifetime must be an integer >= 0 171 | O tempo de vida da senha deve ser um número inteiro >= 0 172 | 173 | 174 | The expiration notification time must be an integer >= 86400 175 | O tempo de notificação de expiração da senha deve ser um número inteiro >= 86400 176 | 177 | 178 | The password doesn't match the validation rule. 179 | A senha não coincide com a regra de validação. 180 | 181 | 182 | Wrong value in updatechildren field 183 | Valor incorreto para o campo updatechildren 184 | 185 | 186 | 187 | mbpaex/content/datatype 188 | 189 | Validation Regexp 190 | Regex de Validação 191 | 192 | 193 | Password LifeTime (DAYS) 194 | Tempo de vida da senha (DIAS) 195 | 196 | 197 | Expiration Notification (SECONDS) 198 | Notificação de Expiração (SEGUNDOS) 199 | 200 | 201 | Current password status: 202 | Status atual da senha: 203 | 204 | 205 | expired 206 | expirada 207 | 208 | 209 | active 210 | ativa 211 | 212 | 213 | Update children nodes? 214 | Atualizar nós filhos? 215 | 216 | 217 | undefined 218 | indefinido 219 | 220 | 221 | Password status 222 | Status da senha 223 | 224 | 225 | Children update pending, will be done in a few minutes... 226 | Atualização de nós filhos pendente, será feito em poucos minutos... 227 | 228 | 229 | 230 | mbpaex/userpaex 231 | 232 | Change password for user 233 | Trocar senha de usuario 234 | 235 | 236 | Please retype your old password. 237 | Insira sua senha antiga. 238 | 239 | 240 | Password didn't match, please retype your new password. 241 | As novas senhas não coincidem, por favor redigite as novas senhas. 242 | 243 | 244 | Password didn't validate, please retype your new password. 245 | A senha não é válida, por favor redigite sua nova senha. 246 | 247 | 248 | Password successfully updated. 249 | A senha foi modificada com sucesso. 250 | 251 | 252 | Old password 253 | Senha antiga 254 | 255 | 256 | New password 257 | Nova senha 258 | 259 | 260 | Retype password 261 | Redigite a senha 262 | 263 | 264 | OK 265 | OK 266 | 267 | 268 | Cancel 269 | Cancelar 270 | 271 | 272 | Your password is about to expire 273 | Sua senha está prestes a expirar 274 | 275 | 276 | %siteurl your password is about to expire 277 | %siteurl sua senha está prestes a expirar 278 | 279 | 280 | New password must be different from the old one. Please choose another password. 281 | A nova senha deve ser diferente da antiga. Por favor, escolha outra senha. 282 | 283 | 284 | 285 | mbpaex/userpaex/forgotpassword 286 | 287 | A mail has been sent to the following email address: %1. This email contains a link you need to click so that we can confirm that the correct user is getting the new password. 288 | Um e-mail foi enviado para o endereço de e-mail %1. O e-mail contém um link no qual você deve clicar para confirmar que o usuário correto está recebendo a nova senha. 289 | 290 | 291 | There is no registered user with that email address. 292 | Não existe nenhum usuário registrado com esse endereço de e-mail. 293 | 294 | 295 | The password has been changed successfully. 296 | A senha foi modificada com sucesso. 297 | 298 | 299 | The passwords do not match. Please, be sure to enter the same password in both fields. 300 | As novas senhas não são idênticas. Por favor, confira se as novas senhas são idênticas. 301 | 302 | 303 | The new password is invalid, please choose new one. 304 | A nova senha é inválida, por favor escolha uma nova. 305 | 306 | 307 | Enter your desired new password in the form below. 308 | Informe sua nova senha no formulário a seguir. 309 | 310 | 311 | Password 312 | Senha 313 | 314 | 315 | Password Confirm 316 | Confirmação de senha 317 | 318 | 319 | Change password 320 | Mudar senha 321 | 322 | 323 | The key is invalid or has been used. 324 | A chave é inválida ou já foi utilizada. 325 | 326 | 327 | Have you forgotten your password? 328 | Esqueceu sua senha? 329 | 330 | 331 | If you have forgotten your password we can generate a new one for you. All you need to do is to enter your email address and we will create a new password for you. 332 | Se você esqueceu sua senha, uma nova pode ser gerada. Digite seu endereço de e-mail e uma nova senha será enviada a você. 333 | 334 | 335 | Email 336 | Email 337 | 338 | 339 | Generate new password 340 | Gerar nova senha 341 | 342 | 343 | %siteurl forgot password 344 | %siteurl senha esquecida 345 | 346 | 347 | Click here to set your new password 348 | Clique aqui para definir sua nova senha 349 | 350 | 351 | This link is valid until %1, after that time you should generate a new one. 352 | Este link é válido até %1, após esse prazo você deve gerar um novo. 353 | 354 | 355 | Choose a new password 356 | Escolha uma nova senha 357 | 358 | 359 | 360 | -------------------------------------------------------------------------------- /translations/cro-HR/translation.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | design/admin/content/edit 6 | 7 | View and manage (copy, delete, etc.) the versions of this object. 8 | Pregled i upravljanje (kopiranje, brisanje itd.) verzija ovog objekta. 9 | 10 | 11 | Manage versions 12 | Upravljanje verzijama 13 | 14 | 15 | 16 | design/admin/node/view/full 17 | 18 | Last modified 19 | Promijenjeno 20 | 21 | 22 | Node ID 23 | ID čvora 24 | 25 | 26 | Object ID 27 | ID objekta 28 | 29 | 30 | Another language 31 | Drugi jezik 32 | 33 | 34 | Edit 35 | Uredi 36 | 37 | 38 | Edit the contents of this item. 39 | Uredi sadržaj ove stavke. 40 | 41 | 42 | Not available 43 | Nije dostpuno 44 | 45 | 46 | You do not have permission to edit this item. 47 | Nemate dozvolu za uređivanje ove stavke. 48 | 49 | 50 | Move 51 | Premjesti 52 | 53 | 54 | Move this item to another location. 55 | Premjesti ovu stavku na drugu lokaciju. 56 | 57 | 58 | You do not have permission to move this item to another location. 59 | Nemate dozbolu za premještanje ove stavke na drugu lokaciju. 60 | 61 | 62 | Remove 63 | Ukloni 64 | 65 | 66 | Remove this item. 67 | Ukloni ovu stavku. 68 | 69 | 70 | You do not have permission to remove this item. 71 | Nemate dozvolu za uklanjanje ove stavke. 72 | 73 | 74 | Preview 75 | Pregled 76 | 77 | 78 | New translation 79 | Novi prijevod 80 | 81 | 82 | 83 | design/admin/pagelayout 84 | 85 | Current user 86 | Trenutni korisnik 87 | 88 | 89 | Change name, email, password, etc. 90 | Promijeni ime, email, lozinku itd. 91 | 92 | 93 | Change information 94 | Promijeni informacije 95 | 96 | 97 | Change user info 98 | Promijeni informacije o korisniku 99 | 100 | 101 | Change password for <%username>. 102 | Promijeni lozinku za <%username>. 103 | 104 | 105 | Change password 106 | Promijeni lozinku 107 | 108 | 109 | There is %basket_count item in the shopping basket. 110 | Postoji %basket_count stavki u košarici. 111 | 112 | 113 | Shopping basket (%basket_count) 114 | Košarica (%basket_count) 115 | 116 | 117 | There are %basket_count items in the shopping basket. 118 | Postoji %basket_count stavki u košarici. 119 | 120 | 121 | Logout from the system. 122 | Odjavi se iz sustava. 123 | 124 | 125 | Logout 126 | Odjava 127 | 128 | 129 | 130 | design/standard/user/forgotpassword 131 | 132 | Your account information 133 | Informacije o vašem korisničkom računu 134 | 135 | 136 | Email 137 | Email 138 | 139 | 140 | 141 | kernel/user 142 | 143 | User 144 | Korisnik 145 | 146 | 147 | Forgot password 148 | Zaboravljena lozinka 149 | 150 | 151 | Change password 152 | Promijeni lozinku 153 | 154 | 155 | 156 | kernel/user/register 157 | 158 | Registration info 159 | Informacije o registraciji 160 | 161 | 162 | 163 | mbpaex/classes/datatypes 164 | 165 | Password Expiration 166 | Datatype name 167 | Istjecanje lozinke 168 | 169 | 170 | The password lifetime must be an integer >= 0 171 | Vrijeme valjanosti lozinke mora biti cijeli broj >= 0 172 | 173 | 174 | The expiration notification time must be an integer >= 86400 175 | Vrijeme za obavijest o valjanosti lozinke mora biti cijeli broj >= 86400 176 | 177 | 178 | The password doesn't match the validation rule. 179 | Lozinka ne odgovara pravilima. 180 | 181 | 182 | Wrong value in updatechildren field 183 | Kriva vrijednost u updatechildren polju 184 | 185 | 186 | 187 | mbpaex/content/datatype 188 | 189 | Validation Regexp 190 | Regularni izraz za validaciju 191 | 192 | 193 | Password LifeTime (DAYS) 194 | Valjanost lozinke (U DANIMA) 195 | 196 | 197 | Expiration Notification (SECONDS) 198 | Obavijest o valjanosti (U SEKUNDAMA) 199 | 200 | 201 | Current password status: 202 | Trenutni status lozinke: 203 | 204 | 205 | expired 206 | istekla 207 | 208 | 209 | active 210 | aktivna 211 | 212 | 213 | Update children nodes? 214 | Osvježiti podređene čvorove? 215 | 216 | 217 | undefined 218 | nedefinirano 219 | 220 | 221 | Password status 222 | Status lozinke 223 | 224 | 225 | Children update pending, will be done in a few minutes... 226 | Osvježavanje podređenih čvorova je u tijeku, bit će gotovo za par minuta... 227 | 228 | 229 | 230 | mbpaex/userpaex 231 | 232 | Change password for user 233 | Promijeni lozinku za korisnika 234 | 235 | 236 | Please retype your old password. 237 | Ponovno unesite vašu staru lozinku. 238 | 239 | 240 | Password didn't match, please retype your new password. 241 | Lozinka nije dobro unesena, molimo ponovno unesite vašu novu lozinku. 242 | 243 | 244 | Password didn't validate, please retype your new password. 245 | Lozinka nije validirana, molimo ponovno unesite vašu novu lozinku. 246 | 247 | 248 | New password must be different from the old one. Please choose another password. 249 | Nova lozinka mora biti različita od stare. Odaberite drugu lozinku. 250 | 251 | 252 | Password successfully updated. 253 | Lozinka uspješno promijenjena. 254 | 255 | 256 | Old password 257 | Stara lozinka 258 | 259 | 260 | New password 261 | Nova lozinka 262 | 263 | 264 | Retype password 265 | Ponovno unesite lozinku 266 | 267 | 268 | OK 269 | OK 270 | 271 | 272 | Cancel 273 | Odustani 274 | 275 | 276 | %siteurl your password is about to expire 277 | %siteurl vaša lozinka uskoro ističe 278 | 279 | 280 | Your password is about to expire 281 | Vaša lozinka uskoro ističe 282 | 283 | 284 | 285 | mbpaex/userpaex/forgotpassword 286 | 287 | Click here to set your new password 288 | Kliknite ovdje za postavljanje nove lozinke 289 | 290 | 291 | A mail has been sent to the following email address: %1. This email contains a link you need to click so that we can confirm that the correct user is getting the new password. 292 | Email je poslan na email adresu %1. Email sadrži link na koji trebate kliknuti da možemo potvrditi da ispravan korisnik dobija novu lozinku. 293 | 294 | 295 | There is no registered user with that email address. 296 | Ne postoji korisnik s tom email adresom. 297 | 298 | 299 | The password has been changed successfully. 300 | Lozinka je uspješno promijenjena. 301 | 302 | 303 | The passwords do not match. Please, be sure to enter the same password in both fields. 304 | Lozinke se ne podudaraju. Molimo unesite istu lozinku u oba polja. 305 | 306 | 307 | The new password is invalid, please choose new one. 308 | Nova lozinka je neispravna, molimo odaberite novu. 309 | 310 | 311 | Choose a new password 312 | Odaberite novu lozinku 313 | 314 | 315 | Enter your desired new password in the form below. 316 | Unesite željenu lozinku u donju formu. 317 | 318 | 319 | Password 320 | Lozinka 321 | 322 | 323 | Password Confirm 324 | Potvrda lozinke 325 | 326 | 327 | Change password 328 | Promjena lozinke 329 | 330 | 331 | The key is invalid or has been used. 332 | Ključ je neispravan ili je već iskorišten. 333 | 334 | 335 | Have you forgotten your password? 336 | Jeste li zaboravili vašu lozinku? 337 | 338 | 339 | If you have forgotten your password we can generate a new one for you. All you need to do is to enter your email address and we will create a new password for you. 340 | Ako ste zaboravili vašu lozinku, možemo vam generirati novu. Sve što trebate napraviti je upisati vašu email adresu i kreirat ćemo novu lozinku za vas. 341 | 342 | 343 | Email 344 | Email 345 | 346 | 347 | Generate new password 348 | Generiraj novu lozinku 349 | 350 | 351 | %siteurl forgot password 352 | %siteurl zaboravljena lozinka 353 | 354 | 355 | This link is valid until %1, after that time you should generate a new one. 356 | Ovaj link je ispravan do %1, nakon toga morate generirati novu lozinku. 357 | 358 | 359 | 360 | -------------------------------------------------------------------------------- /translations/esl-ES/translation.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | design/admin/content/edit 6 | 7 | View and manage (copy, delete, etc.) the versions of this object. 8 | 9 | 10 | 11 | Manage versions 12 | 13 | 14 | 15 | 16 | design/admin/node/view/full 17 | 18 | Last modified 19 | 20 | 21 | 22 | Node ID 23 | 24 | 25 | 26 | Object ID 27 | 28 | 29 | 30 | Another language 31 | 32 | 33 | 34 | Edit 35 | 36 | 37 | 38 | Edit the contents of this item. 39 | 40 | 41 | 42 | Not available 43 | 44 | 45 | 46 | Move 47 | 48 | 49 | 50 | Move this item to another location. 51 | 52 | 53 | 54 | Remove 55 | 56 | 57 | 58 | Remove this item. 59 | 60 | 61 | 62 | Preview 63 | 64 | 65 | 66 | You do not have permission to edit this item. 67 | 68 | 69 | 70 | You do not have permission to move this item to another location. 71 | 72 | 73 | 74 | You do not have permission to remove this item. 75 | 76 | 77 | 78 | New translation 79 | 80 | 81 | 82 | 83 | design/admin/pagelayout 84 | 85 | Current user 86 | 87 | 88 | 89 | Change name, email, password, etc. 90 | 91 | 92 | 93 | Change information 94 | 95 | 96 | 97 | Change user info 98 | 99 | 100 | 101 | Change password for <%username>. 102 | 103 | 104 | 105 | Change password 106 | Cambiar contraseña 107 | 108 | 109 | There is %basket_count item in the shopping basket. 110 | 111 | 112 | 113 | Shopping basket (%basket_count) 114 | 115 | 116 | 117 | There are %basket_count items in the shopping basket. 118 | 119 | 120 | 121 | Logout from the system. 122 | 123 | 124 | 125 | Logout 126 | 127 | 128 | 129 | 130 | design/standard/user/forgotpassword 131 | 132 | Email 133 | Correo electrónico 134 | 135 | 136 | Your account information 137 | 138 | 139 | 140 | 141 | kernel/user 142 | 143 | Change password 144 | Cambiar contraseña 145 | 146 | 147 | User 148 | 149 | 150 | 151 | Forgot password 152 | 153 | 154 | 155 | 156 | kernel/user/register 157 | 158 | Registration info 159 | 160 | 161 | 162 | 163 | mbpaex/classes/datatypes 164 | 165 | Password Expiration 166 | Datatype name 167 | Caducidad de Contraseña 168 | 169 | 170 | The password lifetime must be an integer >= 0 171 | El tiempo de vida de la contraseña debe ser un número >= 0 172 | 173 | 174 | The expiration notification time must be an integer >= 86400 175 | El tiempo de notificación de expiración debe ser un número >= 86400 176 | 177 | 178 | The password doesn't match the validation rule. 179 | La contraseña no respeta la regla de validación. 180 | 181 | 182 | Wrong value in updatechildren field 183 | Valor incorrecto en el campo updatechildren 184 | 185 | 186 | 187 | mbpaex/content/datatype 188 | 189 | Validation Regexp 190 | Regexp de Validación 191 | 192 | 193 | Password LifeTime (DAYS) 194 | Caducidad de la Contraseña (DÍAS) 195 | 196 | 197 | Expiration Notification (SECONDS) 198 | Notificación de Expiración (SEGUNDOS) 199 | 200 | 201 | Current password status: 202 | Estado actual de la contraseña: 203 | 204 | 205 | expired 206 | expirada 207 | 208 | 209 | active 210 | activa 211 | 212 | 213 | Update children nodes? 214 | ¿Actualizar nodos hijos? 215 | 216 | 217 | undefined 218 | no definido 219 | 220 | 221 | Password status 222 | Estado de la contraseña 223 | 224 | 225 | Children update pending, will be done in a few minutes... 226 | Actualización de hijos pendiente, será ejecutada en pocos minutos... 227 | 228 | 229 | 230 | mbpaex/userpaex 231 | 232 | Change password for user 233 | Cambio de contraseña de usuario 234 | 235 | 236 | Please retype your old password. 237 | Por favor, reescribe tu contraseña antigua. 238 | 239 | 240 | Password didn't match, please retype your new password. 241 | Las contraseñas no coinciden, por favor reescribe tu nueva contraseña. 242 | 243 | 244 | Password didn't validate, please retype your new password. 245 | La contraseña no supera la validación, por favor reescribe tu nueva contraseña. 246 | 247 | 248 | Password successfully updated. 249 | Contraseña actualizada correctamente. 250 | 251 | 252 | Old password 253 | Contraseña antigua 254 | 255 | 256 | New password 257 | Nueva contraseña 258 | 259 | 260 | Retype password 261 | Reescribe la contraseña 262 | 263 | 264 | OK 265 | OK 266 | 267 | 268 | Cancel 269 | Cancelar 270 | 271 | 272 | Your password is about to expire 273 | Tu contraseña está a punto de caducar 274 | 275 | 276 | %siteurl your password is about to expire 277 | %siteurl tu contraseña está a punto de caducar 278 | 279 | 280 | New password must be different from the old one. Please choose another password. 281 | La nueva contraseña ha de ser diferente de la antigua. Por favor escoge otra contraseña. 282 | 283 | 284 | 285 | mbpaex/userpaex/forgotpassword 286 | 287 | A mail has been sent to the following email address: %1. This email contains a link you need to click so that we can confirm that the correct user is getting the new password. 288 | Un correo electrónico ha sido enviado a la siguiente dirección: %1. Este correo contiene un enlace que debes pulsar para poder cambiar la contraseña. 289 | 290 | 291 | There is no registered user with that email address. 292 | No hay ningún usuario registrado con esa dirección de correo electrónico. 293 | 294 | 295 | The password has been changed successfully. 296 | La contraseña ha sido cambiada correctamente. 297 | 298 | 299 | The passwords do not match. Please, be sure to enter the same password in both fields. 300 | Las contraseñas no coinciden. Por favor, asegúrate que introduces la misma contraseña en ambos campos. 301 | 302 | 303 | The new password is invalid, please choose new one. 304 | La nueva contraseña es inválida, por favor escoge una nueva. 305 | 306 | 307 | Enter your desired new password in the form below. 308 | Introduce tu nueva contraseña en el siguiete formulario. 309 | 310 | 311 | Password 312 | Contraseña 313 | 314 | 315 | Password Confirm 316 | Confirmación de la Contraseña 317 | 318 | 319 | Change password 320 | Cambiar contraseña 321 | 322 | 323 | The key is invalid or has been used. 324 | La clave no es válida o ha sido utilizada. 325 | 326 | 327 | Have you forgotten your password? 328 | ¿Has olvidado tu contraseña? 329 | 330 | 331 | If you have forgotten your password we can generate a new one for you. All you need to do is to enter your email address and we will create a new password for you. 332 | Si has olvidado tu contraseña podemos generar una nueva para ti. Todo lo que necesitas hacer es introducir tu dirección de correo electrónico y nosotros crearemos una contraseña para ti. 333 | 334 | 335 | Email 336 | Correo electrónico 337 | 338 | 339 | Generate new password 340 | Generar nueva contraseña 341 | 342 | 343 | %siteurl forgot password 344 | %siteurl contraseña olvidada 345 | 346 | 347 | Click here to set your new password 348 | Pulsa aquí para fijar tu nueva contraseña 349 | 350 | 351 | This link is valid until %1, after that time you should generate a new one. 352 | Este enlace es válido hasta %1, tras ese tiempo tendrás que generar uno nuevo. 353 | 354 | 355 | Choose a new password 356 | Escoge una nueva contraseña 357 | 358 | 359 | 360 | -------------------------------------------------------------------------------- /translations/ita-IT/translation.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | design/admin/content/edit 6 | 7 | View and manage (copy, delete, etc.) the versions of this object. 8 | Guarda e gestisci (copia, elimina, ecc.) le versioni di quest'oggetto. 9 | 10 | 11 | Manage versions 12 | Gestisci versioni 13 | 14 | 15 | 16 | design/admin/node/view/full 17 | 18 | Last modified 19 | Ultima modifica 20 | 21 | 22 | Node ID 23 | ID nodo 24 | 25 | 26 | Object ID 27 | ID oggetto 28 | 29 | 30 | Another language 31 | Un'altra lingua 32 | 33 | 34 | Edit 35 | Modifica 36 | 37 | 38 | Edit the contents of this item. 39 | Modifica i contenuti di quest'elemento. 40 | 41 | 42 | Not available 43 | Non disponibile 44 | 45 | 46 | You do not have permission to edit this item. 47 | Non sei abilitato a modifcare quest'elemento. 48 | 49 | 50 | Move 51 | Sposta 52 | 53 | 54 | Move this item to another location. 55 | Sposta quest'elemento in un'altra collocazione. 56 | 57 | 58 | You do not have permission to move this item to another location. 59 | Non sei abilitato a spostare quest'elemento in un'altra collocazione. 60 | 61 | 62 | Remove 63 | Elimina 64 | 65 | 66 | Remove this item. 67 | Elimina quest'elemento. 68 | 69 | 70 | You do not have permission to remove this item. 71 | Non sei abilitato ad eliminare quest'elemento. 72 | 73 | 74 | Preview 75 | Anteprima 76 | 77 | 78 | New translation 79 | Nuova traduzione 80 | 81 | 82 | 83 | design/admin/pagelayout 84 | 85 | Current user 86 | Utente attuale 87 | 88 | 89 | Change name, email, password, etc. 90 | Cambia nome, email, password, ecc. 91 | 92 | 93 | Change information 94 | Cambia informazioni 95 | 96 | 97 | Change user info 98 | Cambia info utente 99 | 100 | 101 | Change password for <%username>. 102 | Cambia password per <%username>. 103 | 104 | 105 | Change password 106 | Cambia password 107 | 108 | 109 | There is %basket_count item in the shopping basket. 110 | Vi è %basket_count elemento nel carrello. 111 | 112 | 113 | Shopping basket (%basket_count) 114 | Carrello (%basket_count) 115 | 116 | 117 | There are %basket_count items in the shopping basket. 118 | Vi sono %basket_count elementi nel carrello. 119 | 120 | 121 | Logout from the system. 122 | Logout dal sistema. 123 | 124 | 125 | Logout 126 | Logout 127 | 128 | 129 | 130 | design/standard/user/forgotpassword 131 | 132 | Your account information 133 | Informazioni sul tuo account 134 | 135 | 136 | Email 137 | Email 138 | 139 | 140 | 141 | kernel/user 142 | 143 | User 144 | Utente 145 | 146 | 147 | Forgot password 148 | Password dimenticata 149 | 150 | 151 | Change password 152 | Cambia password 153 | 154 | 155 | 156 | kernel/user/register 157 | 158 | Registration info 159 | Info registrazione 160 | 161 | 162 | 163 | mbpaex/classes/datatypes 164 | 165 | Password Expiration 166 | Datatype name 167 | Scadenza password 168 | 169 | 170 | The password lifetime must be an integer >= 0 171 | La durata della password dev'essere un intero >= 0 172 | 173 | 174 | The expiration notification time must be an integer >= 86400 175 | L'intervallo di tempo di notifica della scadenza dev'essere un intero >= 86400 176 | 177 | 178 | The password doesn't match the validation rule. 179 | La password non coincide con la validazione. 180 | 181 | 182 | Wrong value in updatechildren field 183 | Valore sbagliato nel campo aggiorna figli 184 | 185 | 186 | 187 | mbpaex/content/datatype 188 | 189 | Validation Regexp 190 | Validazione Regexp 191 | 192 | 193 | Password LifeTime (DAYS) 194 | Durata password (GIORNI) 195 | 196 | 197 | Expiration Notification (SECONDS) 198 | Notifica scadenza (SECONDI) 199 | 200 | 201 | Current password status: 202 | Stato password attuale: 203 | 204 | 205 | expired 206 | scaduta 207 | 208 | 209 | active 210 | attiva 211 | 212 | 213 | Update children nodes? 214 | Aggiornare i nodi figli? 215 | 216 | 217 | undefined 218 | indefinito 219 | 220 | 221 | Password status 222 | Stato password 223 | 224 | 225 | Children update pending, will be done in a few minutes... 226 | Aggiornamento figli in attesa, verrà eseguito in pochi minuti... 227 | 228 | 229 | 230 | mbpaex/userpaex 231 | 232 | Change password for user 233 | Cambia la password per l'utente 234 | 235 | 236 | Please retype your old password. 237 | Sei pregato di reinserire la tua vecchia password. 238 | 239 | 240 | Password didn't match, please retype your new password. 241 | Le password non coincidono, sei pregato di reinserire la tua nuova password. 242 | 243 | 244 | Password didn't validate, please retype your new password. 245 | La password non è valida, sei pregato di reinserire la tua nuova password. 246 | 247 | 248 | New password must be different from the old one. Please choose another password. 249 | La nuova password dev'essere diversa dalla vecchia. Sei pregato di scegliere un'altra password. 250 | 251 | 252 | Password successfully updated. 253 | Aggiornamento password riuscito. 254 | 255 | 256 | Old password 257 | Vecchia password 258 | 259 | 260 | New password 261 | Nuova password 262 | 263 | 264 | Retype password 265 | Reinserisci la password 266 | 267 | 268 | OK 269 | OK 270 | 271 | 272 | Cancel 273 | Annulla 274 | 275 | 276 | %siteurl your password is about to expire 277 | %siteurl la tua password sta per scadere 278 | 279 | 280 | Your password is about to expire 281 | La tua password sta per scadere 282 | 283 | 284 | 285 | mbpaex/userpaex/forgotpassword 286 | 287 | Click here to set your new password 288 | Clicca qui per impostare la tua nuova password 289 | 290 | 291 | A mail has been sent to the following email address: %1. This email contains a link you need to click so that we can confirm that the correct user is getting the new password. 292 | E' stata inviata un'email al seguente indirizzo email: %1. Quest'email contiene un link che devi cliccare per darci la conferma che l'utente giusto ha ricevuto la nuova password. 293 | 294 | 295 | There is no registered user with that email address. 296 | Non esiste alcun utente registrato con quest'indirizzo email. 297 | 298 | 299 | The password has been changed successfully. 300 | Modifica password riuscita. 301 | 302 | 303 | The passwords do not match. Please, be sure to enter the same password in both fields. 304 | Le password non coincidono. Sei pregato di verificare di aver inserito la stessa password in entrambi i campi. 305 | 306 | 307 | The new password is invalid, please choose new one. 308 | La nuova password non è valida, sei pregato di sceglierne un'altra. 309 | 310 | 311 | Choose a new password 312 | Scegli una nuova password 313 | 314 | 315 | Enter your desired new password in the form below. 316 | Inserisci la nuova password scelta nel campo sottostante. 317 | 318 | 319 | Password 320 | Password 321 | 322 | 323 | Password Confirm 324 | Conferma password 325 | 326 | 327 | Change password 328 | Cambia password 329 | 330 | 331 | The key is invalid or has been used. 332 | La chiave non è valida o è stata usata. 333 | 334 | 335 | Have you forgotten your password? 336 | Hai dimenticato la tua password? 337 | 338 | 339 | If you have forgotten your password we can generate a new one for you. All you need to do is to enter your email address and we will create a new password for you. 340 | Se hai dimenticato la tua password possiamo generartene un'altra. Devi solo inserire il tuo indirizzo email e noi ti creeremo una nuova password. 341 | 342 | 343 | Email 344 | Email 345 | 346 | 347 | Generate new password 348 | Genera una nuova password 349 | 350 | 351 | %siteurl forgot password 352 | %siteurl password dimenticata 353 | 354 | 355 | This link is valid until %1, after that time you should generate a new one. 356 | Questo link è valido fino a %1, dopo questo termine dovrai generarne un'altra. 357 | 358 | 359 | 360 | -------------------------------------------------------------------------------- /translations/cat-ES/translation.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | design/admin/content/edit 6 | 7 | View and manage (copy, delete, etc.) the versions of this object. 8 | 9 | 10 | 11 | Manage versions 12 | 13 | 14 | 15 | 16 | design/admin/node/view/full 17 | 18 | Last modified 19 | 20 | 21 | 22 | Node ID 23 | 24 | 25 | 26 | Object ID 27 | 28 | 29 | 30 | Another language 31 | 32 | 33 | 34 | Edit 35 | 36 | 37 | 38 | Edit the contents of this item. 39 | 40 | 41 | 42 | Not available 43 | 44 | 45 | 46 | Move 47 | 48 | 49 | 50 | Move this item to another location. 51 | 52 | 53 | 54 | Remove 55 | 56 | 57 | 58 | Remove this item. 59 | 60 | 61 | 62 | Preview 63 | 64 | 65 | 66 | You do not have permission to edit this item. 67 | 68 | 69 | 70 | You do not have permission to move this item to another location. 71 | 72 | 73 | 74 | You do not have permission to remove this item. 75 | 76 | 77 | 78 | New translation 79 | 80 | 81 | 82 | 83 | design/admin/pagelayout 84 | 85 | Current user 86 | 87 | 88 | 89 | Change name, email, password, etc. 90 | 91 | 92 | 93 | Change information 94 | 95 | 96 | 97 | Change user info 98 | 99 | 100 | 101 | Change password for <%username>. 102 | 103 | 104 | 105 | Change password 106 | Canviar contrasenya 107 | 108 | 109 | There is %basket_count item in the shopping basket. 110 | 111 | 112 | 113 | Shopping basket (%basket_count) 114 | 115 | 116 | 117 | There are %basket_count items in the shopping basket. 118 | 119 | 120 | 121 | Logout from the system. 122 | 123 | 124 | 125 | Logout 126 | 127 | 128 | 129 | 130 | design/standard/user/forgotpassword 131 | 132 | Email 133 | Correu electrònic 134 | 135 | 136 | Your account information 137 | 138 | 139 | 140 | 141 | kernel/user 142 | 143 | Change password 144 | Canviar contrasenya 145 | 146 | 147 | User 148 | 149 | 150 | 151 | Forgot password 152 | 153 | 154 | 155 | 156 | kernel/user/register 157 | 158 | Registration info 159 | 160 | 161 | 162 | 163 | mbpaex/classes/datatypes 164 | 165 | Password Expiration 166 | Datatype name 167 | Caducitat de Contrasenya 168 | 169 | 170 | The password lifetime must be an integer >= 0 171 | El temps de vida de la contrasenya ha de ser un nombre >= 0 172 | 173 | 174 | The expiration notification time must be an integer >= 86400 175 | El temps de notificació d'expiració ha de ser un nombre >= 86400 176 | 177 | 178 | The password doesn't match the validation rule. 179 | La contrasenya no cumpleix la regla de validació. 180 | 181 | 182 | Wrong value in updatechildren field 183 | Valor incorrecte al camp updatechildren 184 | 185 | 186 | 187 | mbpaex/content/datatype 188 | 189 | Validation Regexp 190 | Regexp de validació 191 | 192 | 193 | Password LifeTime (DAYS) 194 | Caducitat de la contrasenya (DIES) 195 | 196 | 197 | Expiration Notification (SECONDS) 198 | Notificació d'expiració (SEGONS) 199 | 200 | 201 | Current password status: 202 | Estat actual de la contrasenya: 203 | 204 | 205 | expired 206 | caducada 207 | 208 | 209 | active 210 | activa 211 | 212 | 213 | Update children nodes? 214 | Actualitzar fills del node? 215 | 216 | 217 | undefined 218 | no definit 219 | 220 | 221 | Password status 222 | Estat de la contrasenya 223 | 224 | 225 | Children update pending, will be done in a few minutes... 226 | Actualització dels fills pendents, serà realitzada en pocs minuts... 227 | 228 | 229 | 230 | mbpaex/userpaex 231 | 232 | Change password for user 233 | Canvia la contrasenya del usuari 234 | 235 | 236 | Please retype your old password. 237 | Si-us-plau reescriu la contrasenya antiga. 238 | 239 | 240 | Password didn't match, please retype your new password. 241 | Les contrasenyes no coincideixen, si-us-plau reescriu la teva nova contrasenya. 242 | 243 | 244 | Password didn't validate, please retype your new password. 245 | La contrasenya no supera la validació, si-us-plau reescriu la nova contrasenya. 246 | 247 | 248 | Password successfully updated. 249 | Contrasenya actualitzada correctament. 250 | 251 | 252 | Old password 253 | Contrasenya antiga 254 | 255 | 256 | New password 257 | Nova contrasenya 258 | 259 | 260 | Retype password 261 | Reescriu la contrasenya 262 | 263 | 264 | OK 265 | D'acord 266 | 267 | 268 | Cancel 269 | Cancel·lar 270 | 271 | 272 | Your password is about to expire 273 | La teva contrasenya és a punt de caducar 274 | 275 | 276 | %siteurl your password is about to expire 277 | %siteurl la teva contrasenya és a punt de caducar 278 | 279 | 280 | New password must be different from the old one. Please choose another password. 281 | La nova contrasenya ha de ser diferent de l'antiga. Si-us-plau tria una altra contrasenya. 282 | 283 | 284 | 285 | mbpaex/userpaex/forgotpassword 286 | 287 | A mail has been sent to the following email address: %1. This email contains a link you need to click so that we can confirm that the correct user is getting the new password. 288 | S'ha enviat un correu electrònic a la següent adreça: %1. Aquest correu conté un enllaç amb el que accediràs al formulari per fixar una nova contrasenya. 289 | 290 | 291 | There is no registered user with that email address. 292 | No hi ha cap usuari registrat amb aquesta adreça de correu electrònic. 293 | 294 | 295 | The password has been changed successfully. 296 | La contrasenya s'ha canviat correctament. 297 | 298 | 299 | The passwords do not match. Please, be sure to enter the same password in both fields. 300 | Les contrasenyes no coincideixen. Si-us-plau, assegura't d'introduir la mateixa contrasenya als dos camps. 301 | 302 | 303 | The new password is invalid, please choose new one. 304 | La nova contrasenya no és vàlida, si-us-plau tria una de nova. 305 | 306 | 307 | Enter your desired new password in the form below. 308 | Introdueix la nova contrasenya al següent formulari. 309 | 310 | 311 | Password 312 | Contrasenya 313 | 314 | 315 | Password Confirm 316 | Confirmar Contrasenya 317 | 318 | 319 | Change password 320 | Canviar contrasenya 321 | 322 | 323 | The key is invalid or has been used. 324 | La clau no és vàlida o ha estat utilitzada. 325 | 326 | 327 | Have you forgotten your password? 328 | Has oblidat la teva contrasenya? 329 | 330 | 331 | If you have forgotten your password we can generate a new one for you. All you need to do is to enter your email address and we will create a new password for you. 332 | Si has oblidat la teva contrasenya nosaltres podem generar una de nova per tu. Tot el que necessites és introduir la teva adreça de correu electrònic i crearem una nova contrasenya per tu. 333 | 334 | 335 | Email 336 | Correu electrònic 337 | 338 | 339 | Generate new password 340 | Generar contrasenya 341 | 342 | 343 | %siteurl forgot password 344 | %siteurl contrasenya oblidada 345 | 346 | 347 | Click here to set your new password 348 | Fes clic aqui per fixar la teva nova contrasenya 349 | 350 | 351 | This link is valid until %1, after that time you should generate a new one. 352 | Aquest enllaç és vàlid fins %1, després d'aquest temps hauràs de generar un de nou. 353 | 354 | 355 | Choose a new password 356 | Tria una nova contrasenya 357 | 358 | 359 | 360 | -------------------------------------------------------------------------------- /translations/fre-FR/translation.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | design/admin/content/edit 6 | 7 | View and manage (copy, delete, etc.) the versions of this object. 8 | Afficher et gérer (copier, supprimer, etc.) les versions de cet objet. 9 | 10 | 11 | Manage versions 12 | Gérer les versions 13 | 14 | 15 | 16 | design/admin/node/view/full 17 | 18 | Last modified 19 | Dernière modification 20 | 21 | 22 | Node ID 23 | ID du nœud 24 | 25 | 26 | Object ID 27 | ID de l'objet 28 | 29 | 30 | Another language 31 | Autre langue 32 | 33 | 34 | Edit 35 | Modifier 36 | 37 | 38 | Edit the contents of this item. 39 | Modifier le contenu de cet éléments. 40 | 41 | 42 | Not available 43 | Non disponible 44 | 45 | 46 | Move 47 | Déplacer 48 | 49 | 50 | Move this item to another location. 51 | Déplacer cet élément vers un autre emplacement. 52 | 53 | 54 | Remove 55 | Supprimer 56 | 57 | 58 | Remove this item. 59 | Supprimer cet élément. 60 | 61 | 62 | Preview 63 | Prévisualisation 64 | 65 | 66 | You do not have permission to edit this item. 67 | Vous n'avez pas le droit de modifier cet élément. 68 | 69 | 70 | You do not have permission to move this item to another location. 71 | Vous n'avez pas le droit de déplacer cet élément vers un autre emplacement. 72 | 73 | 74 | You do not have permission to remove this item. 75 | Vous n'avez pas le droit de supprimer cet élément. 76 | 77 | 78 | New translation 79 | Nouvelle traduction 80 | 81 | 82 | 83 | design/admin/pagelayout 84 | 85 | Current user 86 | Utilisateur identifié 87 | 88 | 89 | Change name, email, password, etc. 90 | Modifier le nom, l'adresse courriel, le mot de passe, etc. 91 | 92 | 93 | Change information 94 | Modifier les informations 95 | 96 | 97 | Change user info 98 | Modifier les informations personnelles 99 | 100 | 101 | Change password for <%username>. 102 | Changer le mot de passe de <%username>. 103 | 104 | 105 | Change password 106 | Modifier le mot de passe 107 | 108 | 109 | There is %basket_count item in the shopping basket. 110 | Le panier comporte %basket_count éléments. 111 | 112 | 113 | Shopping basket (%basket_count) 114 | Panier (%basket_count) 115 | 116 | 117 | There are %basket_count items in the shopping basket. 118 | Le panier comporte %basket_count éléments. 119 | 120 | 121 | Logout from the system. 122 | Quitter. 123 | 124 | 125 | Logout 126 | Fermeture de session 127 | 128 | 129 | 130 | design/standard/user/forgotpassword 131 | 132 | Email 133 | Courriel 134 | 135 | 136 | Your account information 137 | Les informations sur votre compte 138 | 139 | 140 | 141 | kernel/user 142 | 143 | User 144 | Utilisateur 145 | 146 | 147 | Change password 148 | Modifier mon mot de passe 149 | 150 | 151 | Forgot password 152 | Mot de passe oublié 153 | 154 | 155 | 156 | kernel/user/register 157 | 158 | Registration info 159 | Informations d'inscription 160 | 161 | 162 | 163 | mbpaex/classes/datatypes 164 | 165 | Password Expiration 166 | Datatype name 167 | Expiration de mot de passe 168 | 169 | 170 | The password lifetime must be an integer >= 0 171 | La durée de vie du mot de passe doit être un entier >= 0 172 | 173 | 174 | The expiration notification time must be an integer >= 86400 175 | Le délai de notification d'expiration doit être un entier >= 86400 176 | 177 | 178 | The password doesn't match the validation rule. 179 | Le mot de passe ne respecte pas la règle de validation. 180 | 181 | 182 | Wrong value in updatechildren field 183 | Valeur incorrecte dans le champ updatechildren 184 | 185 | 186 | 187 | mbpaex/content/datatype 188 | 189 | Validation Regexp 190 | Expression régulière de validation 191 | 192 | 193 | Password LifeTime (DAYS) 194 | Durée de vie du mot de passe ( JOURS ) 195 | 196 | 197 | Expiration Notification (SECONDS) 198 | Délai de notification d'expiration ( SECONDES ) 199 | 200 | 201 | Current password status: 202 | Satut actuel du mot de passe: 203 | 204 | 205 | expired 206 | expiré 207 | 208 | 209 | active 210 | actif 211 | 212 | 213 | Update children nodes? 214 | Mettre à jour les nœuds enfants ? 215 | 216 | 217 | undefined 218 | indéfini 219 | 220 | 221 | Password status 222 | Statut du mot de passe 223 | 224 | 225 | Children update pending, will be done in a few minutes... 226 | Mise à jour des nœuds enfants en attente, sera effectuée dans quelques minutes... 227 | 228 | 229 | 230 | mbpaex/userpaex 231 | 232 | Change password for user 233 | Changement de mot de passe pour l'utilisateur 234 | 235 | 236 | Please retype your old password. 237 | Entrez à nouveau votre ancien mot de passe. 238 | 239 | 240 | Password didn't match, please retype your new password. 241 | Les mots de passe saisis ne coïncident pas, veuillez entrer à nouveau votre nouveau mot de passe. 242 | 243 | 244 | Password didn't validate, please retype your new password. 245 | Le mot de passe n'a pas pu être validé, veuillez entrer à nouveau votre nouveau mot de passe. 246 | 247 | 248 | Password successfully updated. 249 | Mot de passe correctement mis à jour. 250 | 251 | 252 | Old password 253 | Ancien mot de passe 254 | 255 | 256 | New password 257 | Nouveau mot de passe 258 | 259 | 260 | Retype password 261 | Saisir le mot de passe à nouveau 262 | 263 | 264 | OK 265 | OK 266 | 267 | 268 | Cancel 269 | Annuler 270 | 271 | 272 | Your password is about to expire 273 | Votre mot de passe va bientôt expirer 274 | 275 | 276 | %siteurl your password is about to expire 277 | %siteurl votre mot de passe va bientôt expirer 278 | 279 | 280 | New password must be different from the old one. Please choose another password. 281 | Le nouveau mot de passe doit être différent de l'ancien. Veuillez choisir un autre mot de passe. 282 | 283 | 284 | 285 | mbpaex/userpaex/forgotpassword 286 | 287 | A mail has been sent to the following email address: %1. This email contains a link you need to click so that we can confirm that the correct user is getting the new password. 288 | Un courrier électronique a été envoyé à l'adresse suivante: %1. Ce courrier contient un lien sur lequel vous devez cliquer pour confirmer que le bon utilisateur reçoit le nouveau mot de passe. 289 | 290 | 291 | There is no registered user with that email address. 292 | Aucun utilisateur enregistré sous cette adresse électronique. 293 | 294 | 295 | The password has been changed successfully. 296 | Le mot de passe a été modifié avec succès. 297 | 298 | 299 | The passwords do not match. Please, be sure to enter the same password in both fields. 300 | Les mots de passe ne coïncident pas. Assurez-vous de saisir le même mot de passe dans les deux champs. 301 | 302 | 303 | The new password is invalid, please choose new one. 304 | Le nouveau mot de passe est invalide, veuillez en choisir un autre. 305 | 306 | 307 | Enter your desired new password in the form below. 308 | Saisissez votre nouveau mot de passe dans le formulaire ci-dessous. 309 | 310 | 311 | Password 312 | Mot de passe 313 | 314 | 315 | Password Confirm 316 | Confirmation du mot de passe 317 | 318 | 319 | Change password 320 | Changer de mot de passe 321 | 322 | 323 | The key is invalid or has been used. 324 | La clé est invalide ou a été utilisée. 325 | 326 | 327 | Have you forgotten your password? 328 | Vous avez oublié votre mot de passe? 329 | 330 | 331 | If you have forgotten your password we can generate a new one for you. All you need to do is to enter your email address and we will create a new password for you. 332 | Nous pouvons vous générer un nouveau mot de passe si vous l'avez oublié. Il vous suffit de saisir votre adresse email ci-dessous, et nous nous chargerons de vous créer un nouveau mot de passe. 333 | 334 | 335 | Email 336 | Adresse électronique 337 | 338 | 339 | Generate new password 340 | Générer le nouveau mot de passe 341 | 342 | 343 | %siteurl forgot password 344 | %siteurl mot de passe oublié 345 | 346 | 347 | Click here to set your new password 348 | Cliquer ici pour saisir un nouveau mot de passe 349 | 350 | 351 | This link is valid until %1, after that time you should generate a new one. 352 | Ce lien est valide jusqu'à %1, après quoi vous devrez en générer un nouveau. 353 | 354 | 355 | Choose a new password 356 | Choisissez un nouveau mot de passe 357 | 358 | 359 | 360 | -------------------------------------------------------------------------------- /tests/classes/ezpaex_test.php: -------------------------------------------------------------------------------- 1 | setName( "eZ Password Expiry Unit Tests" ); 20 | }*/ 21 | 22 | /** 23 | * setUp(): 24 | * - creates a PAEX object for the admin user 25 | **/ 26 | public function setUp() 27 | { 28 | parent::setUp(); 29 | 30 | $this->paexTime = time(); 31 | 32 | $row = array( 'contentobject_id' => 14, 33 | 'passwordvalidationregexp' => '', 34 | 'passwordlifetime' => 3, 35 | 'expirationnotification' => eZPaEx::NOT_DEFINED, 36 | 'password_last_updated' => $this->paexTime, 37 | 'updatechildren' => 0, 38 | 'expirationnotification_sent' => 0 ); 39 | $this->paex = new eZPaEx( $row ); 40 | 41 | $this->paexINI = eZINI::instance( 'mbpaex.ini' ); 42 | } 43 | 44 | /** 45 | * tearDown(): 46 | * - deletes the admin PAEX object if it still exists 47 | **/ 48 | public function tearDown() 49 | { 50 | parent::tearDown(); 51 | 52 | // remove the PAEX object if it hasn't been removed by the test 53 | if ( eZPaEx::fetch( $this->paex->attribute( 'contentobject_id' ) ) ) 54 | eZPaEx::removePaex( $this->paex->attribute( 'contentobject_id' ) ); 55 | } 56 | 57 | /** 58 | * Unit test for eZPaEx::__construct() 59 | **/ 60 | public function testeZPaEx() 61 | { 62 | $this->assertInstanceOf( 'eZPaEx', $this->paex ); 63 | 64 | $this->assertEquals( 14, $this->paex->attribute( 'contentobject_id' ) ); 65 | $this->assertEquals( '', $this->paex->attribute( 'passwordvalidationregexp' ) ); 66 | $this->assertEquals( 3, $this->paex->attribute( 'passwordlifetime' ) ); 67 | $this->assertEquals( eZPaEx::NOT_DEFINED, $this->paex->attribute( 'expirationnotification' ) ); 68 | $this->assertEquals( $this->paexTime, $this->paex->attribute( 'password_last_updated' ) ); 69 | $this->assertEquals( 0, $this->paex->attribute( 'updatechildren' ) ); 70 | $this->assertEquals( 0, $this->paex->attribute( 'expirationnotification_sent' ) ); 71 | } 72 | 73 | /** 74 | * Unit test for eZPaEx::create() 75 | **/ 76 | public function testCreate() 77 | { 78 | // Create a user instance 79 | $user = self::createUser( __FUNCTION__ ); 80 | 81 | // Create a paex instanced based on this user's content object ID 82 | $paex = eZPaEx::create( $user->attribute( 'contentobject_id' ) ); 83 | $this->assertInstanceOf( 'eZPaEx', $paex ); 84 | $this->assertEquals( $this->paexINI->variable( 'mbpaexSettings', 'PasswordValidationRegexp' ), 85 | $paex->attribute( 'passwordvalidationregexp' ), 86 | "Password validation regexp value doesn't match" ); 87 | $this->assertEquals( $this->paexINI->variable( 'mbpaexSettings', 'DefaultPasswordLifeTime' ), 88 | $paex->attribute( 'passwordlifetime' ), 89 | "Password lifetime value doesn't match" ); 90 | $this->assertEquals( $this->paexINI->variable( 'mbpaexSettings', 'ExpirationNotification' ), 91 | $paex->attribute( 'expirationnotification' ), 92 | "Password expiration notification value doesn't match" ); 93 | $this->assertEquals( $user->attribute( 'contentobject_id' ), 94 | $paex->attribute( 'contentobject_id' ), 95 | "Paex contentobject ID doesn't match" ); 96 | } 97 | 98 | /** 99 | * Unit test for eZPaEx::setInformation() 100 | **/ 101 | public function testSetInformation() 102 | { 103 | $user = self::createUser( __FUNCTION__ ); 104 | 105 | $paex = new eZPaEx( array() ); 106 | $paex->setInformation( 107 | $contentObjectID = $user->attribute( 'id' ), 108 | $regexp = '', 109 | $passwordLifetime = 10, 110 | $expirationNotification = eZPaEx::NOT_DEFINED, 111 | $time = time(), 112 | $updateChildren = 0, 113 | $expirationNotificationSent = 1 ); 114 | 115 | $this->assertEquals( $contentObjectID, $paex->attribute( 'contentobject_id' ), 116 | "attribute contentobject_id doesn't match" ); 117 | $this->assertEquals( $regexp, $paex->attribute( 'passwordvalidationregexp' ), 118 | "attribute passwordvalidationregexp doesn't match" ); 119 | $this->assertEquals( $passwordLifetime, $paex->attribute( 'passwordlifetime' ), 120 | "attribute passwordlifetime doesn't match" ); 121 | $this->assertEquals( $expirationNotification, $paex->attribute( 'expirationnotification' ), 122 | "attribute expirationnotification doesn't match" ); 123 | $this->assertEquals( $time, $paex->attribute( 'password_last_updated' ), 124 | "attribute password_last_updated doesn't match" ); 125 | $this->assertEquals( $updateChildren, $paex->attribute( 'updatechildren' ), 126 | "attribute updatechildren doesn't match" ); 127 | $this->assertEquals( $expirationNotificationSent, $paex->attribute( 'expirationnotification_sent' ), 128 | "attribute expirationnotification_sent doesn't match" ); 129 | } 130 | 131 | /** 132 | * Unit test for eZPaEx::store() 133 | **/ 134 | public function testStore() 135 | { 136 | $user = self::createUser( __FUNCTION__ ); 137 | $contentObjectID = $user->attribute( 'id' ); 138 | $paex = eZPaEx::create( $contentObjectID ); 139 | 140 | // First try fetching the object from the database 141 | // @expected null 142 | $this->assertNull( eZPaEx::fetch( $contentObjectID ), 143 | "PaEx #$contentObjectID hasn't been stored yet, fetch() should have returned null" ); 144 | 145 | // store, and try to fetch again 146 | $paex->store(); 147 | $fetchedPaex = eZPaEx::fetch( $contentObjectID ); 148 | $this->assertInstanceOf( 'eZPaEx', $fetchedPaex, 149 | "PaEx #$contentObjectID has been stored, fetch() should have returned the object" ); 150 | } 151 | 152 | /** 153 | * Unit test for eZPaEx::removePaex() 154 | **/ 155 | public function testRemovePaex() 156 | { 157 | $user = self::createUser( __FUNCTION__ ); 158 | $paex = eZPaEx::create( $user->attribute( 'id' ) ); 159 | $paex->store(); 160 | 161 | $id = $paex->attribute( 'contentobject_id' ); 162 | unset( $paex ); 163 | 164 | // fetch again to be sure it is stored 165 | $this->assertInstanceOf( 'eZPaEx', eZPaEx::fetch( $id ), 166 | "eZPaEx::fetch() should have returned an object" ); 167 | 168 | // remove, and check if fetch fails as expected 169 | eZPaEx::removePaex( $id ); 170 | $this->assertEquals( null, eZPaEx::fetch( $id ), 171 | "eZPaEx::fetch() should have returned null as the object should no longer exist" ); 172 | } 173 | 174 | /** 175 | * Unit test for eZPaEx::fetch() 176 | **/ 177 | public function testFetch() 178 | { 179 | // Create a user 180 | $user = self::createUser( __FUNCTION__ ); 181 | $contentObjectID = $user->attribute( 'id' ); 182 | 183 | // Try fetching this user's ID. Should fail. 184 | $this->assertNull( eZPaEx::fetch( $contentObjectID ), 185 | "eZPaEx::fetch() should be null as the object hasn't been created yet" ); 186 | 187 | // Create & store the PaEx 188 | eZPaEx::create( $contentObjectID )->store(); 189 | 190 | // Try fetching it again 191 | $this->assertInstanceOf( 'eZPaEx', eZPaEx::fetch( $contentObjectID ) ); 192 | } 193 | 194 | /** 195 | * Unit test for eZPaEx::isExpired 196 | * 197 | * @param int $passwordLifetime 198 | * @param int $passwordLastUpdated 199 | * @param bool $expected 200 | * 201 | * @dataProvider providerForTestIsExpired 202 | **/ 203 | public function testIsExpired( $passwordLifetime, $passwordLastUpdated, $expected ) 204 | { 205 | $this->paex->setAttribute( 'passwordlifetime', $passwordLifetime ); 206 | $this->paex->setAttribute( 'password_last_updated', $passwordLastUpdated ); 207 | 208 | $this->assertEquals( $expected, $this->paex->isExpired() ); 209 | } 210 | 211 | /** 212 | * Unit test for eZPaEx::isUser() 213 | */ 214 | public function testIsUser() 215 | { 216 | $this->assertTrue( $this->paex->isUser(), "PaEx object should have been a user" ); 217 | 218 | $paex = new eZPaEx( array() ); 219 | $this->assertFalse( $paex->isUser(), "PaEx object shouldn't have been a user" ); 220 | } 221 | 222 | /** 223 | * Unit test for eZPaEx::hasRegexp 224 | */ 225 | function testHasRegexp() 226 | { 227 | // No regexp on the default object 228 | $this->assertFalse( $this->paex->hasRegexp(), "PaEx object shouldn't have a regexp" ); 229 | 230 | // Set a regexp and test again 231 | $this->paex->setAttribute( 'passwordvalidationregexp', '/^[a-z0-9]$/' ); 232 | $this->assertTrue( $this->paex->hasRegexp(), "PaEx object should have a regexp" ); 233 | } 234 | 235 | /** 236 | * Unit test for eZPaEx::hasLifeTime() 237 | */ 238 | function testHasLifeTime() 239 | { 240 | $this->assertTrue( $this->paex->hasLifeTime(), "PaEx object should have a lifetime" ); 241 | 242 | // Set lifetime to an empty value 243 | $this->paex->setAttribute( 'passwordlifetime', '' ); 244 | $this->assertFalse( $this->paex->hasLifeTime(), "PaEx object shouldn't have a lifetime (empty string)" ); 245 | 246 | // Set lifetime to the NOT_DEFINED constant 247 | $this->paex->setAttribute( 'passwordlifetime', eZPaEx::NOT_DEFINED ); 248 | $this->assertFalse( $this->paex->hasLifeTime(), "PaEx object shouldn't have a lifetime (eZPaEx::NOT_DEFINED)" ); 249 | } 250 | 251 | /** 252 | * Unit test for eZPaEx::hasNotification() 253 | */ 254 | function testHasNotification() 255 | { 256 | // default object has expirationnotification set to eZPaEx::NOT_DEFINED 257 | $this->assertFalse( $this->paex->hasNotification(), "PaEx object should not have a lifetime" ); 258 | 259 | // check with null 260 | $this->paex->setAttribute( 'expirationnotification', null ); 261 | $this->assertFalse( $this->paex->hasNotification(), "PaEx object should not have a lifetime" ); 262 | 263 | // check with empty string 264 | $this->paex->setAttribute( 'expirationnotification', '' ); 265 | $this->assertFalse( $this->paex->hasNotification(), "PaEx object should not have a lifetime" ); 266 | 267 | // check with an actual value 268 | $this->paex->setAttribute( 'expirationnotification', 172800 ); 269 | $this->assertTrue( $this->paex->hasNotification(), "PaEx object should have a lifetime" ); 270 | } 271 | 272 | /** 273 | * Unit test for eZPaEx::validatePassword() 274 | * 275 | * @dataProvider providerForTestValidatePassword 276 | */ 277 | function testValidatePassword( $regexp, $expected, $password = 'publish' ) 278 | { 279 | // The default object has an empty regexp, will always be valid 280 | $this->paex->setAttribute( 'passwordvalidationregexp', $regexp ); 281 | if ( $expected === true ) 282 | { 283 | $this->assertTrue( $this->paex->validatePassword( $password ) ); 284 | } 285 | elseif ( $expected === false ) 286 | { 287 | $this->assertFalse( $this->paex->validatePassword( $password ) ); 288 | } 289 | else 290 | { 291 | $this->markTestSkipped( "Unknown value for \$expected" ); 292 | } 293 | } 294 | 295 | /** 296 | * Data provider for testValidatePassword() 297 | * 298 | * @see eZPaExTest::testValidatePassword() 299 | */ 300 | public static function providerForTestValidatePassword() 301 | { 302 | return array( 303 | // empty values 304 | array( '', true ), 305 | array( null, true ), 306 | array( eZPaEx::NOT_DEFINED, true ), 307 | 308 | // test different regexp forms 309 | array( '^[0-9a-z]+$', true ), 310 | array( '/^[0-9a-z]+$/', true), 311 | 312 | // a few rejected passwords 313 | array( '^[0-9a-z]+$', false, 'my_password' ), 314 | array( '^[0-9]+$', false, '#@~&' ) 315 | ); 316 | } 317 | 318 | /** 319 | * dataProvider for testIsExpired() 320 | **/ 321 | public static function providerForTestIsExpired() 322 | { 323 | return array( 324 | // undefined password lifetime 325 | array( eZPaEx::NOT_DEFINED, time(), false ), 326 | array( -1, time(), false ), 327 | // defined password lifetime, never updated 328 | array( 15, 0, true ), 329 | // defined password lifetime, updated less than lifetime days ago 330 | array( 15, strtotime( 'now - 3 days' ), false ), 331 | // defined password lifetime, updated more than lifetime days ago 332 | array( 15, strtotime( 'now - 20 days' ), true ), 333 | ); 334 | } 335 | 336 | /** 337 | * Helper method that creates a new user. 338 | * Currently only creates in users/guest_accounts. 339 | * First and last name will be a splitup of username 340 | * 341 | * @param string $username 342 | * @param string $password If not provided, uses the username as password 343 | * @param string $email If not provided, uses 'test.ez.no' 344 | * 345 | * @return eZContentObject 346 | */ 347 | protected static function createUser( $username, $password = false, $email = false ) 348 | { 349 | $firstname = substr( $username, 0, floor( strlen( $username ) / 2 ) ); 350 | $lastname = substr( $username, ceil( strlen( $username ) / 2 ) ); 351 | 352 | if ( $email === false ) 353 | $email = "$username@test.ez.no"; 354 | if ( $password === false ) 355 | $password = $username; 356 | 357 | $user = new ezpObject( 'user', eZContentObjectTreeNode::fetchByPath( 'users/guest_accounts' ) ); 358 | $user->first_name = $firstname; 359 | $user->last_name = $lastname; 360 | $user->user_account = $account = sprintf( '%s|%s|%s|%d', 361 | $username, $email, 362 | eZUser::createHash( $username, $password, eZUser::site(), eZUser::PASSWORD_HASH_MD5_USER ), 363 | eZUser::PASSWORD_HASH_MD5_USER ); 364 | $user->publish(); 365 | $user->refresh(); 366 | 367 | return $user->object; 368 | } 369 | 370 | /** 371 | * PaEx creation time 372 | * @var int 373 | **/ 374 | protected $paexTime; 375 | 376 | /** 377 | * PaEx test instance 378 | * @var eZPaEx 379 | **/ 380 | protected $paex; 381 | 382 | /** 383 | * @var eZINI 384 | **/ 385 | protected $paexINI; 386 | } 387 | 388 | ?> -------------------------------------------------------------------------------- /datatypes/ezpaex/ezpaextype.php: -------------------------------------------------------------------------------- 1 | false, 26 | 'serialize_supported' => true ) ); 27 | } 28 | 29 | /** 30 | * @deprecated Use ezpaextype::__construct() instead 31 | */ 32 | public function ezpaextype() 33 | { 34 | self::__construct(); 35 | } 36 | 37 | /** 38 | * Delete stored object attribute 39 | */ 40 | function deleteStoredObjectAttribute( $contentObjectAttribute, $version = null ) 41 | { 42 | $db = eZDB::instance(); 43 | $paexID = $contentObjectAttribute->attribute( "contentobject_id" ); 44 | 45 | $res = $db->arrayQuery( "SELECT COUNT(*) AS version_count FROM ezcontentobject_version WHERE contentobject_id = $paexID" ); 46 | $versionCount = $res[0]['version_count']; 47 | 48 | if ( $version == null || $versionCount <= 1 ) 49 | { 50 | eZPaEx::removePaex( $paexID ); 51 | } 52 | } 53 | 54 | /** 55 | * Validates input on content object level 56 | * 57 | * @return eZInputValidator::STATE_ACCEPTED or eZInputValidator::STATE_INVALID if 58 | * the values are accepted or not 59 | */ 60 | function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute ) 61 | { 62 | $integerValidator = new eZIntegerValidator(0); 63 | 64 | $passwordlifetime = false; 65 | $expirationnotification = false; 66 | $updatechildren = false; 67 | 68 | if ( $http->hasPostVariable( $base . "_data_paex_passwordlifetime_" . $contentObjectAttribute->attribute( "id" ) ) ) 69 | { 70 | $passwordlifetime = $http->postVariable( $base . "_data_paex_passwordlifetime_" . $contentObjectAttribute->attribute( "id" ) ); 71 | } 72 | if ( $http->hasPostVariable( $base . "_data_paex_expirationnotification_" . $contentObjectAttribute->attribute( "id" ) ) ) 73 | { 74 | $expirationnotification = $http->postVariable( $base . "_data_paex_expirationnotification_" . $contentObjectAttribute->attribute( "id" ) ); 75 | } 76 | 77 | // Check if passwordlifetime is set, that it's an integer >= 0 78 | $statusPasswordlifetime = $integerValidator->validate( $passwordlifetime ); 79 | if ( $statusPasswordlifetime != eZInputValidator::STATE_ACCEPTED && trim( $passwordlifetime ) ) 80 | { 81 | $contentObjectAttribute->setValidationError( ezpI18n::tr( 'mbpaex/classes/datatypes', 82 | 'The password lifetime must be an integer >= 0' ) ); 83 | return eZInputValidator::STATE_INVALID; 84 | } 85 | 86 | // Check if expirationnotification is set, that it's an integer >= 86400 (1 day) 87 | $integerValidator->setRange( 86400, false ); 88 | $statusExpirationnotification = $integerValidator->validate( $expirationnotification ); 89 | if ( $statusExpirationnotification != eZInputValidator::STATE_ACCEPTED && trim( $expirationnotification ) ) 90 | { 91 | $contentObjectAttribute->setValidationError( ezpI18n::tr( 'mbpaex/classes/datatypes', 92 | 'The expiration notification time must be an integer >= 86400' ) ); 93 | return eZInputValidator::STATE_INVALID; 94 | } 95 | 96 | // Check if password validates regexp 97 | $contentObjectID = $contentObjectAttribute->attribute( "contentobject_id" ); 98 | 99 | // Check if paex object for the current coID exists, use default one if needed. 100 | $paex = $contentObjectAttribute->content(); 101 | if ( $paex === null ) 102 | { 103 | $paex = eZPaEx::create( $contentObjectID ); 104 | } 105 | 106 | // If the current contentobject is a user, check if the password has changed and validate if needed 107 | if ( $paex->isUser() ) 108 | { 109 | // Search for password entered in the form 110 | foreach ( $http->postVariable( $base . '_id' ) as $coaid ) 111 | { 112 | if ($http->hasPostVariable($base . '_data_user_password_' . $coaid)) 113 | { 114 | $newPassword = $http->postVariable($base . '_data_user_password_' . $coaid); 115 | break; 116 | } 117 | } 118 | 119 | if (trim($newPassword) && ($newPassword != "_ezpassword")) 120 | { 121 | if ( $paex->canEdit() ) 122 | { 123 | if ($http->hasPostVariable( $base . "_data_paex_passwordvalidationregexp_" . $contentObjectAttribute->attribute( "id" ) )) 124 | { 125 | $paex->setAttribute('passwordvalidationregexp', $http->postVariable( $base . "_data_paex_passwordvalidationregexp_" . $contentObjectAttribute->attribute( "id" ) )); 126 | } 127 | } 128 | if (!$paex->validatePassword($newPassword)) 129 | { 130 | $contentObjectAttribute->setValidationError( ezpI18n::tr( 'mbpaex/classes/datatypes', 131 | "The password doesn't match the validation rule. 132 | Previous password will be preserved if there is any." ) ); 133 | return eZInputValidator::STATE_INVALID; 134 | } 135 | } 136 | } 137 | else // If we are updating a group, try to check the updatechildren checkbox 138 | { 139 | if ($http->hasPostVariable( $base . "_data_paex_updatechildren_" . $contentObjectAttribute->attribute( "id" ) )) 140 | { 141 | $updatechildren = $http->postVariable( $base . "_data_paex_updatechildren_" . $contentObjectAttribute->attribute( "id" ) ); 142 | } 143 | // Check if updatechildren is set, that it's an integer 0 or 1 (1 day) 144 | $integerValidator->setRange(0, 1); 145 | $statusUpdatechildren = $integerValidator->validate($updatechildren); 146 | if ( $statusUpdatechildren != eZInputValidator::STATE_ACCEPTED && trim($updatechildren) ) 147 | { 148 | $contentObjectAttribute->setValidationError( ezpI18n::tr( 'mbpaex/classes/datatypes', 149 | 'Wrong value in updatechildren field' ) ); 150 | return eZInputValidator::STATE_INVALID; 151 | } 152 | } 153 | return eZInputValidator::STATE_ACCEPTED; 154 | } 155 | 156 | /** 157 | * Fetches all variables from the object 158 | * 159 | * @return bool true if fetching of class attributes are successfull, false if not 160 | */ 161 | function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute ) 162 | { 163 | $contentObjectID = $contentObjectAttribute->attribute( "contentobject_id" ); 164 | 165 | // check if paex object for the current coID exists, create if needed. 166 | $paex = $contentObjectAttribute->content(); 167 | if ( $paex === null ) 168 | { 169 | $paex = eZPaEx::create( $contentObjectID ); 170 | } 171 | 172 | // Set current values as default ones 173 | $passwordvalidationregexp = $paex->attribute( 'passwordvalidationregexp' ); 174 | $passwordlifetime = $paex->attribute( 'passwordlifetime' ); 175 | $expirationnotification = $paex->attribute( 'expirationnotification' ); 176 | $passwordLastUpdated = $paex->attribute( 'password_last_updated' ); 177 | $updatechildren = $paex->attribute( 'updatechildren' ); 178 | $expirationnotificationSent = $paex->attribute( 'expirationnotification_sent' ); 179 | 180 | // Update current values with new ones entered in the form if there are any 181 | if ($http->hasPostVariable( $base . "_data_paex_passwordvalidationregexp_" . $contentObjectAttribute->attribute( "id" ) ) ) 182 | { 183 | $passwordvalidationregexp = $http->postVariable( $base . "_data_paex_passwordvalidationregexp_" . $contentObjectAttribute->attribute( "id" ) ); 184 | } 185 | 186 | if ($http->hasPostVariable( $base . "_data_paex_passwordlifetime_" . $contentObjectAttribute->attribute( "id" ) ) ) 187 | { 188 | $passwordlifetime = $http->postVariable( $base . "_data_paex_passwordlifetime_" . $contentObjectAttribute->attribute( "id" ) ); 189 | } 190 | 191 | if ($http->hasPostVariable( $base . "_data_paex_expirationnotification_" . $contentObjectAttribute->attribute( "id" ) ) ) 192 | { 193 | $expirationnotification = $http->postVariable( $base . "_data_paex_expirationnotification_" . $contentObjectAttribute->attribute( "id" ) ); 194 | } 195 | // Be sure passwordlifetime is set 196 | if ( trim( $passwordlifetime ) == '' ) 197 | { 198 | $passwordlifetime = eZPaEx::NOT_DEFINED; 199 | } 200 | 201 | // Be sure expirationnotification is set 202 | if ( trim( $expirationnotification ) == '' ) 203 | { 204 | $expirationnotification = eZPaEx::NOT_DEFINED; 205 | } 206 | 207 | // If we are editing a user account set it's password_last_updated as needed. 208 | if ( $paex->isUser() ) 209 | { 210 | // Search for password entered in the form 211 | $newPassword = ""; 212 | foreach ( $http->postVariable( $base . '_id' ) as $coaid ) 213 | { 214 | if ( $http->hasPostVariable( $base . '_data_user_password_' . $coaid ) ) 215 | { 216 | $newPassword = $http->postVariable( $base . '_data_user_password_' . $coaid ); 217 | break; 218 | } 219 | } 220 | // Check if the password has changed 221 | if ( trim( $newPassword ) && ( $newPassword != "_ezpassword" ) ) 222 | { 223 | $currentUserID = eZUser::currentUserID(); 224 | if ( $currentUserID == $contentObjectID ) 225 | { 226 | // If self editing, set last_updated to current time 227 | $passwordLastUpdated = time(); 228 | 229 | // if audit is enabled password changes should be logged 230 | eZAudit::writeAudit( 'user-password-change-self', array( ) ); 231 | } 232 | else if ( $currentUserID == eZUser::anonymousId() ) 233 | { 234 | // register, @see http://issues.ez.no/15391 235 | $passwordLastUpdated = time(); 236 | } 237 | else 238 | { 239 | // If changing other user's password, set last_updated to 0 to force 240 | // password change in the next connection 241 | $passwordLastUpdated = 0; 242 | 243 | // if audit is enabled password changes should be logged 244 | $targetUser = eZUser::fetch( $contentObjectID ); 245 | eZAudit::writeAudit( 'user-password-change', array( 'User id' => $targetUser->attribute( 'contentobject_id' ), 'User login' => $targetUser->attribute( 'login' ) ) ); 246 | } 247 | // Password has changed, reset expirationnotification_sent flag to send again a notification when this new password be about to expire 248 | $expirationnotificationSent = 0; 249 | } 250 | } 251 | else 252 | { 253 | // If we are updating a user group and don't have the updatechildren post var, set updatechildren flag to disabled 254 | if ($http->hasPostVariable( $base . "_data_paex_updatechildren_" . $contentObjectAttribute->attribute( "id" ) )) 255 | { 256 | $updatechildren = $http->postVariable( $base . "_data_paex_updatechildren_" . $contentObjectAttribute->attribute( "id" ) ); 257 | } 258 | else 259 | { 260 | $updatechildren = 0; 261 | } 262 | } 263 | 264 | if ( $paex->canEdit() ) 265 | { 266 | // If user has permission, update full paex object with possible new values 267 | $paex->setInformation( $contentObjectID, $passwordvalidationregexp, $passwordlifetime, $expirationnotification, $passwordLastUpdated, $updatechildren, $expirationnotificationSent ); 268 | } 269 | else 270 | { 271 | // If user don't have permission to update paex data, only update the password_last_updated and expirationnotification_sent fields 272 | $paex->setAttribute( 'password_last_updated',$passwordLastUpdated ); 273 | $paex->setAttribute( 'expirationnotification_sent',$expirationnotificationSent ); 274 | } 275 | 276 | $contentObjectAttribute->setContent( $paex ); 277 | return true; 278 | } 279 | 280 | /** 281 | * Store the content. 282 | */ 283 | function storeObjectAttribute( $contentObjectAttribute ) 284 | { 285 | $paex = $contentObjectAttribute->content(); 286 | if ( !$paex instanceof eZPaEx ) 287 | { 288 | // create a default paex object 289 | $paex = eZPaEx::create( $contentObjectAttribute->attribute( "contentobject_id" ) ); 290 | } 291 | $paex->store(); 292 | $contentObjectAttribute->setContent( $paex ); 293 | } 294 | 295 | /** 296 | * Get empty paex data values from parent. 297 | * 298 | * @return bool True if the value was stored correctly. 299 | */ 300 | function onPublish( $contentObjectAttribute, $contentObject, $publishedNodes ) 301 | { 302 | eZDebug::writeDebug( 'Start', __METHOD__ ); 303 | $paex = $contentObjectAttribute->content(); 304 | if ( !$paex instanceof eZPaEx ) 305 | { 306 | return true; 307 | } 308 | 309 | // Update empty paex data from parent paex 310 | // NOTE: if the current user don't have permission to edit paex data, and is 311 | // creating a new object (publishing version 1), force paex object update 312 | // to get values set in parent 313 | if ( !$paex->canEdit() && $contentObject->attribute( 'current_version' ) == 1 ) 314 | $paex->updateFromParent( true ); 315 | else 316 | $paex->updateFromParent(); 317 | 318 | eZDebug::writeDebug( 'End', __METHOD__ ); 319 | return true; 320 | } 321 | 322 | /** 323 | * @return bool true if the datatype finds any content in the attribute \a $contentObjectAttribute. 324 | */ 325 | function hasObjectAttributeContent( $contentObjectAttribute ) 326 | { 327 | $paex = $this->objectAttributeContent( $contentObjectAttribute ); 328 | if ( is_object( $paex ) ) 329 | return true; 330 | return false; 331 | } 332 | 333 | /** 334 | * Returns the content. 335 | */ 336 | function objectAttributeContent( $contentObjectAttribute ) 337 | { 338 | $paexID = $contentObjectAttribute->attribute( "contentobject_id" ); 339 | $paex = eZPaEx::fetch( $paexID ); 340 | return $paex; 341 | } 342 | 343 | /** 344 | * Returns the meta data used for storing search indeces. 345 | */ 346 | function metaData( $contentObjectAttribute ) 347 | { 348 | return $contentObjectAttribute->attribute('id'); 349 | } 350 | 351 | /** 352 | * Returns the value as it will be shown if this attribute is used in the 353 | * object name pattern. 354 | */ 355 | function title( $contentObjectAttribute, $name = null ) 356 | { 357 | return $contentObjectAttribute->attribute('id'); 358 | } 359 | 360 | /** 361 | * @return true if the datatype can be indexed 362 | */ 363 | function isIndexable() 364 | { 365 | return true; 366 | } 367 | } 368 | 369 | eZDataType::register( ezpaextype::DATA_TYPE_STRING, "ezpaextype" ); 370 | ?> 371 | --------------------------------------------------------------------------------