/** * Returns parsed path components without escape characters. * * <code> * FileSystem::getPathComponents('a/b/c'); // returns array('a', 'b', 'c') * FileSystem::getPathComponents('a/b/c/'); // returns array('a', 'b', 'c') * FileSystem::getPathComponents('/a/b/c'); // returns array('', 'a', 'b', 'c') * </code> * * @see FileSystem::joinPathComponents() * @uses Strings::splitWithEscape() * * @param string path * @param char directory separator * * @return string */ static function getPathComponents($path, $separator = DIRECTORY_SEPARATOR) { if ($path == '') { return array(); } $tokens = Strings::splitWithEscape($path, $separator, $separator == '\\' ? '\\\\' : '\\', false); // We need to ignore all empty values except for first $components = array(); foreach ($tokens as $t) { if ($t == '' && count($components)) { continue; } $components[] = $t; } return $components; }
/** * Creates IIdentity object from obtained user data * * @param mixed user data * @param IAuthenticator authenticator * * @return IIdentity */ public function createIdentity($userData, $authenticator) { $uid = NULL; $roles = array(); $profile = array(); // --------------------------------------------------------------------- // DB Password if ($authenticator instanceof Authenticators\DatabasePasswordAuthenticator) { $uid = (int) $userData->{$authenticator->getColumn($authenticator::ID)}; $profile = $userData; } elseif ($authenticator instanceof Authenticators\LdapBindAuthenticator) { $ldapData = (array) $userData; $idCol = 'id'; $tableName = 'security_users'; // LDAP Binding // DB column name -> ldap array key (or callable) $binding = array(array('username' => function ($ldapData) use($authenticator) { return mb_substr($ldapData['dn'], mb_strlen($authenticator->getQueryPrefix()), 0 - mb_strlen($authenticator->getQuerySuffix())); }), array('name' => 'givenName', 'surname' => 'sn', 'email' => function ($ldapData) use(&$binding) { $username = $binding[0]['username']($ldapData); $tokens = Strings::splitWithEscape($ldapData['dn'], ',dc='); array_shift($tokens); return $username . '@' . implode($tokens, '.'); })); // Prepare data based on LDAP binding $boundData = $this->bindValues($ldapData, $binding[0]); $this->db->query('LOCK TABLES %n WRITE', $tableName); $ds = $this->db->select('*')->from($tableName); foreach ($boundData as $key => $value) { $ds->where('%n = %s', $key, $value); } $profile = $ds->fetch(); // If profile does not exist yet if ($profile === FALSE) { $boundData = array_merge($boundData, $this->bindValues($ldapData, $binding[1])); $this->db->insert($tableName, $boundData)->execute(); $boundData[$idCol] = $uid = (int) $this->db->getInsertId(); $profile = $boundData; } else { $uid = (int) $profile[$idCol]; } $this->db->query('UNLOCK TABLES'); // TODO: configurable $groupsDn = NULL; if ($groupsDn == NULL) { $dnTokens = array_reverse($userData->getParsedDn()); foreach ($dnTokens as $k => $v) { if (!Strings::startsWith($v, 'dc=')) { array_splice($dnTokens, $k, count($dnTokens), array('ou=groups')); break; } } $groupDn = implode(array_reverse($dnTokens), ','); } $username = str_replace(array('\\', ')'), array('\\\\', '\\)'), $boundData['username']); $userGid = intval($userData->gidNumber); $filter = "(&(objectClass=posixGroup)(|(gidNumber={$userGid})(memberUid={$username})))"; $result = $authenticator->ldapConnection->search($groupsDn, $filter); foreach ($result as $record) { $roles[] = $record->cn; } } elseif ($authenticator instanceof Authenticators\DatabasePSKAuthenticator) { $uid = Strings::intoParameterizedString('psk', array($userData->key)); $roles[] = $uid; $profile = $userData; // Other authenticators } else { throw new Nette\NotSupportedException("Authenticator " . get_class($authenticator) . " not supported yet"); } // --------------------------------------------------------------------- // Remove duplicit roles $roles = array_unique($roles); // Sanity check if (!is_scalar($uid) || $uid == "") { throw new Nette\InvalidStateException("User ID has to be non-empty string or number"); } // --------------------------------------------------------------------- // Query roles from DB if it's not PSK (has user id) if (is_int($uid)) { $roles = array_merge($this->getUserRoles($uid), $roles); } // --------------------------------------------------------------------- // Identity $identity = new Nette\Security\Identity($uid, $roles, $profile); return $identity; }