diff --git a/lam/lib/baseModule.inc b/lam/lib/baseModule.inc index 431b9a3a..23cdae30 100644 --- a/lam/lib/baseModule.inc +++ b/lam/lib/baseModule.inc @@ -1170,20 +1170,97 @@ abstract class baseModule { * @param String $label label name * @param boolean $required this is a required field (default false) * @param integer $length field length + * @param boolean $isTextArea show as text area (default false) */ - protected function addSimpleInputTextField(&$container, $attrName, $label, $required = false, $length = null) { + protected function addSimpleInputTextField(&$container, $attrName, $label, $required = false, $length = null, $isTextArea = false) { $value = ''; if (isset($this->attributes[$attrName][0])) { $value = $this->attributes[$attrName][0]; } - $input = new htmlTableExtendedInputField($label, $attrName, $value, $attrName); - $input->setRequired($required); - if ($length != null) { - $input->setFieldSize($length); + if ($isTextArea) { + $cols = 30; + if ($length != null) { + $cols = $length; + } + $input = new htmlTableExtendedInputTextarea($attrName, $value, $cols, 3, $label, $attrName); } + else { + $input = new htmlTableExtendedInputField($label, $attrName, $value, $attrName); + if ($length != null) { + $input->setFieldSize($length); + } + } + $input->setRequired($required); $container->addElement($input, true); } + /** + * Adds a text input field that may contain multiple values to the given htmlTable. + * The field name will be the same as the attribute name plus a counting number (e.g. street_0). + * The last field will be followed by a button to add a new value. This is named add_{attribute name} (e.g. add_street). + * There must be a help entry with the attribute name as ID. + * A new line will also be added after this entry so multiple calls will show the fields one below the other. + * + * @param htmlTable $container parent container + * @param String $attrName attribute name + * @param String $label label name + * @param boolean $required this is a required field (default false) + * @param integer $length field length + */ + protected function addMultiValueInputTextField(&$container, $attrName, $label, $required = false, $length = null) { + $values = array(); + if (isset($this->attributes[$attrName][0])) { + $values = $this->attributes[$attrName]; + } + if (sizeof($values) == 0) { + $values[] = ''; + } + $labelTextOut = new htmlOutputText($label); + $labelTextOut->alignment = htmlElement::ALIGN_TOP; + $container->addElement($labelTextOut); + $subContainer = new htmlGroup(); + for ($i = 0; $i < sizeof($values); $i++) { + $subContainer->addElement(new htmlInputField($attrName . '_' . $i, $values[$i])); + if ($i < (sizeof($values) - 1)) { + $subContainer->addElement(new htmlOutputText('
', false)); + } + else { + $subContainer->addElement(new htmlButton('add_' . $attrName, 'add.png', true)); + } + } + $container->addElement($subContainer); + $help = new htmlHelpLink($attrName); + $help->alignment = htmlElement::ALIGN_TOP; + $container->addElement($help, true); + } + + /** + * Validates a multi-value text field. + * The input fields must be created with function addMultiValueInputTextField(). + * If validation is used then there must exist a message named [{attribute name}][0] (e.g. $this->messages['street'][0]). + * + * @param String $attrName attribute name + * @param array $errors errors array where to put validation errors + * @param String $validationID validation ID for function get_preg() (default: null, null means no validation) + */ + protected function processMultiValueInputTextField($attrName, &$errors, $validationID = null) { + $counter = 0; + while (isset($_POST[$attrName . '_' . $counter])) { + $this->attributes[$attrName][$counter] = $_POST[$attrName . '_' . $counter]; + if (($validationID != null) && !get_preg($this->attributes[$attrName][$counter], $validationID)) { + $errors[] = $this->messages[$attrName][0]; + } + if ($this->attributes[$attrName][$counter] == '') { + unset($this->attributes[$attrName][$counter]); + } + $counter++; + } + if (isset($_POST['add_' . $attrName])) { + $this->attributes[$attrName][] = ''; + } + $this->attributes[$attrName] = array_values($this->attributes[$attrName]); + } + /** * Returns a list of managed object classes for this module. * diff --git a/lam/lib/modules/windowsHost.inc b/lam/lib/modules/windowsHost.inc index d9e7338a..6da35fc1 100644 --- a/lam/lib/modules/windowsHost.inc +++ b/lam/lib/modules/windowsHost.inc @@ -284,7 +284,7 @@ class windowsHost extends baseModule { */ public function get_pdfEntries() { $return = array(); - $this->addSimplePDFField($return, 'cn', _('Group name')); + $this->addSimplePDFField($return, 'cn', _('Host name')); $this->addSimplePDFField($return, 'description', _('Description')); $this->addSimplePDFField($return, 'location', _('Location')); // managed by diff --git a/lam/lib/modules/windowsUser.inc b/lam/lib/modules/windowsUser.inc new file mode 100644 index 00000000..368b92c8 --- /dev/null +++ b/lam/lib/modules/windowsUser.inc @@ -0,0 +1,379 @@ + "high"); + // LDAP filter + $return["ldap_filter"] = array('or' => "(objectClass=user)"); + // alias name + $return["alias"] = _("Windows"); + // module dependencies + $return['dependencies'] = array('depends' => array(), 'conflicts' => array()); + // managed object classes + $return['objectClasses'] = array('user'); + // managed attributes + $return['attributes'] = array('cn', 'sAMAccountName', 'description', 'displayName', 'givenName', 'initials', + 'l', 'mail', 'otherTelephone', 'physicalDeliveryOfficeName', 'postalCode', 'postOfficeBox', 'sn', 'st', + 'streetAddress', 'telephoneNumber', 'url', 'wWWHomePage'); + // help Entries + $return['help'] = array( + 'cn' => array( + "Headline" => _('User name'), 'attr' => 'cn, sAMAccountName', + "Text" => _('Please enter the user\'s name.') + ), + 'description' => array( + "Headline" => _('Description'), 'attr' => 'description', + "Text" => _('Please enter a descriptive text for this user.') + ), + 'displayName' => array( + "Headline" => _('Display name'), 'attr' => 'displayName', + "Text" => _('This is the account\'s full name on Windows systems.') + ), + 'givenName' => array( + "Headline" => _('First name'), 'attr' => 'givenName', + "Text" => _('First name of user. Only letters, - and spaces are allowed.') + ), + 'initials' => array( + "Headline" => _('Initials'), 'attr' => 'initials', + "Text" => _('The initials of the user\'s first names.') + ), + 'l' => array( + "Headline" => _('Location'), 'attr' => 'l', + "Text" => _('This describes the location of the user.') + ), + 'mail' => array( + "Headline" => _('Email address'), 'attr' => 'mail', + "Text" => _('The user\'s email address.') + ), + 'otherTelephone' => array( + "Headline" => _('Other telephone numbers'), 'attr' => 'otherTelephone', + "Text" => _('If the user has multiple telephone numbers then please enter it here.') + ), + 'physicalDeliveryOfficeName' => array( + "Headline" => _('Office name'), 'attr' => 'physicalDeliveryOfficeName', + "Text" => _('The office name of the user (e.g. YourCompany, Human Resources).') + ), + 'postalCode' => array( + "Headline" => _('Postal code'), 'attr' => 'postalCode', + "Text" => _('The postal code of the user\'s address.') + ), + 'postOfficeBox' => array( + "Headline" => _('Post office box'), 'attr' => 'postOfficeBox', + "Text" => _('The post office box of the user\'s address.') + ), + 'sn' => array( + "Headline" => _('Last name'), 'attr' => 'sn', + "Text" => _('Last name of user. Only letters, - and spaces are allowed.') + ), + 'st' => array( + "Headline" => _('State'), 'attr' => 'st', + "Text" => _('The state where the user resides or works.') + ), + 'streetAddress' => array( + "Headline" => _('Street'), 'attr' => 'streetAddress', + "Text" => _('The street name of the user\'s address.') + ), + 'telephoneNumber' => array( + "Headline" => _('Telephone number'), 'attr' => 'telephoneNumber', + "Text" => _('The user\'s telephone number.') + ), + 'url' => array( + "Headline" => _('Other web sites'), 'attr' => 'url', + "Text" => _('Here you can enter additional web sites for the user.') + ), + 'wWWHomePage' => array( + "Headline" => _('Web site'), 'attr' => 'wWWHomePage', + "Text" => _('The user\'s web site (e.g. http://www.company.com).') + ), + ); + // upload fields + $return['upload_columns'] = array( + array( + 'name' => 'windowsHost_name', + 'description' => _('Host name'), + 'help' => 'cn', + 'example' => _('PC01'), + 'required' => true + ), + array( + 'name' => 'windowsHost_description', + 'description' => _('Description'), + 'help' => 'description', + ), + array( + 'name' => 'windowsHost_location', + 'description' => _('Location'), + 'help' => 'location', + 'example' => _('MyCity'), + ), + array( + 'name' => 'windowsHost_managedBy', + 'description' => _('Managed by'), + 'help' => 'managedBy', + 'example' => 'cn=user1,o=test', + ), + ); + // available PDF fields + $return['PDF_fields'] = array( + 'cn' => _('User name'), + 'description' => _('Description'), + 'displayName' => _('Display name'), + 'givenName' => _('First name'), + 'initials' => _('Initials'), + 'l' => _('Location'), + 'mail' => _('Email address'), + 'otherTelephone' => _('Other telephone numbers'), + 'physicalDeliveryOfficeName' => _('Office name'), + 'postalCode' => _('Postal code'), + 'postOfficeBox' => _('Post office box'), + 'sn' => _('Last name'), + 'st' => _('State'), + 'streetAddress' => _('Street'), + 'telephoneNumber' => _('Telephone number'), + 'url' => _('Other web sites'), + 'wWWHomePage' => _('Web site'), + ); + return $return; + } + + /** + * This function fills the $messages variable with output messages from this module. + */ + public function load_Messages() { + $this->messages['cn'][0] = array('ERROR', _('User name'), _('User name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')); + $this->messages['cn'][1] = array('ERROR', _('Account %s:') . ' windowsUser_cn', _('User name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')); + $this->messages['displayName'][0] = array('ERROR', _('Display name'), _('Please enter a valid display name!')); + $this->messages['displayName'][1] = array('ERROR', _('Account %s:') . ' windowsUser_displayName', _('Please enter a valid display name!')); + $this->messages['givenName'][0] = array('ERROR', _('First name'), _('First name contains invalid characters!')); + $this->messages['givenName'][1] = array('ERROR', _('Account %s:') . ' windowsUser_givenName', _('First name contains invalid characters!')); + $this->messages['sn'][0] = array('ERROR', _('Last name'), _('Last name contains invalid characters or is empty!')); + $this->messages['sn'][1] = array('ERROR', _('Account %s:') . ' windowsUser_sn', _('Last name contains invalid characters or is empty!')); + $this->messages['telephoneNumber'][0] = array('ERROR', _('Telephone number'), _('Please enter a valid telephone number!')); + $this->messages['telephoneNumber'][1] = array('ERROR', _('Account %s:') . ' windowsUser_telephone', _('Please enter a valid telephone number!')); + $this->messages['otherTelephone'][0] = array('ERROR', _('Other telephone numbers'), _('Please enter a valid telephone number!')); + $this->messages['otherTelephone'][1] = array('ERROR', _('Account %s:') . ' windowsUser_otherTelephone', _('Please enter a valid telephone number!')); + $this->messages['postalCode'][0] = array('ERROR', _('Postal code'), _('Please enter a valid postal code!')); + $this->messages['postalCode'][1] = array('ERROR', _('Account %s:') . ' windowsUser_postalCode', _('Please enter a valid postal code!')); + $this->messages['mail'][0] = array('ERROR', _('Email address'), _('Please enter a valid email address!')); + $this->messages['mail'][1] = array('ERROR', _('Account %s:') . ' windowsUser_mail', _('Please enter a valid email address!')); + } + + /** + * Returns the HTML meta data for the main account page. + * + * @return htmlElement HTML meta data + */ + public function display_html_attributes() { + $container = new htmlTable(); + $this->addSimpleInputTextField($container, 'cn', _('User name'), true); + $this->addSimpleInputTextField($container, 'givenName', _('First name')); + $this->addSimpleInputTextField($container, 'sn', _('Last name')); + $this->addSimpleInputTextField($container, 'displayName', _('Display name')); + $this->addSimpleInputTextField($container, 'initials', _('Initials')); + $this->addSimpleInputTextField($container, 'description', _('Description')); + $container->addElement(new htmlSubTitle(_('Address')), true); + $this->addSimpleInputTextField($container, 'streetAddress', _('Street'), false, 20, true); + $this->addSimpleInputTextField($container, 'postOfficeBox', _('Post office box')); + $this->addSimpleInputTextField($container, 'postalCode', _('Postal code')); + $this->addSimpleInputTextField($container, 'l', _('Location')); + $this->addSimpleInputTextField($container, 'st', _('State')); + $this->addSimpleInputTextField($container, 'physicalDeliveryOfficeName', _('Office name')); + $container->addElement(new htmlSubTitle(_('Contact data')), true); + $this->addSimpleInputTextField($container, 'mail', _('Email address')); + $this->addSimpleInputTextField($container, 'telephoneNumber', _('Telephone number')); + $this->addMultiValueInputTextField($container, 'otherTelephone', _('Other telephone numbers')); + $this->addSimpleInputTextField($container, 'wWWHomePage', _('Web site')); + $this->addMultiValueInputTextField($container, 'url', _('Other web sites')); + + $container->addElement(new htmlEqualWidth(array('streetAddress', 'cn'))); + return $container; + } + + /** + * Processes user input of the primary module page. + * It checks if all input values are correct and updates the associated LDAP attributes. + * + * @return array list of info/error messages + */ + public function process_attributes() { + $return = array(); + // cn + $this->attributes['cn'][0] = $_POST['cn']; + $this->attributes['sAMAccountName'][0] = $_POST['cn']; + if (!get_preg($_POST['cn'], 'username')) { + $return[] = $this->messages['cn'][0]; + } + // description + $this->attributes['description'][0] = $_POST['description']; + // display name + $this->attributes['displayName'][0] = $_POST['displayName']; + if (!empty($this->attributes['displayName'][0]) && !get_preg($_POST['displayName'], 'realname')) { + $return[] = $this->messages['displayName'][0]; + } + // first name + $this->attributes['givenName'][0] = $_POST['givenName']; + if (!empty($this->attributes['givenName'][0]) && !get_preg($_POST['givenName'], 'realname')) { + $return[] = $this->messages['givenName'][0]; + } + // initials + $this->attributes['initials'][0] = $_POST['initials']; + // location + $this->attributes['l'][0] = $_POST['l']; + // email + $this->attributes['mail'][0] = $_POST['mail']; + if (!empty($this->attributes['mail'][0]) && !get_preg($_POST['mail'], 'email')) { + $return[] = $this->messages['mail'][0]; + } + // other telephones + $this->processMultiValueInputTextField('otherTelephone', $return, 'telephone'); + // office name + $this->attributes['physicalDeliveryOfficeName'][0] = $_POST['physicalDeliveryOfficeName']; + // postal code + $this->attributes['postalCode'][0] = $_POST['postalCode']; + if (!get_preg($_POST['postalCode'], 'postalCode')) { + $return[] = $this->messages['postalCode'][0]; + } + // post office box + $this->attributes['postOfficeBox'][0] = $_POST['postOfficeBox']; + // last name + $this->attributes['sn'][0] = $_POST['sn']; + if (!empty($this->attributes['sn'][0]) && !get_preg($_POST['sn'], 'realname')) { + $return[] = $this->messages['sn'][0]; + } + // state + $this->attributes['st'][0] = $_POST['st']; + // street + $this->attributes['streetAddress'][0] = $_POST['streetAddress']; + // telephone + $this->attributes['telephoneNumber'][0] = $_POST['telephoneNumber']; + if (!get_preg($_POST['telephoneNumber'], 'telephone')) { + $return[] = $this->messages['telephoneNumber'][0]; + } + // other web sites + $this->processMultiValueInputTextField('url', $return); + // web site + $this->attributes['wWWHomePage'][0] = $_POST['wWWHomePage']; + return $return; + } + + /** + * In this function the LDAP account is built up. + * + * @param array $rawAccounts list of hash arrays (name => value) from user input + * @param array $ids list of IDs for column position (e.g. "posixAccount_uid" => 5) + * @param array $partialAccounts list of hash arrays (name => value) which are later added to LDAP + * @param array $selectedModules list of selected account modules + * @return array list of error messages if any + */ + public function build_uploadAccounts($rawAccounts, $ids, &$partialAccounts, $selectedModules) { + $errors = array(); + for ($i = 0; $i < sizeof($rawAccounts); $i++) { + // add object class + if (!in_array('computer', $partialAccounts[$i]['objectClass'])) $partialAccounts[$i]['objectClass'][] = 'computer'; + // cn + sAMAccountName + if ($rawAccounts[$i][$ids['windowsHost_name']] != "") { + if (get_preg($rawAccounts[$i][$ids['windowsHost_name']], 'hostname')) { + $partialAccounts[$i]['cn'] = $rawAccounts[$i][$ids['windowsHost_name']]; + $partialAccounts[$i]['sAMAccountName'] = $rawAccounts[$i][$ids['windowsHost_name']] . '$'; + } + else { + $errMsg = $this->messages['cn'][1]; + array_push($errMsg, array($i)); + $errors[] = $errMsg; + } + } + // description + if ($rawAccounts[$i][$ids['windowsHost_description']] != "") { + $partialAccounts[$i]['description'] = $rawAccounts[$i][$ids['windowsHost_description']]; + } + // location + if ($rawAccounts[$i][$ids['windowsHost_location']] != "") { + $partialAccounts[$i]['location'] = $rawAccounts[$i][$ids['windowsHost_location']]; + } + // managed by + if ($rawAccounts[$i][$ids['windowsHost_managedBy']] != "") { + $partialAccounts[$i]['managedBy'] = $rawAccounts[$i][$ids['windowsHost_managedBy']]; + } + // machine trust account, no password required + $partialAccounts[$i]['userAccountControl'][0] = 4128; + } + return $errors; + } + + /** + * Returns a list of PDF entries + */ + public function get_pdfEntries() { + $return = array(); + $this->addSimplePDFField($return, 'cn', _('User name')); + $this->addSimplePDFField($return, 'description', _('Description')); + $this->addSimplePDFField($return, 'displayName', _('Display name')); + $this->addSimplePDFField($return, 'givenName', _('First name')); + $this->addSimplePDFField($return, 'initials', _('Initials')); + $this->addSimplePDFField($return, 'l', _('Location')); + $this->addSimplePDFField($return, 'mail', _('Email address')); + $this->addSimplePDFField($return, 'otherTelephone', _('Other telephone numbers')); + $this->addSimplePDFField($return, 'physicalDeliveryOfficeName', _('Office name')); + $this->addSimplePDFField($return, 'postalCode', _('Postal code')); + $this->addSimplePDFField($return, 'postOfficeBox', _('Post office box')); + $this->addSimplePDFField($return, 'sn', _('Last name')); + $this->addSimplePDFField($return, 'st', _('State')); + $this->addSimplePDFField($return, 'streetAddress', _('Street')); + $this->addSimplePDFField($return, 'telephoneNumber', _('Telephone number')); + $this->addSimplePDFField($return, 'url', _('Other web sites')); + $this->addSimplePDFField($return, 'wWWHomePage', _('Web site')); + return $return; + } + +} + + +?>