1
0
Fork 0
mirror of https://github.com/dducret/kopano-webapp-passwd synced 2026-07-27 10:32:26 +02:00

added dialog for password change

implemented skeleton for php code
This commit is contained in:
Saket Patel 2013-07-03 03:30:43 +05:30
commit b434706684
7 changed files with 340 additions and 12 deletions

View file

@ -1,4 +1,13 @@
<?php
/** Enable the passwd plugin for all clients **/
define('PLUGIN_PASSWD_USER_DEFAULT_ENABLE', true);
/** Define zarafa installtion uses LDAP **/
define('PLUGIN_PASSWD_LDAP', true);
/** Base DN to access LDAP users **/
define('PLUGIN_PASSWD_LDAP_BASEDN', 'dc=example,dc=com');
/** URI to access LDAP server **/
define('PLUGIN_PASSWD_LDAP_URI', 'localhost');
?>

View file

@ -5,4 +5,4 @@ Ext.namespace('Zarafa.plugins.passwd');
*
* The copyright string holding the copyright notice for the Zarafa passwd Plugin.
*/
Zarafa.plugins.sugarcrm.ABOUT = "Something should be here";
Zarafa.plugins.passwd.ABOUT = "Something should be here";

34
js/PasswdContentPanel.js Normal file
View file

@ -0,0 +1,34 @@
Ext.namespace('Zarafa.plugins.passwd');
/**
* @class Zarafa.plugins.passwd.PasswdContentPanel
* @extends Zarafa.core.ui.ContentPanel
*
* Content panel that will layout the container
*/
Zarafa.plugins.passwd.PasswdContentPanel = Ext.extend(Zarafa.core.ui.ContentPanel, {
/**
* @constructor
* @param {Object} config configuration object that needs to be used when creating this dialog
*/
constructor : function(config)
{
config = config || {};
Ext.applyIf(config, {
xtype : 'zarafa.passwdcontentpanel',
layout : 'fit',
height : 175,
width : 400,
title : _('Change password'),
items : [{
xtype : 'zarafa.passwdpanel'
}]
});
Zarafa.plugins.passwd.PasswdContentPanel.superclass.constructor.apply(this, arguments);
}
});
Ext.reg('zarafa.passwdcontentpanel', Zarafa.plugins.passwd.PasswdContentPanel);

96
js/PasswdPanel.js Normal file
View file

@ -0,0 +1,96 @@
Ext.namespace('Zarafa.plugins.passwd');
/**
* @class Zarafa.plugins.passwd.PasswdPanel
* @extends Ext.form.FormPanel
*
* Panel which holds a form that will be used to change the password
*/
Zarafa.plugins.passwd.PasswdPanel = Ext.extend(Ext.form.FormPanel, {
/**
* @property
* @type Ext.LoadMask
*/
saveMask : undefined,
/**
* @constructor
* @param {Object} config configuration object that needs to be used when creating this dialog
*/
constructor : function(config)
{
config = config || {};
Ext.applyIf(config, {
xtype : 'zarafa.passwdpanel',
labelWidth : 150,
defaults : {
width : 200
},
items : [{
xtype : 'displayfield',
ref : 'userNameField',
fieldLabel : 'User name'
}, {
xtype : 'textfield',
ref : 'oldPasswdField',
fieldLabel : 'Current password',
inputType : 'password'
}, {
xtype : 'textfield',
ref : 'newPasswdField',
fieldLabel : 'New password',
inputType : 'password'
}, {
xtype : 'textfield',
ref : 'newPasswdRepeatField',
fieldLabel : 'Retype new password',
inputType : 'password'
}],
buttons : [{
text : 'Ok',
handler : this.onOk,
scope : this
}, {
text : 'Cancel',
handler : this.onCancel,
scope : this
}]
});
Zarafa.plugins.passwd.PasswdPanel.superclass.constructor.apply(this, arguments);
this.on('afterrender', this.initialize, this);
},
initialize : function()
{
this.userNameField.setValue(container.getUser().getUserName());
this.saveMask = new Ext.LoadMask(this.getEl(), {
msg : _('Saving please wait ...')
})
},
onOk : function()
{
// send request
this.saveMask.show();
container.getRequest().singleRequest('passwdmodule', 'save', {
username : this.userNameField.getValue(),
current_password : this.oldPasswdField.getValue(),
new_password : this.newPasswdField.getValue(),
new_password_repeat : this.newPasswdRepeatField.getValue()
//}, new Zarafa.plugins.sugarcrm.data.SugarCRMResponseHandler());
});
},
onCancel : function()
{
this.dialog.close();
}
});
Ext.reg('zarafa.passwdpanel', Zarafa.plugins.passwd.PasswdPanel);

View file

@ -19,6 +19,49 @@ Zarafa.plugins.passwd.PasswdPlugin = Ext.extend(Zarafa.core.Plugin, {
Zarafa.plugins.passwd.PasswdPlugin.superclass.initPlugin.apply(this, arguments);
this.registerInsertionPoint('main.maintabbar.right', this.putTabbarButton, this);
// Register common specific dialog types
Zarafa.core.data.SharedComponentType.addProperty('plugins.passwd.passwdpanel');
},
/**
* Bid for the type of shared component and the given record.
* @param {Zarafa.core.data.SharedComponentType} type Type of component a context can bid for.
* @param {Ext.data.Record} record Optionally passed record.
* @return {Number} The bid for the shared component
*/
bidSharedComponent: function(type, record)
{
var bid = -1;
switch (type) {
// Bid for password dialog
case Zarafa.core.data.SharedComponentType['plugins.passwd.passwdpanel']:
bid = 1;
break;
}
return bid;
},
/**
* Will return the reference to the shared component.
* Based on the type of component requested a component is returned.
* @param {Zarafa.core.data.SharedComponentType} type Type of component a context can bid for.
* @param {Ext.data.Record} record Optionally passed record.
* @return {Ext.Component} Component
*/
getSharedComponent: function(type, record)
{
var component;
switch (type) {
case Zarafa.core.data.SharedComponentType['plugins.passwd.passwdpanel']:
component = Zarafa.plugins.passwd.PasswdContentPanel;
break;
}
return component;
},
/**
@ -42,7 +85,10 @@ Zarafa.plugins.passwd.PasswdPlugin = Ext.extend(Zarafa.core.Plugin, {
*/
clickPasswdButton : function()
{
// open a dialog
var componentType = Zarafa.core.data.SharedComponentType['plugins.passwd.passwdpanel'];
Zarafa.core.data.UIFactory.openLayerComponent(componentType, undefined, {
modal : true
});
}
});

View file

@ -23,6 +23,8 @@
<clientfile load="release">js/passwd.js</clientfile>
<clientfile load="debug">js/passwd-debug.js</clientfile>
<clientfile load="source">js/PasswdPlugin.js</clientfile>
<clientfile load="source">js/PasswdContentPanel.js</clientfile>
<clientfile load="source">js/PasswdPanel.js</clientfile>
<clientfile load="source">js/ABOUT.js</clientfile>
</client>
<!-- <resources>

View file

@ -3,29 +3,20 @@
* Passwd module.
*
*/
class PasswdModule extends Module
{
public function __construct($id, $data) {
parent::Module($id, $data);
}
/**
* Process the incoming events that were fire by the client.
*
* @return boolean True if everything was processed correctly.
*/
public function execute()
{
$result = false;
foreach($this->data as $actionType => $actionData)
{
if(isset($actionType)) {
try {
switch($actionType)
{
case "save":
case 'save':
$this->save($actionData);
break;
default:
@ -38,5 +29,155 @@ class PasswdModule extends Module
}
}
}
public function save($data)
{
// some sanity checks
if(empty($data)) {
$this->sendFeedback(false);
}
if(empty($data['username']) || empty($data['current_password']) || empty($data['new_password']) || empty($data['new_password_repeat'])) {
$this->sendFeedback(false);
}
if(PLUGIN_PASSWD_LDAP) {
$this->saveInLDAP($data);
} else {
$this->saveInDB($data);
}
}
public function saveInLDAP($data)
{
$errorMessage = '';
// connect to LDAP server
$ldapconn = ldap_connect(PLUGIN_PASSWD_LDAP_URI);
// check connection is successfull
if(ldap_errno($ldapconn) === 0) {
// search for the user dn that will be used to do login into LDAP
$userdn = ldap_search (
$ldapconn, // connection-identify
PLUGIN_PASSWD_LDAP_BASEDN, // basedn
"uid=".$uid, // search filter
array("dn") // needed attributes. we need the dn
);
if ($userdn) {
$userdn = ldap_get_entries($ldapconn, $userdn);
$userdn = $userdn[0]['dn'];
// bind to ldap directory
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
// login with current password if that fails then current password is wrong
$bind = ldap_bind($ladpconn, $userdn, $data['current_password']);
if(ldap_errno($ldapconn) === 0) {
$passwd = $data['new_password'];
$passwdRepeat = $data['new_password_repeat'];
if($passwd === $passwdRepeat) {
if(checkPasswordStrenth($passwd)) {
$password_hash = sshaEncode($passwd);
$entry = array('userPassword' => $password_hash);
$return_mod = ldap_modify($ldapconn, $userdn, $entry);
if (ldap_errno($ldapconn) === 0) {
// password changed successfully
$this->sendFeedback(true, {
'info' => array(
'display_message' => _('Password is changed successfully.')
)
});
} else {
$errorMessage = _('Password is not changed.');
}
} else {
$errorMessage = _('Password is weak.');
}
} else {
$errorMessage = _('New passwords does not match.');
}
} else {
$errorMessage = _('Current password does not match.');
}
// release ldap-bind
ldap_unbind($ldapconn);
}
}
if(!empty($errorMessage)) {
$this->sendFeedback(false, {
'type' => 999, // ERROR_LDAP
'info' => array(
'ldap_error' => ldap_errno(),
'ldap_error_name' => ldap_error(),
'display_message' => $errorMessage
)
});
}
}
public function saveInDB($data)
{
$passwd = $data['new_password'];
$passwdRepeat = $data['new_password_repeat'];
$passwd_cmd = "/usr/bin/zarafa-passwd -u %s -o %s -p %s";
if($passwd === $passwdRepeat) {
if(checkPasswordStrenth($passwd)) {
// all information correct, change password
$cmd = sprintf($passwd_cmd, $data['username'], $data['current_passwd'], $passwd);
exec($cmd, $arrayout, $retval);
if ($retval === 0) {
// password changed successfully
$this->sendFeedback(true, {
'info' => array(
'display_message' => _('Password is changed successfully.')
)
});
} else {
$errorMessage = _('Password is not changed.');
}
} else {
$errorMessage = _('Password is weak.');
}
} else {
$errorMessage = _('New passwords does not match.');
}
}
// check passwords. They should meet the following criteria:
// - min. 8 chars, max. 20
// - contain caps und noncaps characters
// - contain numbers
// return FALSE if not all criteria are met
public function checkPasswordStrenth($password)
{
// @FIXME should be moved to client side
if (preg_match("#.*^(?=.{8,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*$#", $password)) {
return true;
} else {
return false;
}
}
// create a ldap-password-hash from $text
function sshaEncode($text)
{
$salt = '';
for ($i=1; $i<=10; $i++) {
$salt .= substr('0123456789abcdef', rand(0, 15), 1);
}
$hash = '{SSHA}' . base64_encode(pack("H*",sha1($text . $salt)) . $salt);
return $hash;
}
}
?>