public function getUUID($attributeName, $tries = 5) { if (!is_string($attributeName) || empty($attributeName) || !is_int($tries)) { // TODO: real exception throw new Exception('bad parameter'); } if ($tries < 1 || $tries > 20) { $tries = 5; } // Generate an uuid and check its unicity by searching in LDAP ($tries tries max) $uuid = null; $cnt = 0; while ($uuid === null && $cnt++ < $tries) { // Generate UUIDv4 (http://stackoverflow.com/a/10861056) $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)); // Validate its unicity // TODO: escape $attributeName? $result = $this->search(array('filter' => '(' . $attributeName . '=' . Filter::escapeValue($uuid) . ')', 'attributes' => array($attributeName), 'sizelimit' => 1)); if ($result->count() > 0) { $uuid = null; } } if ($uuid === null) { // Seriously? Something is really bad on this server... throw new Exception('Unable to generate an unique UUID'); } return $uuid; }
public function testFilterValueUtf8() { $filter = 'ÄÖÜäöü߀'; $escaped = Ldap\Filter::escapeValue($filter); $unescaped = Ldap\Filter::unescapeValue($escaped); $this->assertEquals($filter, $unescaped); }
protected function assertValidEntry($entry, $isUpdate = false) { $domainDn = null; $errors = array(); /* * employeeNumber */ if (!preg_match('#^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$#', $entry['employeeNumber'])) { // This is fatal if ($isUpdate !== true) { throw new UserFriendlyException(500, 'Server error', 'The server is unable to generate a valid ID for this account. Please contact a technician.'); } else { throw new UserFriendlyException(400, 'Incorrect request', 'The account ID provided with this request is incorrect.'); } } /* * cn */ if (!isset($entry['cn']) || empty($entry['cn'])) { $errors['cn'] = 'Display name is required.'; } /* * givenName */ // Nop /* * sn */ if (!isset($entry['sn']) || empty($entry['sn'])) { $errors['sn'] = 'Last name is required.'; } /* * mail */ // Validate mail format $emailValidator = new EmailAddress(); if (!isset($entry['mail']) || empty($entry['mail'])) { $errors['mail'] = 'Email is required.'; } else { if (!$emailValidator->isValid($entry['mail'])) { $errors['mail'] = 'The email provided is not correctly formated.'; } else { // Validate mail domain-part is an allowed domain $result = $this->ldap->search(array('filter' => '(|(dc=' . Filter::escapeValue($emailValidator->hostname) . ')(associatedDomain=' . Filter::escapeValue($emailValidator->hostname) . '))', 'basedn' => $this->userBaseDn, 'attributes' => array('dc'), 'sizelimit' => 2)); if ($result->count() < 1) { $errors['mail'] = array('You are not allowed to create an account for the domain \'%@1\'.', $emailValidator->hostname); } else { if ($result->count() > 1) { // This is fatal throw new UserFriendlyException(500, 'Server error', 'An inconsistency has been detected in the data. Please contact a technician.'); } else { $domainEntry = $result->getFirst(); if ($domainEntry['dc'][0] !== $emailValidator->hostname) { $errors['mail'] = array('\'%@1\' is a domain alias. Please use the primary domain.', $emailValidator->hostname); } else { $domainDn = $result->dn(); // Validate mail unicity $result = $this->ldap->search(array('filter' => '(|(mail=' . Filter::escapeValue($entry['mail']) . ')(mailAlias=' . Filter::escapeValue($entry['mail']) . '))', 'basedn' => $domainDn, 'attributes' => array('employeeNumber'), 'sizelimit' => 2)); $result->getInnerIterator()->setAttributeNameTreatment(DefaultIterator::ATTRIBUTE_NATIVE); if ($result->count() === 1) { $duplicateEntry = $result->getFirst(); if ($isUpdate === false || $entry['employeeNumber'] !== $duplicateEntry['employeeNumber'][0]) { $errors['mail'] = 'This email address already exists on an other account.'; } } else { if ($result->count() > 1) { // This is fatal throw new UserFriendlyException(500, 'Server error', 'An inconsistency has been detected in the data. Please contact a technician.'); } } } } } } } /* * mailAlias */ // Validate each mail aliases if (!empty($entry['mailAlias']) && !is_array($entry['mailAlias'])) { $errors['mailAlias'] = 'The data for email aliases are not consistent.'; } else { if (!empty($entry['mailAlias'])) { $errors['mailAlias'] = array(); $aliasValidator = new EmailAddress(); foreach ($entry['mailAlias'] as $alias) { if (!$aliasValidator->isValid($alias)) { // Validate alias format $errors['mailAlias'][$alias] = 'The email alias provided is not correctly formated.'; } else { if ($emailValidator->hostname !== $aliasValidator->hostname) { // Validate alias domain-part is the same as mail domain-part $errors['mailAlias'][$alias] = 'The email alias must use the same domain as the email.'; } else { if ($alias === $entry['mail']) { // Validate alias unicity with mail $errors['mailAlias'][$alias] = 'The email alias address cannot be the same as the alias must use the same domain as the email.'; } else { // Validate alias unicity with other entries (including mail) } } } } if (count($errors['mailAlias']) < 1) { unset($errors['mailAlias']); } } } /* * password / passwordConfirmation */ if (isset($entry['userPassword']) && strlen($entry['userPassword']) < 6) { $errors['password'] = '******'; } else { if (isset($entry['userPassword']) && isset($entry['userPassword']) !== isset($entry['passwordConfirmation'])) { $errors['passwordConfirmation'] = 'Please re-enter the password to confirm it.'; } else { if (isset($entry['userPassword']) && $entry['userPassword'] !== $entry['passwordConfirmation']) { $errors['passwordConfirmation'] = 'The confirmation does not match. Please check both password and its confirmation.'; } } } // if (empty($errors)) { return sprintf('employeeNumber=%s,ou=Mailboxes,%s', $entry['employeeNumber'], $domainDn); } else { $description = count($errors) === 1 ? 'There were an error processing your request. Please review the field marked in red.' : 'There were errors processing your request. Please review the fields marked in red.'; throw new UserFriendlyException(400, 'Provided data are incorrect', $description, $errors); } }