?`~'); ////////////////////////////////////////////////////////////////////////////// // Core API hooks /** * Implementation of hook_help(). */ function ldapprov_help($path, $arg) { switch ($path) { case 'user/validate': return '

'. t('Please check your e-mail and click the link in the message to confirm your address. If you are unable to click the link, you can copy the secret code from the e-mail and enter it below.') .'

'; case 'admin/user/accounts': return t('This page displays user accounts which have been requested but have not yet been approved (are not yet usable by the persons who requested them).'); case 'admin/user/accounts/created': return t('These accounts have been filled in by either a user or administrator and have been given administrator approval. An account here may be used to access this site.'); case 'admin/user/accounts/rejected': return t('These accounts were created by users requesting access to the site, but have been rejected by an administrator. An account here cannot be used to access this site.'); case 'admin/user/accounts/deleted': return t('These accounts have been removed from the system. '); case 'admin/user/accounts/unverified': return t('An unverified account has been requested by someone intending to access the site, but that person has not yet entered the code, emailed to them by the site, which verifies the validity of their email address and their status as a real person (and, therefore, not a spam program or virus).'); } } /** * Implementation of hook_init(). */ function ldapprov_init() { // Initiates LDAP object. if (LDAPPROV_ENABLED) { _ldapprov_init(); } } /** * Implementation of hook_perm(). */ function ldapprov_perm() { return array(LDAPPROV_PERMISSION, LDAPPROV_ROLE_PERMISSION); } /** * Implementation of hook_theme(). */ function ldapprov_theme() { return array( 'ldapprov_list_form' => array( 'arguments' => array('form' => NULL), 'file' => 'ldapprov.theme.inc', ), ); } /** * Implementation of hook_menu(). */ function ldapprov_menu() { return array( 'admin/settings/ldap/ldapprov' => array( 'title' => 'Provisioning', 'description' => 'Configure LDAP provisioning settings.', 'page callback' => 'drupal_get_form', 'page arguments' => array('ldapprov_admin_settings'), 'access arguments' => array('administer site configuration'), 'file' => 'ldapprov.admin.inc', ), 'admin/settings/ldap/ldapprov/test' => array( 'title' => 'Test LDAP Server', 'page callback' => '_ldapprov_ajax_test', 'type' => MENU_CALLBACK, 'access arguments' => array('administer ldap modules'), 'file' => 'ldapprov.admin.inc', ), 'admin/user/accounts' => array( 'title' => 'Account management', 'description' => 'Configure LDAP provisioning accounts.', 'page callback' => 'ldapprov_list', 'access arguments' => array(LDAPPROV_PERMISSION), 'weight' => -1, ), 'admin/user/accounts/pending' => array( 'title' => 'Pending', 'type' => MENU_DEFAULT_LOCAL_TASK, ), 'admin/user/accounts/pending/create' => array( 'page callback' => 'drupal_get_form', 'page arguments' => array('ldapprov_create', 3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, ), 'admin/user/accounts/created' => array( 'title' => 'Created', 'page callback' => 'ldapprov_list', 'page arguments' => array(3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, 'weight' => 1, ), 'admin/user/accounts/created/create' => array( 'page callback' => 'drupal_get_form', 'page arguments' => array('ldapprov_create', 3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, ), 'admin/user/accounts/rejected' => array( 'title' => 'Rejected', 'page callback' => 'ldapprov_list', 'page arguments' => array(3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, 'weight' => 2, ), 'admin/user/accounts/rejected/create' => array( 'page callback' => 'drupal_get_form', 'page arguments' => array('ldapprov_create', 3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, ), 'admin/user/accounts/deleted' => array( 'title' => 'Deleted', 'page callback' => 'ldapprov_list', 'page arguments' => array(3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, 'weight' => 3, ), 'admin/user/accounts/deleted/create' => array( 'page callback' => 'drupal_get_form', 'page arguments' => array('ldapprov_create', 3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, ), 'admin/user/accounts/unverified' => array( 'title' => 'Unverified', 'page callback' => 'ldapprov_list', 'page arguments' => array(3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, 'weight' => 4, ), 'admin/user/accounts/unverified/create' => array( 'title' => 'Create', 'page callback' => 'drupal_get_form', 'page arguments' => array('ldapprov_create', 3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, ), 'admin/user/accounts/new' => array( 'title' => 'Create user', 'page callback' => 'drupal_get_form', 'page arguments' => array('ldapprov_create', 3), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_LOCAL_TASK, 'weight' => 5, ), 'ldapprov/template' => array( 'title' => 'Batch upload file template', 'page callback' => '_ldapprov_template', 'page arguments' => array(2), 'access arguments' => array(LDAPPROV_PERMISSION), 'type' => MENU_CALLBACK, ), ); } /** * Implementation of hook_menu_alter(). */ function ldapprov_menu_alter(&$callbacks) { // LDAPPROV_ENABLED won't work here because the variable. // is changed on settings save. if (variable_get('ldapprov_enabled', 0)) { // Take over the registration form. $callbacks['user/register']['page arguments'] = array('ldapprov_register', 2); unset($callbacks['user/register']['file']); // Secret code validation. $callbacks['user/validate'] = array( 'title' => 'Validate e-mail', 'page callback' => 'drupal_get_form', 'page arguments' => array('ldapprov_code', 2), 'access callback' => 'user_register_access', 'type' => MENU_LOCAL_TASK, ); } if (!variable_get('ldapprov_enabled', 0)) { unset($callbacks['admin/user/accounts']); unset($callbacks['admin/user/accounts/pending']); unset($callbacks['admin/user/accounts/created']); unset($callbacks['admin/user/accounts/rejected']); unset($callbacks['admin/user/accounts/deleted']); unset($callbacks['admin/user/accounts/unverified']); unset($callbacks['admin/user/accounts/new']); } if (variable_get('ldapprov_enabled', 0) && variable_get('ldapprov_disable_create', 0)) { unset($callbacks['admin/user/user/create']); } } /** * Implementation of hook_user(). */ function ldapprov_user($op, &$edit, &$account, $category = NULL) { if (LDAPPROV_ENABLED) { switch ($op) { case 'delete': _ldapprov_user_delete($edit, $account); break; } } } /** * Implementation of hook_form_alter(). */ function ldapprov_form_alter(&$form, $form_state, $form_id) { switch ($form_id) { case "user_profile_form": global $user; if (LDAPPROV_ENABLED && (user_access(LDAPPROV_PERMISSION) || user_access('change own username') && $form['_account']['#value']->uid == $user->uid)) { // Set a custom form validate and submit handlers. $form['#validate'][] = 'ldapprov_account_validate'; $form['#submit'][] = 'ldapprov_account_submit'; } break; case "user_admin_settings": if (LDAPPROV_ENABLED && user_access(LDAPPROV_PERMISSION)) { unset($form['registration']['user_email_verification']); unset($form['email']['admin_created']); unset($form['email']['no_approval_required']); unset($form['email']['pending_approval']); unset($form['email']['deleted']); } break; } } /** * Implementation of hook_mail(). */ function ldapprov_mail($key, &$message, $params) { $language = $message['language']; $account = isset($params['account']) ? $params['account'] : (object)array(); $variables = array_merge(user_mail_tokens($account, $language), $params['variables'] ? $params['variables'] : array()); $message['subject'] .= _ldapprov_mail_text($key .'_subject', $language, $variables); $message['body'][] = _ldapprov_mail_text($key .'_body', $language, $variables); } ////////////////////////////////////////////////////////////////////////////// // FAPI /** * Account save validate handler. */ function ldapprov_account_validate($form, &$form_state) { $values = $form_state['values']; $account = $form['_account']['#value']; if (isset($values['name']) && $account->name != $values['name']) { _ldapprov_user_validate($values['name']); } } /** * Account save submit handler. */ function ldapprov_account_submit($form, &$form_state) { $values = $form_state['values']; $account = $form['_account']['#value']; // The user name in $form['_account']['#value'] is already changed. // Has to look for the old name in the authmap. $result = db_query("SELECT * FROM {authmap} WHERE uid = %d", $account->uid); if (isset($values['name']) && ($row = db_fetch_object($result)) && $row->module == 'ldapauth' && $values['name'] != $row->authname) { _ldapprov_user_update($values['name'], $account); } } ////////////////////////////////////////////////////////////////////////////// // Mail strings /** * Returns a mail string for a variable name. * * Used by ldapprov_mail() and the settings forms to retrieve strings. */ function _ldapprov_mail_text($key, $language = NULL, $variables = array()) { $langcode = isset($language) ? $language->language : NULL; if ($admin_setting = variable_get('ldapprov_mail_'. $key, FALSE)) { // An admin setting overrides the default string. return t($admin_setting, $variables, $langcode); } else { // No override, return default string. switch ($key) { case 'code_subject': return t('Validate your e-mail at !site', $variables, $langcode); case 'code_body': return t("!first_name !last_name,\n\nThank you for registering at !site. You may now validate your e-mail address by entering the code\n\n!code\n\nat !validate_uri (by copying and pasting).\n\nYou may also validate the e-mail by clicking on this link or copying and pasting it in your browser:\n\n!validate_url\n\n-- !site team", $variables, $langcode); case 'reject_subject': return t('Your request at !site has been rejected', $variables, $langcode); case 'reject_body': return t("!first_name !last_name,\n\nSorry, but your account request at !site has been rejected. Please resubmit the registration form with more information.\n\n-----\n\n!message\n\n-- !site team", $variables, $langcode); case 'notify_subject': return t('New account request at !site', $variables, $langcode); case 'notify_body': return t("!first_name !last_name (!mailto) has requested the account at !site.\n\nClick this link !create_url to process the request.", $variables, $langcode); case 'create_subject': return t('The account has been created for you at !site', $variables, $langcode); case 'create_body': return t("!first_name !last_name,\n\nThe account at !site has been created for you. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\n-----\n\n!message\n\n-- !site team", $variables, $langcode); case 'delete_subject': return t('Your account has been deleted at !site', $variables, $langcode); case 'delete_body': return t("!first_name !last_name,\n\nYour account !username has been deleted at !site.\n\n-- !site team", $variables, $langcode); } } } ////////////////////////////////////////////////////////////////////////////// // Account actions /** * User validate action. */ function _ldapprov_user_validate($name) { global $_ldapprov_ldap; // Search for the entry in LDAP. if (isset($name)) { if (!$_ldapprov_ldap->connect(LDAPPROV_DN, LDAPPROV_PASS)) { watchdog('ldapprov', 'User validate: user data could not be read in the LDAP directory. Could not bind as %dn.', array('%dn' => LDAPPROV_DN), WATCHDOG_ERROR); form_set_error('name', t('User data could not be read in the LDAP directory. Please contact site administrator.')); return; } $basedn = $_ldapprov_ldap->getOption('basedn'); $name_attr = $_ldapprov_ldap->getOption('user_attr') ? $_ldapprov_ldap->getOption('user_attr') : LDAP_DEFAULT_USER_ATTRIBUTE; if ($ret = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name .')', array($name_attr))) { form_set_error('name', t('The DN %dn is already taken in LDAP.', array('%dn' => $ret[0]['dn']))); } $_ldapprov_ldap->disconnect(); } } /** * User update action. */ function _ldapprov_user_update($name, $account) { global $_ldapprov_ldap; if (!$_ldapprov_ldap->connect(LDAPPROV_DN, LDAPPROV_PASS)) { watchdog('ldapprov', 'User update: user data could not be read in the LDAP directory. Could not bind as %dn.', array('%dn' => LDAPPROV_DN), WATCHDOG_ERROR); drupal_set_message(t('User update: user data could not be read in the LDAP directory. Please contact site administrator.'), 'error'); return; } $basedn = $_ldapprov_ldap->getOption('basedn'); $name_attr = $_ldapprov_ldap->getOption('user_attr') ? $_ldapprov_ldap->getOption('user_attr') : LDAP_DEFAULT_USER_ATTRIBUTE; if (!$_ldapprov_ldap->rename_entry($account->ldap_dn, $name_attr .'='. $name, $basedn, TRUE)) { watchdog('ldapprov', 'User update: user %name ldap entry %dn was not renamed to a new name %name_new.', array('%name' => $account->name, '%dn' => $account->ldap_dn, '%name_new' => $name), WATCHDOG_ERROR); } $_ldapprov_ldap->disconnect(); user_save($account, array('ldap_dn' => $name_attr .'='. $name .','. $basedn, 'ldap_config' => $_ldapprov_ldap->getOption('sid'))); db_query("UPDATE {authmap} SET authname = '%s' WHERE module = 'ldapauth' AND uid = %d", $name, $account->uid); } /** * User delete action. */ function _ldapprov_user_delete(&$edit, &$account) { global $user, $_ldapprov_ldap; if (isset($account->ldap_dn)) { if (!$_ldapprov_ldap->connect(LDAPPROV_DN, LDAPPROV_PASS)) { watchdog('ldapprov', 'User deletion: user data could not be read in the LDAP directory. Could not bind as %dn.', array('%dn' => LDAPPROV_DN), WATCHDOG_ERROR); drupal_set_message(t('The user !name has not been deleted from the LDAP directory.', array('!name' => theme('username', $account))), 'error'); return; } $basedn = $_ldapprov_ldap->getOption('basedn'); $name_attr = $_ldapprov_ldap->getOption('user_attr') ? $_ldapprov_ldap->getOption('user_attr') : LDAP_DEFAULT_USER_ATTRIBUTE; $name = _ldapprov_get_name_from_dn($account->ldap_dn); if ($ret = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name .')', array($name_attr))) { if ($_ldapprov_ldap->delete_entry($account->ldap_dn)) { watchdog('ldapprov', 'User deletion: user %name has been deleted from the LDAP directory.', array('%name' => $account->name), WATCHDOG_WARNING); } else { watchdog('ldapprov', 'User deletion: user %name has not been deleted from the LDAP directory.', array('%name' => $account->name), WATCHDOG_ERROR); drupal_set_message(t('The user !name has not been deleted from the LDAP directory.', array('!name' => theme('username', $account))), 'error'); } } else { watchdog('ldapprov', 'User deletion: user %name is not found in LDAP directory.', array('%name' => $account->name), WATCHDOG_WARNING, l(t('edit'), 'user/'. $account->uid .'/edit'), WATCHDOG_ERROR); } $_ldapprov_ldap->disconnect(); } // Mark registration entry as deleted. $time = time(); $result = db_query("SELECT * FROM {ldapprov} WHERE uid = %d", $account->uid); if ($row = db_fetch_object($result)) { db_query("UPDATE {ldapprov} SET name = '%s', status = '4', cuid = %d, cname = '%s', approved = %d WHERE rid = %d", $account->name, $user->uid, $user->name, $time, $row->rid); } else { db_query("INSERT INTO {ldapprov} (name, mail, status, registered, approved, cuid, cname) VALUES ('%s', '%s', '4', %d, %d, %d, '%s')", $account->name, $account->mail, $time, $time, $user->uid, $user->name); } // Mail one time deletion notification. $variables = array('!first_name' => isset($row->first_name) ? $row->first_name : NULL, '!last_name' => isset($row->last_name) ? $row->last_name : NULL); $params = array('account' => $account, 'variables' => $variables); $message = drupal_mail('ldapprov', 'delete', $account->mail, user_preferred_language($account), $params); if ($message['result']) { watchdog('ldapprov', 'Account deletion notification e-mail mailed to %name at %mail.', array('%name' => $account->name, '%mail' => $account->mail)); } else { watchdog('ldapprov', 'Error mailing account deletion notification to %name at %mail.', array('%name' => $account->name, '%mail' => $account->mail), WATCHDOG_ERROR); } // If this user has created other users, then capture his name in the db for the record. db_query("UPDATE {ldapprov} SET cname = '%s' WHERE cuid = %d", $account->name, $account->uid); } ////////////////////////////////////////////////////////////////////////////// // LDAP related functions /** * Initiates LDAP object. * * @param $sid * A server ID or NULL for a default server. * * @return */ function _ldapprov_init($sid = NULL) { global $_ldapprov_ldap; if ($server = _ldapprov_get_server($sid)) { $_ldapprov_ldap = new LDAPInterface(); $_ldapprov_ldap->setOption('sid', $server->sid); $_ldapprov_ldap->setOption('name', $server->name); $_ldapprov_ldap->setOption('server', $server->server); $_ldapprov_ldap->setOption('port', $server->port); $_ldapprov_ldap->setOption('tls', $server->tls); $_ldapprov_ldap->setOption('encrypted', $server->encrypted); $_ldapprov_ldap->setOption('basedn', $server->basedn); $_ldapprov_ldap->setOption('user_attr', $server->user_attr); $_ldapprov_ldap->setOption('mail_attr', $server->mail_attr); return $_ldapprov_ldap; } return FALSE; } /** * Load server settings. * * @param $sid * A server ID or NULL for a default server. * * @return * An obgject with the server settings. */ function _ldapprov_get_server($sid = NULL) { static $row = NULL; if (!isset($sid) && is_object($row)) return $row; $result = db_query("SELECT * FROM {ldapauth} WHERE sid = %d", isset($sid) ? $sid : LDAPPROV_SERVER); return $row = db_fetch_object($result); } /** * Get a user name from a dn. * * @param $dn * A LDAP dn. * * @return * A username. */ function _ldapprov_get_name_from_dn($dn) { global $_ldapprov_ldap; $name_attr = $_ldapprov_ldap->getOption('user_attr') ? $_ldapprov_ldap->getOption('user_attr') : LDAP_DEFAULT_USER_ATTRIBUTE; foreach (explode(',', $dn) as $entry) { list($key, $val) = explode('=', trim($entry)); if ($key == $name_attr) { $name = $val; break; } } return $name; } ////////////////////////////////////////////////////////////////////////////// // USER REGISTRATION /** * User registration form. * * @param $form_state * A form state array. * @param $code * A secret code. Correct code means that email is already validated. * * @result * A form array. */ function ldapprov_register(&$form_state, $code = FALSE) { $form = array(); // User registration guidelines from User settings. $form['user_registration_help'] = array( '#value' => filter_xss_admin(variable_get('user_registration_help', '')), ); // Main registration form. $form = array_merge($form, _ldapprov_register_form()); $form['submit'] = array( '#type' => 'submit', '#value' => t('Request new account'), '#weight' => 10 ); // Unset several form elements if user is coming from invite. if (module_exists('ldapprov_invite') && LDAPPROV_INVITE_ENABLED && $code) { $row = db_fetch_object(db_query("SELECT l.* FROM {ldapprov} l WHERE code = '%s'", $code)); if ($row->rid) { if ($row->status > 0) { drupal_set_message(t('The code %code has already been validated.', array('%code' => $code)), 'error'); } else { unset($form['account']['mail']); $form['account']['mail'] = array( '#type' => 'hidden', '#value' => $row->mail, ); $form['code'] = array( '#type' => 'hidden', '#value' => $code, ); } } else { drupal_set_message(t('The code %code is not valid or has expired.', array('%code' => $code)), 'error'); } } return $form; } /** * Main registration form. * Printed on the user registration and admin interface for a new account. * * @param $data * An array of the submitted data. * @param $disabled * If form elements should be disabled (when account is already created). * * @return * A form array. */ function _ldapprov_register_form($data = array(), $disabled = FALSE) { $form['account'] = array('#type' => 'fieldset', '#title' => t('Account information')); if (LDAPPROV_ALLOW_USERNAME) { $form['account']['name'] = array( '#type' => 'textfield', '#title' => t('Username'), '#description' => t('Your full name or your preferred username; only letters, numbers and spaces are allowed.'), '#size' => 30, '#maxlength' => 60, '#default_value' => isset($data['name']) ? $data['name'] : NULL, '#required' => !$disabled ? TRUE : FALSE, '#disabled' => $disabled, '#weight' => -2, ); } if ((!module_exists('profile') || !LDAPPROV_PROFILE || LDAPPROV_PROFILE_FIRST == '' || LDAPPROV_PROFILE_LAST == '') && (!module_exists('content_profile_registration') || !LDAPPROV_CONTENT_PROFILE || LDAPPROV_CONTENT_PROFILE_FIRST == '' || LDAPPROV_CONTENT_PROFILE_LAST == '')) { $form['account']['first_name'] = array( '#type' => 'textfield', '#title' => t('First Name'), '#size' => 30, '#maxlength' => 100, '#default_value' => isset($data['first_name']) ? $data['first_name'] : NULL, '#required' => !$disabled ? TRUE : FALSE, '#disabled' => $disabled, '#weight' => -1, ); $form['account']['last_name'] = array( '#type' => 'textfield', '#title' => t('Last Name'), '#size' => 30, '#maxlength' => 100, '#default_value' => isset($data['last_name']) ? $data['last_name'] : NULL, '#required' => !$disabled ? TRUE : FALSE, '#disabled' => $disabled, '#weight' => 0, ); } $form['account']['mail'] = array( '#type' => 'textfield', '#title' => t('E-mail address'), '#description' => t('A password and instructions will be sent to this e-mail address, so make sure it is accurate.'), '#size' => 30, '#maxlength' => 100, '#default_value' => isset($data['mail']) ? $data['mail'] : NULL, '#required' => !$disabled ? TRUE : FALSE, '#disabled' => $disabled, '#weight' => 2, ); // Custom fields. $form_custom = variable_get('ldapprov_custom', array()); foreach ($form_custom as $name => $field) { $form_custom[$name]['#default_value'] = isset($data[$name]) ? $data[$name] : NULL; $form_custom[$name]['#disabled'] = $disabled; } $form['account'] = array_merge($form['account'], $form_custom); // Print writable ldap fields. if (module_exists('ldapdata')) { $server = _ldapprov_get_server(); $ldapdata_attributes = _ldapdata_ldap_info($server->sid, 'ldapdata_attrs'); $ldapdata_options = variable_get('ldapprov_ldapdata', array()); foreach (_ldapdata_ldap_info($server->sid, 'ldapdata_rwattrs') as $attribute) { if ($attr_info = $ldapdata_attributes[$attribute]) { // if this attribute should be shown ir registration. if (isset($ldapdata_options[$attribute]) && $ldapdata_options[$attribute] > 0) { array_shift($attr_info); $form['account']['ldap_'. $attribute] = _ldapdata_attribute_form($attribute, $data['ldap_'. $attribute], $attr_info); $form['account']['ldap_'. $attribute]['#disabled'] = $disabled; } // If this attribute is required. if (isset($ldapdata_options[$attribute]) && $ldapdata_options[$attribute] > 1) { $form['account']['ldap_'. $attribute]['#required'] = !$disabled ? TRUE : FALSE; } } } } // Print profile fields. if (module_exists('profile') && LDAPPROV_PROFILE) { $form = array_merge($form, array(_ldapprov_profile_form($data, $disabled))); } // Print content profile fields. if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE) { $form = array_merge($form, _ldapprov_content_profile_form($data, $disabled)); } // OG integration. if (module_exists('og') && LDAPPROV_OG) { $form_groups = module_invoke('og', 'user', 'register', NULL, NULL); if (isset($form_groups['og_register']['og_register']) && isset($data['og_register'])) { $form_groups['og_register']['og_register']['#default_value'] = $data['og_register']; $form_groups['og_register']['og_register']['#disabled'] = $disabled; } $form = array_merge($form, is_array($form_groups) ? $form_groups : array()); } return $form; } /** * User registration form validation. */ function ldapprov_register_validate($form, &$form_state) { // Main registration form validation. _ldapprov_register_validate($form_state['values']); if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE) { content_profile_registration_user_register_validate($form, $form_state); } } /** * Main registration form validation. * * @param $values * An array of the values to validate. * @param $messages * A flag if set, then the form errors will be set, otherwise errors will be counted. * * @return * If $messages is not set, then the number of errors. */ function _ldapprov_register_validate($values, $messages = TRUE) { global $_ldapprov_ldap; // When doing mass account creation, check for errors, but don't set form errors. $errors = 0; $basedn = $_ldapprov_ldap->getOption('basedn'); $name_attr = $_ldapprov_ldap->getOption('user_attr') ? $_ldapprov_ldap->getOption('user_attr') : LDAP_DEFAULT_USER_ATTRIBUTE; // When user is allowed to select a username. if (LDAPPROV_ALLOW_USERNAME) { if (preg_match('/^\s+/', $values['name'])) { $errors = ($messages) ? form_set_error('name', t('Username cannot begin with a space.')) : $errors + 1; } if (preg_match('/\s+$/', $values['name'])) { $errors = ($messages) ? form_set_error('name', t('Username cannot end with a space.')) : $errors + 1; } if (preg_match('/[^\w\s]+/', $values['name'])) { $errors = ($messages) ? form_set_error('name', t('Username should contain only letters, numbers and spaces.')) : $errors + 1; } $result = db_query("SELECT uid FROM {users} WHERE name = '%s'", $values['name']); if ($user = db_fetch_object($result)) { $errors = ($messages) ? form_set_error('name', t('The username %name is already taken. Please choose different one.', array('%name' => $values['name']))) : $errors + 1; } // When ldap users are in sync with drupal users, ldap search is not needed. if (!$_ldapprov_ldap->connect(LDAPPROV_DN, LDAPPROV_PASS)) { watchdog('ldapprov', 'User validate: user data could not be read in the LDAP directory. Could not bind as %dn.', array('%dn' => LDAPPROV_DN), WATCHDOG_ERROR); drupal_set_message(t('User validate: user data could not be read in the LDAP directory. Please contact site administrator.'), 'error'); return; } if ($ret = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $values['name'] .')', array('mail'))) { $errors = ($messages) ? form_set_error('name', t('The username %name is already taken. Please choose different one.', array('%name' => $values['name']))) : $errors + 1; } $_ldapprov_ldap->disconnect(); } if (!valid_email_address($values['mail'])) { $errors = ($messages) ? form_set_error('mail', t('The e-mail address %mail is not valid.', array('%mail' => $values['mail']))) : $errors + 1; } $result = db_query("SELECT uid FROM {users} WHERE mail = '%s'", $values['mail']); if ($user = db_fetch_object($result)) { $errors = ($messages) ? form_set_error('mail', t('The user with e-mail address %mail is already registered with the system. Click !request if you forgot your login information.', array('%mail' => $values['mail'], '!request' => l(t('request new password'), 'user/password')))) : $errors + 1; } // When ldap users are in sync with drupal users, ldap search is not needed. if (!$_ldapprov_ldap->connect(LDAPPROV_DN, LDAPPROV_PASS)) { watchdog('ldapprov', 'User validate: user data could not be read in the LDAP directory. Could not bind as %dn.', array('%dn' => LDAPPROV_DN), WATCHDOG_ERROR); drupal_set_message(t('User validate: user data could not be read in the LDAP directory. Please contact site administrator.'), 'error'); return; } if ($ret = $_ldapprov_ldap->search($_ldapprov_ldap->getOption('basedn'), '(mail='. $values['mail'] .')', array('mail'))) { $errors = ($messages) ? form_set_error('mail', t('The user with e-mail address %mail is already registered with the system. Click !request if you forgot your login information.', array('%mail' => $values['mail'], '!request' => l(t('request new password'), 'user/password')))) : $errors + 1; } $_ldapprov_ldap->disconnect(); // First and last names. if (module_exists('profile') && LDAPPROV_PROFILE && LDAPPROV_PROFILE_FIRST != '' && LDAPPROV_PROFILE_LAST != '') { $first_name = $values[LDAPPROV_PROFILE_FIRST]; $last_name = $values[LDAPPROV_PROFILE_LAST]; } else if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE && LDAPPROV_CONTENT_PROFILE_FIRST != '' && LDAPPROV_CONTENT_PROFILE_LAST != '') { $first_name = $values[LDAPPROV_CONTENT_PROFILE_FIRST]; $last_name = $values[LDAPPROV_CONTENT_PROFILE_LAST]; } else { $first_name = $values['first_name']; $last_name = $values['last_name']; } $first_name = is_array($first_name) ? $first_name[0]['value'] : $first_name; $last_name = is_array($last_name) ? $last_name[0]['value'] : $last_name; /* foreach (preg_split('//', LDAPPROV_UID_FORBIDDEN_CHAR) as $c) { if (in_array($c, preg_split('//', $first_name))) { $first_bad .= $c; } if (in_array($c, preg_split('//', $last_name))) { $last_bad .= $c; } } */ if (!LDAPPROV_ALLOW_USERNAME) { // Username is constructed for the user. if (isset($first_name) && preg_match('/^\s+/', $first_name)) { $errors = ($messages) ? form_set_error('first_name', t('First Name cannot begin with a space.')) : $errors + 1; } if (isset($first_name) && preg_match('/\s+$/', $first_name)) { $errors = ($messages) ? form_set_error('first_name', t('First Name cannot end with a space.')) : $errors + 1; } if (isset($first_name) && preg_match('/[^a-zA-Z\'-\s]+/', $first_name)) { $errors = ($messages) ? form_set_error('first_name', t('First Name should contain only latin letters, apostrophe, dash or space.')) : $errors + 1; } /* elseif ($first_bad) { $errors = ($messages) ? form_set_error('first_name', t('First Name should not contain %chars characters.', array('%chars' => $first_bad))) : $errors + 1; } */ if (isset($last_name) && preg_match('/^\s+/', $last_name)) { $errors = ($messages) ? form_set_error('last_name', t('Last Name cannot begin with a space.')) : $errors + 1; } if (isset($last_name) && preg_match('/\s+$/', $last_name)) { $errors = ($messages) ? form_set_error('last_name', t('Last Name cannot end with a space.')) : $errors + 1; } if (isset($last_name) && preg_match('/[^a-zA-Z\'-\s]+/', $last_name)) { $errors = ($messages) ? form_set_error('last_name', t('Last Name should contain only latin letters, apostrophe, dash or space.')) : $errors + 1; } /* elseif ($last_bad) { $errors = ($messages) ? form_set_error('last_name', t('Last Name should not contain %chars characters.', array('%chars' => $last_bad))) : $errors + 1; } */ } else { // Custom usernames are not allowed. if (preg_match('/^\s+$/', $first_name)) { $errors = ($messages) ? form_set_error('first_name', t('First Name can not contain only whitespace characters.')) : $errors + 1; } if (preg_match('/^\s+$/', $last_name)) { $errors = ($messages) ? form_set_error('last_name', t('Last Name can not contain only whitespace characters.')) : $errors + 1; } } // Validating password length. if (isset($values['password']) && !empty($values['password']) && drupal_strlen(trim($values['password'])) < LDAPPROV_PASS_LENGTH) { form_set_error('password', t('Password should be at least %length characters in length.', array('%length' => LDAPPROV_PASS_LENGTH))); } // Checking for a batch user upload. if (!$messages) { return $errors; } } /** * User registration form submission. */ function ldapprov_register_submit($form, &$form_state) { global $language; $time = time(); $values = $form_state['values']; // Prepare data to enter into the database. $data = array('language' => $language->language); foreach ($values as $key => $value) { if (preg_match('/(^profile_|^ldap_|^og_register|^field_|^custom_)/', $key)) { $data[$key] = $value; } } // First and last names. if (module_exists('profile') && LDAPPROV_PROFILE && LDAPPROV_PROFILE_FIRST != '' && LDAPPROV_PROFILE_LAST != '') { $first_name = $values[LDAPPROV_PROFILE_FIRST]; $last_name = $values[LDAPPROV_PROFILE_LAST]; } else if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE && LDAPPROV_CONTENT_PROFILE_FIRST != '' && LDAPPROV_CONTENT_PROFILE_LAST != '') { $first_name = $data[LDAPPROV_CONTENT_PROFILE_FIRST]; $last_name = $data[LDAPPROV_CONTENT_PROFILE_LAST]; } else { $first_name = $values['first_name']; $last_name = $values['last_name']; } $first_name = is_array($first_name) ? $first_name[0]['value'] : $first_name; $last_name = is_array($last_name) ? $last_name[0]['value'] : $last_name; // Check if registering from an invite. if (module_exists('ldapprov_invite') && LDAPPROV_INVITE_ENABLED && isset($values['code'])) { // Registering from an invite. E-mail is valid. $result = db_query("SELECT * FROM {ldapprov} WHERE code = '%s' AND status = '0'", $values['code']); if ($row = db_fetch_object($result)) { $data_initial = unserialize($row->data); db_query("UPDATE {ldapprov} SET name = '%s', first_name = '%s', last_name = '%s', registered = %d, data = '%s', status = '1' WHERE rid = %d", isset($values['name']) ? $values['name'] : NULL, $first_name, $last_name, $time, serialize($data), $row->rid); drupal_set_message(t('Please wait until your account is approved. You will receive login information to your e-mail account.', array('%mail' => $row->mail))); $form_state['redirect'] = 'user'; } else { drupal_set_message(t('The code %code is not valid or has expired.', array('%code' => $values['code'])), 'error'); $form_state['redirect'] = 'user/register'; } } else { // Ordinary registration. // Create a secret code. $hash = _ldapprov_hash((isset($values['name']) ? $values['name'] : NULL) . $first_name . $last_name, $time); db_query("INSERT INTO {ldapprov} (name, mail, first_name, last_name, code, registered, data, status) VALUES ('%s', '%s', '%s', '%s', '%s', %d, '%s', '0')", isset($values['name']) ? $values['name'] : NULL, $values['mail'], $first_name, $last_name, $hash, $time, serialize($data)); // Mail one time login URL and instructions. $variables = array('!validate_url' => url('user/validate/'. $hash, array('absolute' => TRUE)), '!validate_uri' => url('user/validate', array('absolute' => TRUE)), '!mailto' => $values['mail'], '!first_name' => $first_name, '!last_name' => $last_name, '!code' => $hash); $params = array('variables' => $variables); $message = drupal_mail('ldapprov', 'code', $values['mail'], $language, $params); if ($message['result']) { watchdog('ldapprov', 'E-mail validation request mailed to %first_name %last_name at %mail.', array('%first_name' => $first_name, '%last_name' => $last_name, '%mail' => $values['mail'])); drupal_set_message(t('An e-mail has been sent to the e-mail account %s to verify that you have entered a valid e-mail address.', array('%s' => $values['mail']))); } else { watchdog('ldapprov', 'Error mailing e-mail validation request to %first_name %last_name at %mail.', array('%first_name' => $first_name, '%last_name' => $last_name, '%mail' => $values['mail']), WATCHDOG_ERROR); drupal_set_message(t('Unable to send mail. Please contact the site admin.'), 'error'); } $form_state['redirect'] = 'user/validate'; } } /** * Creats a secret hash. * * @param $string * A string to calculate hash from. * @param $seed * A seed to salt the hash. * * @return * The hash. */ function _ldapprov_hash($string, $seed) { return md5($string . $seed); } ////////////////////////////////////////////////////////////////////////////// // Secret code validateion /** * Code validation form. * * @param $form_state * A form state array. * @param $code * A secret mail validation code. * * @return * A form array if there is no code. */ function ldapprov_code(&$form_state, $code = NULL) { // The code is passed as argument when clicking a link in the validation e-mail. if ($code) { if (!_ldapprov_code_validate(array('code' => $code))) { _ldapprov_code_submit(array('code' => $code)); drupal_goto('user'); } else { drupal_goto('user/validate'); } } // The code validation form. $form = array(); $form['code'] = array('#type' => 'textfield', '#title' => t('Secret Code'), '#size' => 50, '#maxlength' => 100, '#default_value' => $code, '#required' => TRUE, ); $form['submit'] = array('#type' => 'submit', '#value' => t('Validate')); return $form; } /** * Code validation form validation. */ function ldapprov_code_validate($form, &$form_state) { // Main code validation form validation. _ldapprov_code_validate($form_state['values']); } /** * Main code validation form validation. * * @param $values * A submitted data. * * @return * TRUE or FALSE depending if validation was passed. */ function _ldapprov_code_validate($values) { $code = trim($values['code']); $result = db_query("SELECT rid, status FROM {ldapprov} WHERE code = '%s'", $code); if ($row = db_fetch_object($result)) { if ($row->status > 0) { form_set_error('code', t('The code %s has already been validated.', array('%s' => $code))); return TRUE; } } else { form_set_error('code', t('The code %s is not valid.', array('%s' => $code))); return TRUE; } return FALSE; } /** * Code validation form submission. */ function ldapprov_code_submit($form, &$form_state) { // Main code validation form submission. _ldapprov_code_submit($form_state['values']); $form_state['redirect'] = 'user'; } /** * Main code validation form submission. * * @param $values * A submitted data. * * @return */ function _ldapprov_code_submit($values) { $code = trim($values['code']); $result = db_query("SELECT * FROM {ldapprov} WHERE code = '%s' AND status = '0'", $code); if ($row = db_fetch_object($result)) { // Check if users should be approved. if (variable_get('user_register', 1) == 2) { // User approval is needed. $time = time(); db_query("UPDATE {ldapprov} SET status = '1' WHERE code = '%s'", $code); // Mail the user managers about the new request. $variables = array('!mailto' => $row->mail, '!first_name' => $row->first_name, '!last_name' => $row->last_name); $result = db_query("SELECT DISTINCT u.uid FROM {users} u INNER JOIN {users_roles} ur ON u.uid = ur.uid INNER JOIN {permission} p ON ur.rid = p.rid WHERE p.perm LIKE '%%%s%%'", LDAPPROV_PERMISSION); while ($row2 = db_fetch_object($result)) { $account = user_load($row2->uid); $variables['!create_url'] = url('admin/user/accounts/pending/create/'. $row->rid, array('absolute' => TRUE, 'language' => user_preferred_language($account))); $params = array('account' => $account, 'variables' => $variables); $message = drupal_mail('ldapprov', 'notify', $account->mail, user_preferred_language($account), $params); if ($message['result']) { watchdog('ldapprov', 'E-mail notification message about %first_name %last_name account request mailed to %mail.', array('%first_name' => $row->first_name, '%last_name' => $row->last_name, '%mail' => $account->mail)); } else { watchdog('ldapprov', 'Error mailing notification e-mail about %first_name %last_name account request mailed to %mail.', array('%first_name' => $row->first_name, '%last_name' => $row->last_name, '%mail' => $account->mail), WATCHDOG_EROR); } } drupal_set_message(t('Your e-mail account %mail has been validated. Please wait until your account is approved. You will receive login information to your e-mail account.', array('%mail' => $row->mail))); } else { // User approval is not needed, account is created. // Only default role can be assigned this way. unset($values['roles']); if (is_array(unserialize($row->data))) { foreach (unserialize($row->data) as $k => $v) { $values[$k] = $v; } } $values['rid'] = $row->rid; $values['name'] = $row->name; $values['first_name'] = $row->first_name; $values['last_name'] = (!empty($row->last_name)) ? $row->last_name : $row->name; $values['mail'] = $row->mail; $account = _ldapprov_create_user($values); if (is_object($account)) { drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.')); if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE) { _ldapprov_content_profile_create($account, $values); } } else { drupal_set_message(t('The new user was not created. Please contact site administrator.'), 'error'); } } } else { drupal_set_message(t('The code %code is not valid or has expired.', array('%code' => $code)), 'error'); } } ////////////////////////////////////////////////////////////////////////////// // Account management /** * List account requests. * * @param $status * The tab clicked. * * @return * A HTML page. */ function ldapprov_list($status = 'pending') { $page = drupal_get_form('ldapprov_list_form', $status); // Print batch users upload form. if ($status == 'pending') { $page .= drupal_get_form('ldapprov_attach'); } return $page; } /** * List account requests form. * * @param $form_state * A form state array. * @param $tab * A tab clicked. * * @return * A form array. */ function ldapprov_list_form(&$form_state, $tab) { // Possible $status values are. // unverified(0), pending(1), rejected(2), created(3), deleted(4). $tabs = array('unverified', 'pending', 'rejected', 'created', 'deleted'); $status = array_search($tab, $tabs); // Action options. if ($status != 3) { $form['options'] = array('#type' => 'fieldset', '#title' => t('Update options')); if (module_exists('og')) { $og_types = array(OG_OPEN, OG_MODERATED); $result = db_query('SELECT og.nid, n.title FROM {og} og JOIN {node} n ON og.nid = n.nid WHERE og.og_selective IN ('. db_placeholders($og_types) .') ORDER BY n.title', $og_types); while ($row = db_fetch_object($result)) { $groups[$row->nid] = ''. t('Join %group.', array('%group' => $row->title)) .''; } if (!empty($groups)) { $script = ''; if (module_exists('og_mandatory_group') && ($mandatory_group = variable_get('og_mandatory_group', 0)) && $mandatory_group > 0 && in_array($mandatory_group, array_keys($groups))) { $script .= '$("#edit-og-groups-'. $mandatory_group .'").attr("checked", true).attr("disabled", true);'; } $script = empty($script) ? '' : ''; $form['options']['og'] = array('#type' => 'fieldset', '#title' => t('Groups'), '#collapsible' => TRUE, '#collapsed' => TRUE); $form['options']['og']['og_groups'] = array( '#type' => 'checkboxes', '#title' => t('Groups'), '#options' => $groups, '#description' => t('Join users to these groups on account creation.'), '#suffix' => $script, ); } } if (module_exists('signup') && ($nids = _ldapprov_get_signup_nodes()) && !empty($nids)) { $form['options']['signup'] = array('#type' => 'fieldset', '#title' => t('Signups'), '#collapsible' => TRUE, '#collapsed' => TRUE); $form['options']['signup']['signups'] = array( '#type' => 'checkboxes', '#title' => t('Signups'), '#options' => $nids, '#description' => t('Signup users to these nodes on account creation.'), ); } $options = array(); $options['create'] = t('Create the selected users'); if ($status < 2) { $options['reject'] = t('Reject the selected users'); } $form['options']['operation'] = array( '#type' => 'select', '#options' => $options, '#default_value' => 'create', '#prefix' => '
', ); $form['options']['submit'] = array( '#type' => 'submit', '#value' => t('Update'), '#suffix' => '
', ); } // Requests list. $header[] = array('data' => t('Submission Date'), 'field' => 'registered', 'sort' => 'desc'); if (LDAPPROV_ALLOW_USERNAME || $status == 4) { $header[] = array('data' => t('Username'), 'field' => 'name'); } $header[] = array('data' => t('First Name'), 'field' => 'first_name'); $header[] = array('data' => t('Last Name'), 'field' => 'last_name'); $header[] = array('data' => t('E-Mail'), 'field' => 'mail'); if (module_exists('ldapprov_invite') && LDAPPROV_INVITE_ENABLED) { $header[] = array('data' => t('Inviter')); } if ($status > 1) { $header[] = array('data' => t('Approval Date'), 'field' => 'approved'); $header[] = array('data' => t('Approver'), 'field' => 'name_c'); } if ($status == 3) { $header[] = array('data' => t('Account'), 'field' => 'name_u'); } $form['header']['#value'] = $header; if (in_array($status, array(1, 2, 4))) { // Accounts are not created. $sql = "SELECT l.*, u.name AS name_c FROM {ldapprov} l LEFT JOIN {users} u ON l.cuid = u.uid WHERE l.status = %d"; $query_count = "SELECT COUNT(l.rid) FROM {ldapprov} l LEFT JOIN {users} u ON l.cuid = u.uid WHERE l.status = %d"; } elseif ($status == 3) { // Accounts are created. $sql = "SELECT l.*, u.name AS name_c, u2.name AS name_u FROM {ldapprov} l INNER JOIN {users} u2 ON l.uid = u2.uid LEFT JOIN {users} u ON l.cuid = u.uid WHERE l.status = %d"; $query_count = "SELECT COUNT(l.rid) FROM {ldapprov} l INNER JOIN {users} u2 ON l.uid = u2.uid LEFT JOIN {users} u ON l.cuid = u.uid WHERE l.status = %d"; } else { // Account requests with unverified e-mails. $sql = "SELECT l.* FROM {ldapprov} l WHERE status = %d"; $query_count = "SELECT COUNT(l.rid) FROM {ldapprov} l WHERE status = %d"; } $result = pager_query($sql . tablesort_sql($header), LDAPPROV_MAX_LIST_ENTRIES, 0, $query_count, $status); $requests = array(); while ($row = db_fetch_object($result)) { $requests[$row->rid] = ''; $data = unserialize($row->data); $form['registered'][$row->rid] = array('#value' => l(format_date($row->registered, LDAPPROV_DATE_FORMAT), 'admin/user/accounts/'. $tab .'/create/'. $row->rid)); if (LDAPPROV_ALLOW_USERNAME || $status == 4) { $form['name'][$row->rid] = array('#value' => check_plain($row->name)); } $form['first_name'][$row->rid] = array('#value' => check_plain($row->first_name)); $form['last_name'][$row->rid] = array('#value' => check_plain($row->last_name)); $form['mail'][$row->rid] = array('#value' => check_plain($row->mail)); if (module_exists('ldapprov_invite') && LDAPPROV_INVITE_ENABLED) { $inviters = array(); foreach (module_invoke('ldapprov_invite', 'ldapinvites', $row->rid) as $entry) { $inviters[] = theme('username', user_load($entry->uid)); } $form['inviter'][$row->rid] = array('#value' => !empty($inviters) ? implode(', ', $inviters) : ''); } if ($status > 1) { $form['approved'][$row->rid] = array('#value' => format_date($row->approved, LDAPPROV_DATE_FORMAT)); $form['name_c'][$row->rid] = isset($row->name_c) ? array('#value' => theme('username', user_load($row->cuid))) : array('#value' => $row->cname); } if ($status == 3) { // Set username. $form['name_u'][$row->rid] = array('#value' => theme('username', user_load($row->uid))); } } if ($status != 3) { $form['requests'] = array( '#type' => 'checkboxes', '#options' => $requests ); } $form['status'] = array( '#type' => 'hidden', '#value' => $status ); $form['#validate'][] = 'ldapprov_list_validate'; $form['#submit'][] = 'ldapprov_list_submit'; $form['pager'] = array('#value' => theme('pager', NULL, LDAPPROV_MAX_LIST_ENTRIES, 0)); return $form; } /** * List account requests form validation. */ function ldapprov_list_validate($form, &$form_state) { if (module_exists('signup')) { _ldapprov_signup_validate($form, $form_state); } } /** * List account requests form submission. */ function ldapprov_list_submit($form, &$form_state) { $values = $form_state['values']; $values['requests'] = array_values(array_filter($values['requests'])); $register_form_state = array(); $register_form = drupal_retrieve_form('ldapprov_register', $register_form_state); switch ($values['operation']) { case 'create': $batch = array( 'operations' => array( array('ldapprov_user_create_batch_process', array($values['requests'], $register_form)), ), 'finished' => 'ldapprov_user_create_batch_finished', 'title' => t('Processing user creation'), 'init_message' => t('User creation is starting.'), 'progress_message' => t('Processing...'), 'error_message' => t('User creation has encountered an error.'), ); batch_set($batch); break; case 'reject': foreach ($values['requests'] as $rid) { _ldapprov_reject_user(array('rid' => $rid)); } break; } } /** * Batch Operation Callback. */ function ldapprov_user_create_batch_process($requests, &$form, &$context) { if (!isset($context['sandbox']['progress'])) { $context['sandbox']['progress'] = 0; $context['sandbox']['max'] = count($requests); } if ($context['sandbox']['max'] > 0) { $result = db_query("SELECT * FROM {ldapprov} WHERE rid = %d", $requests[$context['sandbox']['progress']]); $row = db_fetch_object($result); $data = unserialize($row->data); $data['rid'] = $row->rid; $data['name'] = $row->name; $data['first_name'] = $row->first_name; $data['last_name'] = $row->last_name; $data['mail'] = $row->mail; $data['og_groups'] = isset($values['og_groups']) ? $values['og_groups'] : array(); $data['signups'] = isset($values['signups']) ? $values['signups'] : array(); // Validate the data. // Validate using common validation function. $errors = _ldapprov_register_validate($data, FALSE); // Check required fields. foreach ($data as $key => $val) { if (!isset($val) || $val == '') { $errors += _ldapprov_check_required($form, $key); } } // Check if the user with the same name already created in the system. if (!LDAPPROV_ALLOW_USERNAME) { $name = _ldapprov_make_username($data['first_name'], $data['last_name']); $result = db_query("SELECT mail FROM {users} WHERE name = '%s'", $name); if ($row = db_fetch_object($result)) { $errors++; } else { // When ldap users are in sync with drupal users, ldap search is not needed. global $_ldapprov_ldap; $basedn = $_ldapprov_ldap->getOption('basedn'); $name_attr = $_ldapprov_ldap->getOption('user_attr') ? $_ldapprov_ldap->getOption('user_attr') : LDAP_DEFAULT_USER_ATTRIBUTE; if (!$_ldapprov_ldap->connect(LDAPPROV_DN, LDAPPROV_PASS)) { watchdog('ldapprov', 'User creation: user data could not be read in the LDAP directory. Could not bind as %dn.', array('%dn' => LDAPPROV_DN), WATCHDOG_ERROR); drupal_set_message(t('User creation: user data could not be read in the LDAP directory. Please contact site administrator.'), 'error'); } if ($ret = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name .')', array('mail'))) { $errors++; } $_ldapprov_ldap->disconnect(); } } if ($errors > 0) { $context['message'] = t('User with an e-mail address %mail was not created.', array('%mail' => $data['mail'])); $context['results'][1][] = $data['mail']; } else { // Create a new user. $new_user = _ldapprov_create_user($data); if (isset($new_user)) { $context['message'] = t('The new user !name has been created.', array('!name' => theme('username', $new_user))); $context['results'][0][] = theme('username', $new_user); if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE) { _ldapprov_content_profile_create($new_user, $data); } } else { $context['message'] = t('User with an e-mail address %mail was not created.', array('%mail' => $data['mail'])); $context['results'][1][] = $data['mail']; } } } if ($context['sandbox']['progress'] != $context['sandbox']['max']) { $context['finished'] = ++$context['sandbox']['progress'] / $context['sandbox']['max']; } } /** * Batch 'finished' callback. */ function ldapprov_user_create_batch_finished($success, $results, $operations) { if ($success) { if (empty($results)) { drupal_set_message(t('Please choose at least one request.'), 'warning'); } if (isset($results[0]) && count($results[0]) > 0) { drupal_set_message(t('Following users were created.') . theme('item_list', $results[0])); } if (isset($results[1]) && count($results[1]) > 0) { drupal_set_message(t('Users with the following e-mails were not created. Please create them manually.') . theme('item_list', $results[1]), 'error'); } } else { $error_operation = reset($operations); drupal_set_message(t('An error occurred while processing %error. Please contact site administrator.', array('%error' => $error_operation[0])), 'error'); } } /** * Check if a field is required in registration form. * Recursevle checks childrens. * * @param $form_element * An array of form element. * @param $name * A name of the element. * * @return * A number of required elements. */ function _ldapprov_check_required($form_element, $name) { $err = 0; if (is_array($form_element)) { foreach ($form_element as $key => $val) { if ($key === $name) { foreach ($val as $k => $v) { if ($k == '#required' && $val[$k] == 1) { $err++; } } } else { $err += _ldapprov_check_required($val, $name); } } } return $err; } /** * Retrieve a creation form. * * @param $form_state * A form state array. * @param $tab * A tab clicked. * @param $rid * A registration ID. * * @return * A form array. */ function ldapprov_create(&$form_state, $tab, $rid = NULL) { global $user; $tabs = array('unverified', 'pending', 'rejected', 'created', 'deleted'); $status = $tab == 'new' ? NULL : array_search($tab, $tabs); if (isset($status) && is_numeric($rid)) { if ($status == 2 || $status == 4) { // Account rejected or deleted. $result = db_query("SELECT l.*, u.name AS cname FROM {ldapprov} l INNER JOIN {users} u ON l.cuid = u.uid WHERE l.rid = %d", $rid); } elseif ($status == 3) { // Account is created but we print out registration data. $result = db_query("SELECT l.*, u.name AS cname, u2.name AS name_u FROM {ldapprov} l INNER JOIN {users} u ON l.cuid = u.uid INNER JOIN {users} u2 ON l.uid = u2.uid WHERE l.rid = %d", $rid); } else { // Account is pending. $result = db_query("SELECT l.* FROM {ldapprov} l WHERE l.rid = %d", $rid); } if ($data = db_fetch_array($result)) { $data['data'] = unserialize($data['data']); $data = array_merge(is_array($data['data']) ? $data['data'] : array(), $data); } } $data = isset($data) ? $data : array(); $form['language'] = array( '#type' => 'hidden', '#value' => isset($data['language']) ? $data['language'] : '', ); // Invite information. if (module_exists('ldapprov_invite') && LDAPPROV_INVITE_ENABLED && $rid) { foreach (module_invoke('ldapprov_invite', 'ldapinvites', $rid) as $entry) { $invites[$entry->iid] = array( '#value' => '
'. t('Invited by !name', array('!name' => theme('username', user_load($entry->uid)))) . (!empty($entry->data) ? t(', context: !context.', array('!context' => $entry->data['string'])) : '.') .'
', ); } if (!empty($invites)) { $form['invite'] = array_merge(array('#type' => 'fieldset', '#title' => t('Invitations'), '#collapsible' => FALSE, '#collapsed' => FALSE, '#weight' => '0'), $invites); } } // Main registration form. $form = array_merge($form, _ldapprov_register_form($data, $status == 3 ? TRUE : FALSE)); // Password field. if (LDAPPROV_PASS_ENABLE) { $form['account']['password'] = array( '#type' => 'password', '#title' => t('Password'), '#description' => t('Leave this field empty and the password will be autogenerated.'), '#default_value' => '', '#weight' => 10, '#disabled' => $status == 3 ? TRUE : FALSE, ); } // OG integration. if (module_exists('og')) { $og_types = array(OG_OPEN, OG_MODERATED); $result = db_query('SELECT og.nid, n.title FROM {og} og JOIN {node} n ON og.nid = n.nid WHERE og.og_selective IN ('. db_placeholders($og_types) .') ORDER BY n.title', $og_types); while ($row = db_fetch_object($result)) { $groups[$row->nid] = ''. t('Join %group.', array('%group' => $row->title)) .''; } if (!empty($groups)) { $script = ''; $groups_disabled = array(); if (module_exists('ldapprov_invite') && LDAPPROV_INVITE_ENABLED && $rid) { foreach (module_invoke('ldapprov_invite', 'ldapinvites', $rid) as $entry) { if ($entry->data['type'] == 'og' && !in_array($entry->data['gid'], $groups_disabled)) { $groups_disabled[] = $entry->data['gid']; $script .= '$("#edit-!name-'. $entry->data['gid'] .'").attr("checked", true).attr("disabled", true);'; } } } if (module_exists('og_mandatory_group') && ($mandatory_group = variable_get('og_mandatory_group', 0)) && $mandatory_group > 0 && in_array($mandatory_group, array_keys($groups)) && !in_array($mandatory_group, $groups_disabled)) { $groups_disabled[] = $mandatory_group; $script .= '$("#edit-!name-'. $mandatory_group .'").attr("checked", true).attr("disabled", true);'; } $script = empty($script) ? '' : ''; if (isset($form['og_register'])) { foreach (array_keys($form['og_register']['og_register']['#options']) as $key) { if (!in_array($key, array_keys($groups))) { $groups[$key] = $form['og_register']['og_register']['#options'][$key]; } } $form['og_register']['og_register']['#options'] = $groups; $form['og_register']['og_register']['#suffix'] = strtr($script, array('!name' => 'og-register')); } else { $form['options']['og'] = array('#type' => 'fieldset', '#title' => t('Groups'), '#collapsible' => TRUE, '#collapsed' => TRUE); $form['options']['og']['og_groups'] = array( '#type' => 'checkboxes', '#title' => t('Groups'), '#options' => $groups, '#default_value' => isset($data['og_groups']) ? $data['og_groups'] : array(), '#description' => t('Join users to these groups on account creation.'), '#suffix' => strtr($script, array('!name' => 'og-groups')), '#disabled' => $status == 3 ? TRUE : FALSE, ); } } } // Signup integration. if (module_exists('signup') && ($nids = _ldapprov_get_signup_nodes()) && !empty($nids)) { $form['options']['signup'] = array('#type' => 'fieldset', '#title' => t('Signups'), '#collapsible' => TRUE, '#collapsed' => TRUE); $form['options']['signup']['signups'] = array( '#type' => 'checkboxes', '#title' => t('Signups'), '#options' => $nids, '#description' => t('Signup users to these nodes on account creation.'), '#disabled' => $status == 3 ? TRUE : FALSE, ); } // Get all roles except authenticated user. $roles = user_roles(1); unset($roles[DRUPAL_AUTHENTICATED_RID]); // Integration with role assign module. if (module_exists('roleassign')) { // Get roles that are available for assignment. $assignable_roles = _roleassign_assignable_roles($roles); } if (((user_access(LDAPPROV_ROLE_PERMISSION) && $roles) || user_access('assign roles') && isset($assignable_roles) && !empty($assignable_roles)) && $status != 3) { $form['ldapprov_roles'] = array( '#type' => 'fieldset', '#title' => t('Roles'), '#collapsible' => FALSE, '#collapsed' => FALSE, '#weight' => '3', ); $roles_available = (user_access(LDAPPROV_ROLE_PERMISSION)) ? $roles : $assignable_roles; $form['ldapprov_roles']['roles'] = array( '#type' => 'checkboxes', '#title' => t('Roles'), '#default_value' => isset($data['roles']) ? array_keys((array)$data['roles']) : array(), '#options' => $roles_available, '#description' => t('The user receives the combined permissions of the %au role, and all roles selected here.', array('%au' => t('authenticated user'))) ); } if ($status != 3) { // Account is not yet created. $form['ldapprov_messages'] = array('#type' => 'fieldset', '#title' => t('Messages'), '#collapsible' => FALSE, '#collapsed' => FALSE, '#weight' => '4'); $form['ldapprov_messages']['message'] = array( '#type' => 'textarea', '#title' => t('Message'), '#rows' => 5, '#description' => t('This message will be added to the notification e-mail sent out.'), '#default_value' => isset($data['message']) ? $data['message'] : NULL, ); } $form['ldapprov_notes'] = array('#type' => 'fieldset', '#title' => t('Notes'), '#collapsible' => FALSE, '#collapsed' => FALSE, '#weight' => '5'); $form['ldapprov_notes']['notes'] = array( '#type' => 'textarea', '#title' => t('Notes'), '#rows' => 5, '#description' => t('Internal notes shared between account managers.'), '#default_value' => isset($data['notes']) ? $data['notes'] : NULL, ); $form['rid'] = array( '#type' => 'hidden', '#value' => $rid, ); if ($status != 3) { // Don't print create button for already created requests. $form['create'] = array( '#type' => 'submit', '#value' => t('Create account'), '#weight' => 10 ); } if ($rid && $status < 2) { // Reject button only for pending accounts. $form['reject'] = array( '#type' => 'submit', '#value' => t('Reject account'), '#weight' => 11 ); } if ($rid) { $form['save'] = array( '#type' => 'submit', '#value' => t('Save notes'), '#weight' => 12 ); } // Print account status history messages. if (empty($form_state['post'])) { if ($status == 2) { drupal_set_message(t('The request was rejected at %date by !name.', array('%date' => format_date($data['approved'], LDAPPROV_DATE_FORMAT), '!name' => theme('username', user_load($data['cuid']))))); } elseif ($status == 3) { drupal_set_message(t('The user !name was created at %date by !cname.', array('!name' => theme('username', user_load($data['uid'])), '%date' => format_date($data['approved'], LDAPPROV_DATE_FORMAT), '!cname' => theme('username', user_load($data['cuid']))))); } elseif ($status == 4) { drupal_set_message(t('The account was deleted at %date by !name.', array('%date' => format_date($data['approved'], LDAPPROV_DATE_FORMAT), '!name' => theme('username', user_load($data['cuid']))))); } // Prints a message if a user with this username already exists in the system when the form is rendered. if ($status != 3 && !LDAPPROV_ALLOW_USERNAME && isset($data['first_name']) && isset($data['last_name'])) { $name = _ldapprov_make_username($data['first_name'], $data['last_name']); $result = db_query("SELECT mail FROM {users} WHERE name = '%s'", $name); if ($row = db_fetch_object($result)) { drupal_set_message(t('An account with a username %name and e-mail %mail is already created in the system. If you proceed, a new account will be created with a number appended to the username.', array('%name' => $name, '%mail' => $row->mail)), 'error'); } else { // When ldap users are in sync with drupal users, ldap search is not needed. global $_ldapprov_ldap; $basedn = $_ldapprov_ldap->getOption('basedn'); $name_attr = $_ldapprov_ldap->getOption('user_attr') ? $_ldapprov_ldap->getOption('user_attr') : LDAP_DEFAULT_USER_ATTRIBUTE; if (!$_ldapprov_ldap->connect(LDAPPROV_DN, LDAPPROV_PASS)) { watchdog('ldapprov', 'User registration: user data could not be read in the LDAP directory. Could not bind as %dn.', array('%dn' => LDAPPROV_DN), WATCHDOG_ERROR); drupal_set_message(t('User registration: user data could not be read in the LDAP directory. Please contact site administrator.'), 'error'); } if ($ret = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name .')', array('mail'))) { drupal_set_message(t('An account with a username %name and e-mail %mail is already created in the system. If you proceed, a new account will be created with a number appended to the username.', array('%name' => $name, '%mail' => $ret[0]['mail'][0])), 'error'); } $_ldapprov_ldap->disconnect(); } } } return $form; } /** * User creation form validation. */ function ldapprov_create_validate($form, &$form_state) { $values = $form_state['values']; // Remember the tab. $status = 1; $tabs = array('unverified', 'pending', 'rejected', 'created', 'deleted'); if (isset($values['rid'])) { $result = db_query("SELECT rid, status FROM {ldapprov} WHERE rid = %d", $values['rid']); $row = db_fetch_object($result); $status = $row->status; } $form_state['values']['status'] = $status; // Main registration form validation. if ($values['op'] == t('Create account')) { _ldapprov_register_validate($form_state['values']); if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE) { content_profile_registration_user_register_validate($form, $form_state); } if (module_exists('signup')) { _ldapprov_signup_validate($form, $form_state); } } } /** * User creation form submission. */ function ldapprov_create_submit($form, &$form_state) { $values = $form_state['values']; // Handle operations. if ($values['op'] == t('Reject account')) { _ldapprov_reject_user($values); } elseif ($values['op'] == t('Save notes')) { db_query("UPDATE {ldapprov} SET notes = '%s' WHERE rid = %d", $values['notes'], $values['rid']); drupal_set_message(t('The notes have been saved.')); } else { // Create a new user. $account = _ldapprov_create_user($values); if (is_object($account)) { drupal_set_message(t('The new user !name has been created.', array('!name' => theme('username', $account)))); if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE) { _ldapprov_content_profile_create($account, array(), $form, $form_state); } } else { drupal_set_message(t('The new user was not created. Please contact site administrator.'), 'error'); } } $tabs = array('unverified', 'pending', 'rejected', 'created', 'deleted'); $form_state['redirect'] = 'admin/user/accounts/'. $tabs[$values['status']]; } ////////////////////////////////////////////////////////////////////////////// // User creation /** * User creation in LDAP and drupal. * * @param $data * An array of the submitted data. * * @return * A created user object. */ function _ldapprov_create_user($data) { global $user, $_ldapprov_ldap; // First and last names. if (module_exists('profile') && LDAPPROV_PROFILE && LDAPPROV_PROFILE_FIRST != '' && LDAPPROV_PROFILE_LAST != '') { $first_name = $data[LDAPPROV_PROFILE_FIRST]; $last_name = $data[LDAPPROV_PROFILE_LAST]; } else if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE && LDAPPROV_CONTENT_PROFILE_FIRST != '' && LDAPPROV_CONTENT_PROFILE_LAST != '') { $first_name = $data[LDAPPROV_CONTENT_PROFILE_FIRST]; $last_name = $data[LDAPPROV_CONTENT_PROFILE_LAST]; } else { $first_name = $data['first_name']; $last_name = $data['last_name']; } $first_name = is_array($first_name) ? $first_name[0]['value'] : $first_name; $last_name = is_array($last_name) ? $last_name[0]['value'] : $last_name; if (LDAPPROV_ALLOW_USERNAME) { $name = $data['name']; } else { $name = _ldapprov_make_username($first_name, $last_name); } if (!$_ldapprov_ldap->connect(LDAPPROV_DN, LDAPPROV_PASS)) { watchdog('ldapprov', 'User creation: user data could not be read in the LDAP directory. Could not bind as %dn.', array('%dn' => LDAPPROV_DN), WATCHDOG_ERROR); drupal_set_message(t('Error! User data could not be read in the LDAP directory. Please contact site administrator.'), 'error'); return; } $basedn = $_ldapprov_ldap->getOption('basedn'); $name_attr = $_ldapprov_ldap->getOption('user_attr') ? $_ldapprov_ldap->getOption('user_attr') : LDAP_DEFAULT_USER_ATTRIBUTE; if ($ret = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name .')', array($name_attr)) || user_load(array('name' => $name))) { $i = 1; while ($ret = $_ldapprov_ldap->search($basedn, '('. $name_attr .'='. $name . $i .')', array($name_attr)) || user_load(array('name' => $name . $i))) { $i++; } $name = $name . $i; } // ldapauth defines if we use md5 for ldap passwords. $pass = !empty($data['password']) ? $data['password'] : user_password(LDAPPROV_PASS_LENGTH); $pass_ldap = $_ldapprov_ldap->getOption('encrypted') ? '{md5}'. base64_encode(pack('H*', md5($pass))) : $pass; $ldap_vars['!uid'] = $name; $ldap_vars['!base_dn'] = $_ldapprov_ldap->getOption('basedn'); $ldap_vars['!mail'] = $data['mail']; $ldap_vars['!first_name'] = $first_name; $ldap_vars['!last_name'] = $last_name; $ldap_vars['!pass'] = $pass_ldap; $dn = $name_attr .'='. $name .','. $basedn; // Construct main user ldif entry. foreach (explode("\n", LDAPPROV_USER_ENTRY) as $line) { $line = str_replace("\r", '', $line); if (preg_match('/^\s*$/', $line)) continue; if (preg_match('/^#.*$/', $line)) continue; list($attr, $var) = explode(': ', $line); $ldif_var = strtr($var, $ldap_vars); if (!empty($ldif_var)) { $ldif[$attr][] = $ldif_var; } } $server = _ldapprov_get_server(); // Create writable attributes from ldapdata. if (module_exists('ldapdata')) { $ldapdata_attributes = _ldapdata_ldap_info($server->sid, 'ldapdata_attrs'); $ldapdata_options = variable_get('ldapprov_ldapdata', array()); foreach (_ldapdata_ldap_info($server->sid, 'ldapdata_rwattrs') as $attribute) { if ($attr_info = $ldapdata_attributes[$attribute]) { // if this attribute should be shown ir registration. if (isset($ldapdata_options[$attribute]) && $ldapdata_options[$attribute] > 0 && !empty($data['ldap_'. $attribute])) { $ldif[$attribute][] = strtr($data['ldap_'. $attribute], $ldap_vars); } } } } // Print ldif if debugging is enabled. if (LDAPPROV_DEBUG) { $ldif_out = "dn: $dn
"; foreach ($ldif as $key => $val) { foreach ($val as $k => $v) { $ldif_out .= "$key: $v
"; } } drupal_set_message($ldif_out); } // Create user in LDAP. if ($_ldapprov_ldap->create_entry($dn, $ldif)) { // Enter profile data. $account_profile = array(); if (module_exists('profile') && LDAPPROV_PROFILE && module_exists('ldapdata')) { $result = db_query("SELECT * FROM {profile_fields}"); while ($row = db_fetch_object($result)) { $profile[$row->name] = $row->fid; } $ldapdata_mappings = _ldapdata_ldap_info($server->sid, 'ldapdata_mappings'); foreach ($data as $key => $value) { if (preg_match('/^profile_/', $key) && isset($profile[$key]) && isset($data[$key])) { if (isset($ldapdata_mappings['ldap_amap-'. $profile[$key]]) && ($ldap_profile = $ldapdata_mappings['ldap_amap-'. $profile[$key]])) { // drupal profile will be sync with ldap on the next load. $ldap_profile_ldif[$ldap_profile][] = $data[$key]; } $account_profile[$key] = $data[$key]; } } // Profile to ldap mapping. if (isset($ldap_profile_ldif)) { $_ldapprov_ldap->writeAttributes($dn, $ldap_profile_ldif); } } // Proceed with a Drupal user only if LDAP user is created successfully. // Set user roles. $roles = array(); if ((user_access(LDAPPROV_ROLE_PERMISSION) || user_access('assign roles')) && isset($data['roles'])) { $roles = $data['roles']; foreach ($roles as $key => $value) { if ($value == 0) { unset($roles[$key]); } } } // Create a drupal user. $account = user_save('', array_merge(array('name' => $name, 'pass' => $pass, 'mail' => $data['mail'], 'init' => $data['mail'], 'status' => 1, 'authname_ldapauth' => $name, 'roles' => $roles, 'ldap_authentified' => TRUE, 'ldap_dn' => $dn, 'ldap_config' => LDAPPROV_SERVER), isset($data['language']) ? array('language' => $data['language']) : array(), $account_profile)); watchdog('ldapprov', 'A new external user %name was created using module %module.', array('%name' => $name, '%module' => 'ldapprov'), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit')); $time = time(); if ($user->uid == 0) { // Registration without approval. db_query("UPDATE {ldapprov} SET status = '3', cuid = %d, approved = %d, uid = %d WHERE rid = %d", $account->uid, $time, $account->uid, $data['rid']); } elseif ($data['rid']) { // Manager is approving request. db_query("UPDATE {ldapprov} SET status = '3', cuid = %d, approved = %d, uid = %d, notes = '%s' WHERE rid = %d", $user->uid, $time, $account->uid, isset($data['notes']) ? $data['notes'] : NULL, $data['rid']); } else { // User is created from the account manager interface. db_query("INSERT INTO {ldapprov} (name, mail, first_name, last_name, status, registered, data, approved, cuid, uid, notes) VALUES ('%s', '%s', '%s', '%s', '3', %d, '%s', %d, %d, %d, '%s')", isset($data['name']) ? $data['name'] : NULL, $data['mail'], $first_name, $last_name, $time, serialize($data), $time, $user->uid, $account->uid, $data['notes']); } // Mail one time login URL and instructions. $variables = array('!mailto' => $data['mail'], '!first_name' => $first_name, '!last_name' => $last_name, '!username' => $name, '!password' => $pass, '!message' => isset($data['message']) ? $data['message'] : NULL); $params = array('account' => $account, 'variables' => $variables); $message = drupal_mail('ldapprov', 'create', $account->mail, user_preferred_language($account), $params); if ($message['result']) { watchdog('ldapprov', 'Account creation notification e-mail mailed to %name at %mail.', array('%name' => $name, '%mail' => $data['mail'])); } else { watchdog('ldapprov', 'Error mailing account creation notification to %name at %mail.', array('%name' => $name, '%mail' => $data['mail']), WATCHDOG_ERROR); } // OG integration. if (module_exists('og')) { $og_register = isset($data['og_register']) ? array_filter($data['og_register']) : array(); $og_groups = isset($data['og_groups']) ? array_filter($data['og_groups']) : array(); foreach (array_merge($og_register, $og_groups) as $gid) { $return = og_subscribe_user($gid, $account); } } // Signup integration if (module_exists('signup') && user_access('sign up for content', $account) && isset($data['signups'])) { foreach (array_filter($data['signups']) as $nid) { signup_sign_up_user(array('nid' => $nid, 'uid' => $account->uid)); if (module_exists('signup_status')) { $sid = db_last_insert_id('signup_log', 'sid'); _signup_status_change('insert', (object)array('sid' => $sid, 'uid' => $account->uid, 'nid' => $nid, 'anon_mail' => '', 'status' => SIGNUP_STATUS_INVITE_STATUS)); } } } // Execute additional create hooks. $account->clear_pass = $pass; if ($data['rid']) $account->rid = $data['rid']; module_invoke_all('ldapuser', $account); } else { // User creation in LDAP failed. watchdog('ldapprov', 'User creation: user was not created in the LDAP directory.', array(), WATCHDOG_ERROR); } $_ldapprov_ldap->disconnect(); return isset($account) ? $account : NULL; } /** * Creates username from the configuration template. * * @param $first * A first name. * @param $last * A last name. * * @return * A constructed username. */ function _ldapprov_make_username($first, $last) { $first = drupal_strtolower($first); $first = preg_replace('/\'/', '', $first); $first = preg_replace('/\s+/', '-', $first); $last = drupal_strtolower($last); $last = preg_replace('/\'/', '', $last); $last = preg_replace('/\s+/', '-', $last); $name = LDAPPROV_USERNAME; if (preg_match('/%f\d+/', $name)) { $no = $name; $no = preg_replace('/.*%f(\d+).*/', '\1', $no); $name = preg_replace('/%f\d+/', drupal_substr($first, 0, $no--), $name); } elseif (preg_match('/%f/', $name)) { $name = preg_replace('/%f/', $first, $name); } if (preg_match('/%l\d+/', $name)) { $no = $name; $no = preg_replace('/.*%l(\d+).*/', '\1', $no); $name = preg_replace('/%l\d+/', drupal_substr($last, 0, $no--), $name); } elseif (preg_match('/%l/', $name)) { $name = preg_replace('/%l/', $last, $name); } return $name; } ////////////////////////////////////////////////////////////////////////////// // User rejection /** * User rejection in LDAP and Drupal. * * @param $data * A submitted data, * * @return */ function _ldapprov_reject_user($data) { global $user; $time = time(); db_query("UPDATE {ldapprov} SET status = '2', cuid = %d, approved = %d WHERE rid = %d", $user->uid, $time, $data['rid']); if (isset($data['notes'])) { // We don't want to delete existing notes, so update them on separate update. db_query("UPDATE {ldapprov} SET notes = '%s' WHERE rid = %d", $data['notes'], $data['rid']); } $result = db_query("SELECT rid, mail, first_name, last_name FROM {ldapprov} WHERE rid = %d", $data['rid']); $row = db_fetch_object($result); drupal_set_message(t('The account request for %first %last (%mail) has been rejected.', array('%first' => $row->first_name, '%last' => $row->last_name, '%mail' => $row->mail))); // Mail the user about rejection. $variables = array('!mailto' => $row->mail, '!first_name' => $row->first_name, '!last_name' => $row->last_name, '!message' => isset($data['message']) ? $data['message'] : NULL); $params = array('variables' => $variables); $message = drupal_mail('ldapprov', 'reject', $row->mail, language_default(), $params); if ($message['result']) { watchdog('ldapprov', 'E-mail rejection message mailed to %first_name %last_name at %mail.', array('%first_name' => $row->first_name, '%last_name' => $row->last_name, '%mail' => $row->mail)); } else { watchdog('ldapprov', 'Error mailing rejection e-mail to %first_name %last_name at %mail.', array('%first_name' => $row->first_name, '%last_name' => $row->last_name, '%mail' => $row->mail), WATCHDOG_ERROR); } } ////////////////////////////////////////////////////////////////////////////// // Profile API /** * Print profile fields marked for registration. * * @param $edit * A submitted data. * @param $disabled * A flag saying if the form elements should be disabled. * * @return * A form array. */ function _ldapprov_profile_form($edit, $disabled = FALSE) { $form = profile_form_profile($edit, NULL, NULL, TRUE); if ($disabled) { foreach ($form as $cat => $category) { foreach ($category as $field => $data) { if (is_array($data)) { $form[$cat][$field]['#disabled'] = TRUE; $form[$cat][$field]['#required'] = FALSE; } } } } return $form; } ////////////////////////////////////////////////////////////////////////////// // Content profile integration /** * Print content profile fields marked for registration. * * @param $edit * A submitted data. * @param $disabled * A flag saying if the form elements should be disabled. * * @return * A form array. */ function _ldapprov_content_profile_form($edit, $disabled = FALSE) { $form = array(); $form_state = array(); foreach ($edit as $name => $value) { if (preg_match('/^field_/', $name)) { $form_state['values'][$name] = $value; } } content_profile_registration_form_alter($form, $form_state, 'user_register'); unset($form['#validate']); unset($form['#submit']); if ($disabled) { _ldapprov_content_profile_disable($form); } return $form; } /** * Disables form elements so that they could not be altered. * * @param $form * A reference to a form array. */ function _ldapprov_content_profile_disable(&$form) { foreach ($form as $name => $field) { if (preg_match('/^group_/', $name) and is_array($form[$name])) { _ldapprov_content_profile_disable($form[$name]); } if (preg_match('/^field_/', $name) and is_array($form[$name])) { if (isset($form[$name][0])) { foreach ($form[$name] as $key => $val) { if (is_numeric($key) and is_array($form[$name][$key])) { // #disable does not work with the cck defined form types. //$form[$name][$key]['#disabled'] = TRUE; $form[$name][$key]['#suffix'] = ''; $form[$name][$key]['#required'] = FALSE; } } } else { $form[$name]['#suffix'] = ''; $form[$name]['#required'] = FALSE; } } } } /** * Create a content profile node from the submitted form or * from the saved data. * * @param $account * A user object. * @param $data * A saved data array. * @param $form * A form array. * @param $form_state * A form state array. * * @return */ function _ldapprov_content_profile_create($account, $data = array(), $form = array(), $form_state = array()) { if (!empty($data)) { foreach ($data as $name => $value) { if (preg_match('/^field_/', $name)) { $form_state['values'][$name] = $value; } } content_profile_registration_form_alter($form, $form_state, 'user_register'); content_profile_registration_user_register_validate($form, $form_state); } $form_state['user'] = $account; content_profile_registration_user_register_submit($form, $form_state); if (LDAPPROV_NOTIFICATIONS_UNSUBSCRIBE && module_exists('notifications')) { global $user; $node = node_load(db_result(db_query('SELECT nid FROM {node} WHERE uid = %d', $account->uid))); if ($subscriptions = notifications_user_get_subscriptions($user->uid, 'node', $node->nid, $node)) { notifications_delete_subscription(reset($subscriptions)->sid); } } } ////////////////////////////////////////////////////////////////////////////// // File upload API /** * File upload form. * * @return * A form array. */ function ldapprov_attach() { $form = array('#attributes' => array('enctype' => 'multipart/form-data')); // Attachments fieldset. $form['attachments'] = array( '#type' => 'fieldset', '#title' => t('Upload accounts'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#description' => t('Upload users data in xml or csv format. The templates can be downloaded for the !xml or !csv formats', array('!xml' => l('xml', 'ldapprov/template/xml'), '!csv' => l('csv', 'ldapprov/template/csv'))), '#prefix' => '
', '#suffix' => '
', ); $form['attachments']['upload'] = array('#type' => 'file', '#title' => t('Attach new file'), '#size' => 40); $form['attachments']['action'] = array('#type' => 'submit', '#value' => 'Submit'); return $form; } /** * Handle file upload validate. */ function ldapprov_attach_validate($form, &$form_state) { // A file should be uploaded. $filename = $_FILES['files']['name']['upload']; if (empty($filename)) { form_set_error('upload', t('The file should be provided.')); } else { $ext = preg_replace('/^.*\.([^\.]+)$/', '$1', $filename); if (!in_array($ext, array('xml', 'csv'))) { form_set_error('upload', t('Unsupported file extension %ext.', array('%ext' => $ext))); } } } /** * Handle file upload submit. */ function ldapprov_attach_submit($form, &$form_state) { $file = file_save_upload('upload'); // Drupal adds .txt for unknown mime types. //$filename = preg_match('/\.txt$/', $file->filename) ? $filename = preg_replace('/\.txt$/', '', $file->filename) : $file->filename; _ldapprov_attach_file($file); file_delete($file->filepath); } /** * Parse the file and save data in the database. * * @param $file * A file object. * * @return */ function _ldapprov_attach_file($file) { global $user; preg_match('/[^\.]+$/', $file->filename, $matches); if (function_exists('_ldapprov_'. $matches[0] .'_parse')) { $data = call_user_func('_ldapprov_'. $matches[0] .'_parse', $file); if (is_array($data)) { $time = time(); foreach ($data as $account) { // First and last names. if (module_exists('profile') && LDAPPROV_PROFILE && LDAPPROV_PROFILE_FIRST != '' && LDAPPROV_PROFILE_LAST != '') { $account['first_name'] = $account[LDAPPROV_PROFILE_FIRST]; $account['last_name'] = $account[LDAPPROV_PROFILE_LAST]; } else if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE && LDAPPROV_CONTENT_PROFILE_FIRST != '' && LDAPPROV_CONTENT_PROFILE_LAST != '') { $account['first_name'] = $account[LDAPPROV_CONTENT_PROFILE_FIRST]; $account['last_name'] = $account[LDAPPROV_CONTENT_PROFILE_LAST]; } $account['first_name'] = is_array($account['first_name']) ? $account['first_name'][0]['value'] : $account['first_name']; $account['last_name'] = is_array($account['last_name']) ? $account['last_name'][0]['value'] : $account['last_name']; // Content profile data adjustment. foreach ($account as $k => $v) { if (preg_match('/^field_/', $k)) { $account[$k] = array(array('value' => $v, '_error_element' => $k .'][0][value')); } } db_query("INSERT INTO {ldapprov} (name, mail, first_name, last_name, status, registered, data, cuid) VALUES ('%s', '%s', '%s', '%s', '1', %d, '%s', %d)", isset($account['name']) ? $account['name'] : NULL, $account['mail'], $account['first_name'], $account['last_name'], $time, serialize($account), $user->uid); } drupal_set_message(t("The users data from the file %file has been uploaded.", array('%file' => $file->filename))); } else { drupal_set_message(t("Error: %error in file %file.", array('%error' => $data, '%file' => $file->filename)), 'error'); } } else { drupal_set_message(t("File %file has unsupported extension %extension.", array('%file' => $file->filename, '%extension' => $matches[0])), 'error'); } } /** * Prints batch upload template files. * * @param $type * A type - xml or csv. * * @return */ function _ldapprov_template($type) { if (!in_array($type, array('xml', 'csv'))) { drupal_not_found(); return; } header('Content-type: application/'. $type); header('Content-Disposition: attachment; filename="template.'. $type .'"'); $data = ((!module_exists('profile') || !LDAPPROV_PROFILE || LDAPPROV_PROFILE_FIRST == '' || LDAPPROV_PROFILE_LAST == '') && (!module_exists('content_profile_registration') || !LDAPPROV_CONTENT_PROFILE || LDAPPROV_CONTENT_PROFILE_FIRST == '' || LDAPPROV_CONTENT_PROFILE_LAST == '')) ? array('first_name' => t('First name') .' ('. t('required') .')', 'last_name' => t('Last name') .' ('. t('required') .')') : array(); $data['mail'] = t('E-mail') .' ('. t('required') .')'; if (LDAPPROV_ALLOW_USERNAME) { $data['name'] = t('Username') .' ('. t('required') .')'; } // Print writable ldap fields. if (module_exists('ldapdata')) { $server = _ldapprov_get_server(); $ldapdata_attributes = _ldapdata_ldap_info($server->sid, 'ldapdata_attrs'); $ldapdata_options = variable_get('ldapprov_ldapdata', array()); foreach (_ldapdata_ldap_info($server->sid, 'ldapdata_rwattrs') as $attribute) { if ($attr_info = $ldapdata_attributes[$attribute]) { // If this attribute should be shown ir registration. if (isset($ldapdata_options[$attribute]) && $ldapdata_options[$attribute] > 0) { $data['ldap_'. $attribute] = $attr_info['2']; } } } } // Print profile fields. if (module_exists('profile') && LDAPPROV_PROFILE) { //$result = db_query('SELECT * FROM {profile_fields} WHERE visibility != %d AND register = 1 ORDER BY category, weight', PROFILE_HIDDEN); $result = _profile_get_fields('', 1); while ($field = db_fetch_object($result)) { $data[$field->name] = $field->title; if ($field->required == 1) { $data[$field->name] .= ' ('. t('required') .')'; } } } // Print content profile fields. if (module_exists('content_profile_registration') && LDAPPROV_CONTENT_PROFILE) { $profile_type = reset(array_keys(content_profile_get_types('names', 'registration_use'))); $profile_fields = _content_profile_registration_get_field_select($profile_type); $profile_required = _content_profile_registration_get_field_select($profile_type, TRUE); $hidden = content_profile_get_settings($profile_type, 'registration_hide'); $hidden = array_filter(isset($hidden) && is_array($hidden) ? $hidden : array()); foreach ($profile_fields as $k => $v) { if (preg_match('/^group_/', $k)) { unset($profile_fields[$k]); unset($profile_required[$k]); } } $data += array_diff_key($profile_fields, is_array($hidden) ? $hidden : array()); foreach ($profile_required as $key => $val) { $data[$key] = isset($data[$key]) ? $data[$key] : ''; $data[$key] .= ' ('. t('required') .')'; } } // Print custom fields. foreach (variable_get('ldapprov_custom', array()) as $key => $val) { $data[$key] = $val['#title']; if (isset($val['#required']) && $val['#required']) { $data[$key] .= ' ('. t('required') .')'; } } switch ($type) { case 'xml': print "\n"; print "\n"; print " \n"; foreach ($data as $key => $val) { print " <$key>$val\n"; } print " \n"; print ""; break; case 'csv': print implode(LDAPPROV_CSV_DELIMITER, array_keys($data)) ."\n"; print implode(LDAPPROV_CSV_DELIMITER, array_map(create_function('$a', 'return \'"\'. preg_replace(\'/"/\', \'\"\', $a) .\'"\';'), array_values($data))); break; } exit(); } ////////////////////////////////////////////////////////////////////////////// // File parse API /** * Parse a xml file. * * param $file. * A file object. * * @return * An array of parsed file data. */ function _ldapprov_xml_parse($file) { global $_ldapprov_xml_names; global $_ldapprov_xml_values; global $_ldapprov_xml_count; $fh = fopen($file->filepath, "r"); $data = fread($fh, $file->filesize); fclose($fh); $_ldapprov_xml_count = 0; $_ldapprov_xml_names = array(); //$_ldapprov_xml_values = array(); $xml_parser = xml_parser_create(); xml_set_element_handler($xml_parser, "_ldapprov_start_element", "_ldapprov_end_element"); xml_set_character_data_handler($xml_parser, "_ldapprov_character_data"); $data = preg_replace('/[\n\r]/', '', $data); if (!xml_parse($xml_parser, $data, TRUE)) { return t('XML error: %error at line %line', array('%error' => xml_error_string(xml_get_error_code($xml_parser)), '%line' => xml_get_current_line_number($xml_parser))); } xml_parser_free($xml_parser); return $_ldapprov_xml_values; } /** * Push xml start element. */ function _ldapprov_start_element($parser, $name, $attrs) { global $_ldapprov_xml_names; array_push($_ldapprov_xml_names, $name); } /** * Pull xml start element. */ function _ldapprov_end_element($parser, $name) { global $_ldapprov_xml_names; global $_ldapprov_xml_count; array_pop($_ldapprov_xml_names); if ($name == 'USER') { $_ldapprov_xml_count++; } } /** * Extract xml data. */ function _ldapprov_character_data($parser, $data) { global $_ldapprov_xml_names; global $_ldapprov_xml_values; global $_ldapprov_xml_count; if ($_ldapprov_xml_names[0] == 'ACCOUNTS' && $_ldapprov_xml_names[1] == 'USER' && isset($_ldapprov_xml_names[2])) { $name = drupal_strtolower($_ldapprov_xml_names[2]); // xml parser makes all names upercase. if (preg_match('/^ldap_/', $name)) { $attributes = variable_get('ldap_user_attributes', array()); foreach ($attributes as $attribute) { if ($name == 'ldap_'. drupal_strtolower($attribute)) { $name = 'ldap_'. $attribute; break; } } } $_ldapprov_xml_values[$_ldapprov_xml_count][$name] = $data; } } /** * Parse a csv file. * * param $file. * A file object. * * @return * An array of parsed file data. */ function _ldapprov_csv_parse($file) { $row = 1; $columnheadings = TRUE; $fh = fopen($file->filepath, 'r'); while (($data = fgetcsv($fh, 1000, LDAPPROV_CSV_DELIMITER, LDAPPROV_CSV_ENCLOSURE )) !== FALSE) { foreach ($data as $key => $value) { $data[$key] = preg_replace('/\\\"/', '"', $value); } if ($columnheadings && ($row == 1)) { $heading_texts = $data; } elseif ($columnheadings) { foreach ($data as $key => $value) { unset($data[$key]); $data[$heading_texts[$key]] = $value; } $rows[] = $data; } else { $rows[] = $data; } $row++; } fclose($fh); return $rows; } ////////////////////////////////////////////////////////////////////////////// // Signup integration /** * Get nodes with signups enabled. * * @return * An array of the signup node nids pointing to node titles. */ function _ldapprov_get_signup_nodes() { global $user; $nids = array(); $result = db_query("SELECT n.nid FROM {node} n JOIN {signup} s ON n.nid = s.nid WHERE s.status = 1 ORDER BY n.title"); while ($row = db_fetch_object($result)) { $node = node_load($row->nid); if (user_access('administer all signups') || (user_access('administer signups for own content') && $user->uid == $node->uid)) { unset($og_access); if (module_exists('og') && module_exists('og_access') && isset($node->og_public) && $node->og_public != 1 && isset($node->og_groups)) { $og_access = FALSE; foreach ($node->og_groups as $gid) { $og_access = in_array(node_load($gid)->og_selective, array(OG_OPEN, OG_MODERATED)) ? TRUE : $og_access; } } if (!isset($og_access) || $og_access) { $nids[$row->nid] = check_plain($node->title); } } } return $nids; } /** * Signup validation. */ function _ldapprov_signup_validate($form, &$form_state) { $values = $form_state['values']; if (module_exists('og') && module_exists('og_access')) { $og_register = isset($values['og_register']) ? $values['og_register'] : array(); $og_groups = isset($values['og_groups']) ? $values['og_groups'] : array(); $og_groups_all = array_merge(array_keys($og_register), array_keys($og_groups)); $og_groups_checked = array_merge(array_filter($og_register), array_filter($og_groups)); if (module_exists('og_mandatory_group') && ($mandatory_group = variable_get('og_mandatory_group', 0)) && $mandatory_group > 0 && !in_array($mandatory_group, $og_groups_checked)) { $og_groups_checked[] = $mandatory_group; } $signups = isset($values['signups']) ? array_filter($values['signups']) : array(); foreach ($signups as $nid) { $node = node_load($nid); if (isset($node->og_public) && $node->og_public != 1 && isset($node->og_groups) && count(array_intersect($node->og_groups, $og_groups_checked)) == 0) { $og_nodes = array(); foreach ($node->og_groups as $gid) { if (in_array($gid, $og_groups_all)) { $og_nodes[] = node_load($gid)->title; } } form_set_error('signups', t('The node %title would not be accessible to created users. The users should also be added to one of the groups the node belongs to, therefore, select any of the following groups: %groups.', array('%title' => $node->title, '%groups' => implode(', ', $og_nodes)))); } } } }