Hey everybody,
today i added a little field to my user/edit page with that it is possible to edit the xmpp password in the dxmpp and ejabberd db. Everyone who want to use this, read the comments.


/********** add password edit form for dxmpp users! ************ */
/**
 * Implementation of hook_form_alter()
 */
 /**
 * Encrypt the user password for saving in the system
 */
function dxmpp_user_encrypt_password($password = NULL) {
  if (!is_null($password) && drupal_strlen($password)) {
    return strtr($password, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm nopqrstuvwxyz', 'fo2gFeBMQ45Vl3sDp1HGTYbz7vWdikU86taqSPE0muZOj9cKr xRLnJXhwyCIAN');
  }
  return NULL;
}

/**
 * Decrypt the user password for usage by the system
 */
function dxmpp_user_decrypt_password($password = NULL) {
  if (!is_null($password) && drupal_strlen($password)) {
    return strtr($password, 'fo2gFeBMQ45Vl3sDp1HGTYbz7vWdikU86taqSPE0muZOj9cKr xRLnJXhwyCIAN', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm nopqrstuvwxyz');
  }
  return NULL;
}


function dxmpp_form_alter(&$form, $form_state, $form_id) {
	if($form_id == 'user_profile_form') {
		global $user;
		$user_data = db_fetch_object(db_query("SELECT uid, xid, xmpp_username, xmpp_password, password_changed FROM {dxmpp_users} WHERE uid = %d", $user->uid));	//you have to create a new field to the dxmp_users database -> the easiest way: copy the uid field, rename it to password_changed in the install.file  and reinstall the module.
		//display password edit form if user has an existing dxmpp account
			if($user_data->xmpp_username) {
				$form['account']['dxmpp_user']['jid'] = array(
				  '#type' => 'textfield',
				  '#title' => t('Chat UserID'),
				  '#value' => $user_data->xmpp_username . '@domain.de',
				  '#disabled' => TRUE,
				  '#description' => t('This is your ID you have to use for the Connection to the Chat with an external client.'),
				  // has to be locked only for informative use!!!!!!! 
				);
				if($user_data->password_changed == '0') {
					$form['account']['dxmpp_user']['password'] = array(
					  '#type' => 'textfield',
					  '#title' => t('Password'),
					  '#default_value' => $user_data->xmpp_password,
					  '#description' => t('This is your default xmpp password for the use with external clients. You can set here your own password. For security reasons please choose a different than your normal login password. For urgent matters please contact chat@....de'),
					);
				} else {
					  $form['account']['dxmpp_user']['password'] = array(
					  '#type' => 'password',
					  '#title' => t('Password'),
					  '#description' => t('You can set here your own password - leave blank if you dont want to change. For security reasons please choose a different than your normal login password. For urgent matters please contact chat@aktientempel.de'),
					);
				}
				$form['submit']['#submit'][] = 'dxmpp_form_validate';
			  return $form;
			  } else { //if user has no dxmpp user account
				  $form['account']['dxmpp_user']['jid'] = array(
				  '#type' => 'textfield',
				  '#title' => t('JID'),
				  '#default_value' => t('no ID found!'),
				  '#description' => t('You do not have an existing chat account. Please visit one of the chats - than your useraccount will be created automaticily.'),
				  // has to be locked only for informative use!!!!!!! 
				);
				return $form;
			  }
	}
}

function dxmpp_form_validate($form, &$form_state) {
  if(strlen($form_state['values']['password']) < '6') {
    form_set_error('text', t('Your Password for the using the Chat has not been set. Please enter password of more than 5 character length!'));
  } elseif(ereg('[^A-Za-z0-9_!,"()/]', $form_state['values']['password'])) { 
  form_set_error('text', t('Please use only alphabets a to z, numbers from 0 to 9 or these special characters _!,"()/ in your Chat password'));
  } else {
   dxmpp_user_login_block_submit($form, &$form_state);
  }
}

function dxmpp_get_domain($url) {
	$nowww = ereg_replace('www\.','',$url);
	$domain = parse_url($nowww);
		if(!empty($domain["host"]))	{
			return $domain["host"];
		} else {
			return $domain["path"];
		}
}

function dxmpp_user_login_block_submit($form, &$form_state) {
	// get the right user data by uid
	global $user;
	$user_data = db_fetch_object(db_query("SELECT uid, xid, xmpp_username, xmpp_password, password_changed FROM {dxmpp_users} WHERE uid = %d", $user->uid));
	//check if password field is set and if it is a new one - if not nothing changed!
	if($form_state['values']['password'] != '' && dxmpp_user_decrypt_password($user_data->xmpp_password) != dxmpp_user_decrypt_password($form_state['values']['password'])) {
		// just have to figure out the right data from $form_state
		$username = $user_data->xmpp_username; 
		$password = $form_state['values']['password']; 
		$xid = $user_data->xid;
		$domain = dxmpp_get_domain($_SERVER['HTTP_HOST']); 
		//wirte the new data into the dxmpp database 
		 $object = (object) array(
			'xmpp_password' => dxmpp_user_encrypt_password($password),
			'password_changed' => "1",
			'xid' => $xid,
		  );
		 drupal_write_record('dxmpp_users', $object, 'xid');
		//tell ejabberd the new password! ejabberdct copied and renamed to ejabberdctl_php. If using ejabberd 2.1.5. installed by the .bin installer add (right below the #!/bin/bash line) export HOME=/var/www (if this is your $homedir of the user running this script) and copy the .erlang.cookie to the same.
		//use your installation path of ejabebrd! 
		exec("/ADD HERE YOUR INSTALL PATH OF EJABBERD/ejabberdctl_php change_password $username $domain dxmpp_user_decrypt_password($password)");
	}
  }

Comments

IckZ’s picture

sorry did a mistake in the last function $password should be decyrpted before it goes into the db and the shell command could not execute php code.

function dxmpp_user_login_block_submit($form, &$form_state) {
	// get the right user data by uid
	global $user;
	$user_data = db_fetch_object(db_query("SELECT uid, xid, xmpp_username, xmpp_password, password_changed FROM {dxmpp_users} WHERE uid = %d", $user->uid));
	//check if password field is set and if it is a new one - if not nothing changed!
	if($form_state['values']['password'] != '' && dxmpp_user_decrypt_password($user_data->xmpp_password) != dxmpp_user_decrypt_password($form_state['values']['password'])) {
		// just have to figure out the right data from $form_state
		$username = $user_data->xmpp_username; 
		$password = dxmpp_user_encrypt_password($form_state['values']['password']); 
		$xid = $user_data->xid;
		$domain = dxmpp_get_domain($_SERVER['HTTP_HOST']); 
		//wirte the new data into the dxmpp database 
		 $object = (object) array(
			'xmpp_password' => $password,
			'password_changed' => "1",
			'xid' => $xid,
		  );
		 drupal_write_record('dxmpp_users', $object, 'xid');
		//tell ejabberd the new password! ejabberdct copied and renamed to ejabberdctl_php. If using ejabberd 2.1.5. installed by the .bin installer add (right below the #!/bin/bash line) export HOME=/var/www (if this is your $homedir of the user running this script) and copy the .erlang.cookie to the same.
		//use your installation path of ejabebrd! 
		$password = dxmpp_user_decrypt_password($password);
		shell_exec("/opt/dir of ejabberd/ejabberdctl_php change_password $username $domain $password");
	}
  }
aleix’s picture

Could it be used with the last dxmpp code? And do you have alternative for openfire? If not I'll investigate how...

IckZ’s picture

Hey aleix,
I dont use openfire, so I dont know which shell commands it have... I also see that I have forgotten to say that you have to change the code around line ~242 to this:

    if ($xmpp && $xmpp->xmpp_username) {
	$user_data = db_fetch_object(db_query("SELECT uid, password_changed FROM {dxmpp_users} WHERE uid = %d", $account->uid));	//check if password has changed!
	 if($user_data->password_changed == '1') {
		$xmpp->xmpp_password = dxmpp_user_decrypt_password($xmpp->xmpp_password);  // password decryption
	  }

to check if the password has changed and has to encyrpt.

cheers!