X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=classes%2Fplatal.php;h=2d988bccfebd361aa0d6d355a946ee265140a470;hb=857a2b960d47c1ef4990e6ed55bad2ed40681f66;hp=e64e4c8d7de6b854b2aa27b3a85b9865a055b229;hpb=8b1f8e12d444062ef63a0db3a8fa94582a9778c3;p=platal.git diff --git a/classes/platal.php b/classes/platal.php index e64e4c8..2d988bc 100644 --- a/classes/platal.php +++ b/classes/platal.php @@ -1,6 +1,6 @@ buildGlobals(); + $globals->init(); + + /* Get the current session: assign first, then activate the session. + */ + $session = $this->buildSession(); + if (!$session->startAvailableAuth()) { + Platal::page()->trigError("Données d'authentification invalides."); + } + $modules = func_get_args(); + if (isset($modules[0]) && is_array($modules[0])) { + $modules = $modules[0]; + } $this->path = trim(Get::_get('n', null), '/'); $this->__mods = array(); @@ -41,12 +68,17 @@ class Platal array_unshift($modules, 'core'); foreach ($modules as $module) { + $module = strtolower($module); $this->__mods[$module] = $m = PLModule::factory($module); - $this->__hooks += $m->handlers(); + $this->__hooks = $m->handlers() + $this->__hooks; + } + + if ($globals->mode == '') { + pl_redirect('index.html'); } } - function pl_self($n = null) + public function pl_self($n = null) { if (is_null($n)) return $this->path; @@ -60,7 +92,15 @@ class Platal return join('/', array_slice($this->argv, 0, $n)); } - function find_hook() + public static function wiki_hook($auth = AUTH_PUBLIC, $perms = 'user', $type = DO_AUTH) + { + return array('hook' => PL_WIKI_HOOK, + 'auth' => $auth, + 'perms' => $perms, + 'type' => $type); + } + + protected function find_hook() { $p = $this->path; @@ -77,23 +117,28 @@ class Platal $hook = $this->__hooks[$p]; - if (!is_callable($hook['hook'])) { + if (!is_callable($hook['hook']) && $hook['hook'] != PL_WIKI_HOOK) { return null; } + $this->https = ($hook['type'] & NO_HTTPS) ? false : true; $this->argv = explode('/', substr($this->path, strlen($p))); $this->argv[0] = $p; return $hook; } - function find_nearest_key($key, &$array) + protected function find_nearest_key($key, array &$array) { $keys = array_keys($array); if (in_array($key, $keys)) { return $key; } + if (($pos = strpos($key, '.php')) !== false) { + $key = substr($key, 0, $pos); + } + $has_end = in_array("#final#", $keys); if (strlen($key) > 24 && $has_end) { return "#final#"; @@ -104,24 +149,27 @@ class Platal continue; } $lev = levenshtein($key, $k); - if ((!isset($val) || $lev < $val) && $lev <= (strlen($k)*2)/3) { + + if ((!isset($val) || $lev < $val) + && ($lev <= strlen($k)/2 || strpos($k, $key) !== false || strpos($key, $k) !== false)) { $val = $lev; $best = $k; } } if (!isset($best) && $has_end) { return "#final#"; - } else { + } else if (isset($best)) { return $best; } return null; } - function near_hook() + public function near_hook() { $hooks = array(); + $leafs = array(); foreach ($this->__hooks as $hook=>$handler) { - if (!empty($handler['perms']) && $handler['perms'] != S::v('perms')) { + if (!$this->check_perms($handler['perms'])) { continue; } $parts = split('/', $hook); @@ -130,11 +178,20 @@ class Platal if (!isset($place[$part])) { $place[$part] = array(); } - $place =& $place[$part]; + $place =& $place[$part]; + } + $leaf = $parts[count($parts)-1]; + if (!isset($leafs[$leaf])) { + $leafs[$leaf] = $hook; + } else if (is_array($leafs[$leaf])) { + $leafs[$leaf][] = $hook; + } else { + $leafs[$leaf] = array($hook, $leafs[$leaf]); } $place["#final#"] = array(); } + // search for the nearest full path $p = split('/', $this->path); $place =& $hooks; $link = ''; @@ -146,7 +203,8 @@ class Platal } if ($key == "#final#") { if (!array_key_exists($link, $this->__hooks)) { - return null; + $link = ''; + break; } $key = $k; $ended = true; @@ -158,58 +216,99 @@ class Platal $link .= $key; $place =& $place[$key]; } else { - return null; + $link = ''; + break; + } + } + if ($link == $this->path) { + $link = ''; + } + if ($link && levenshtein($link, $this->path) < strlen($link)/3) { + return $link; + } + + // search for missing namespace (the given name is a leaf) + $leaf = array_shift($p); + $args = count($p) ? '/' . implode('/', $p) : ''; + if (isset($leafs[$leaf]) && !is_array($leafs[$leaf]) && $leafs[$leaf] != $this->path) { + return $leafs[$leaf] . $args; + } + unset($val); + $best = null; + foreach ($leafs as $k=>&$path) { + if (is_array($path)) { + continue; } + $lev = levenshtein($leaf, $k); + + if ((!isset($val) || $lev < $val) + && ($lev <= strlen($k)/2 || strpos($k, $leaf) !== false || strpos($leaf, $k) !== false)) { + $val = $lev; + $best = $path; + } + } + return $best == null ? ( $link ? $link : null ) : $best . $args; + } + + protected function check_perms($perms) + { + if (!$perms) { // No perms, no check + return true; } - return $link; + $s_perms = S::v('perms'); + return $s_perms->hasFlagCombination($perms); } - function call_hook(&$page) + private function call_hook(PlPage &$page) { $hook = $this->find_hook(); if (empty($hook)) { return PL_NOT_FOUND; } - - $args = $this->argv; - $args[0] = &$page; - - if (!empty($hook['perms']) && $hook['perms'] != S::v('perms')) { - return PL_FORBIDDEN; + global $globals, $session; + if ($this->https && !@$_SERVER['HTTPS'] && $globals->core->secure_domain) { + http_redirect('https://' . $globals->core->secure_domain . $_SERVER['REQUEST_URI']); } + $args = $this->argv; + $args[0] =& $page; + if ($hook['auth'] > S::v('auth', AUTH_PUBLIC)) { - if ($hook['type'] == DO_AUTH) { - global $globals; - - if (!call_user_func(array($globals->session, 'doAuth'))) { + if ($hook['type'] & DO_AUTH) { + if (!$session->start($hook['auth'])) { $this->force_login($page); } } else { return PL_FORBIDDEN; } } + if ($hook['auth'] != AUTH_PUBLIC && !$this->check_perms($hook['perms'])) { + if (self::notAllowed()) { + return PL_FORBIDDEN; + } + } - return call_user_func_array($hook['hook'], $args); + if ($hook['hook'] == PL_WIKI_HOOK) { + return PL_WIKI; + } + $val = call_user_func_array($hook['hook'], $args); + if ($val == PL_DO_AUTH) { + // The handler need a better auth with the current args + if (!$session->start($session->loggedLevel())) { + $this->force_login($page); + } + $val = call_user_func_array($hook['hook'], $args); + } + return $val; } - function force_login(&$page) - { - if (S::logged()) { - $page->changeTpl('core/password_prompt_logged.tpl'); - $page->addJsLink('do_challenge_response_logged.js'); - } else { - $page->changeTpl('core/password_prompt.tpl'); - $page->addJsLink('do_challenge_response.js'); - } - $page->run(); - } + /** Show the authentication form. + */ + abstract public function force_login(PlPage& $page); - function run() + public function run() { - global $page; - - new_skinned_page('platal/index.tpl'); + $page =& self::page(); if (empty($this->path)) { $this->path = 'index'; @@ -224,21 +323,126 @@ class Platal case PL_NOT_FOUND: $this->__mods['core']->handler_404($page); break; + + case PL_WIKI: + return PL_WIKI; } $page->assign('platal', $this); $page->run(); } - function on_subscribe($forlife, $uid, $promo, $pass) + public function error403() { - $args = func_get_args(); - foreach ($this->__mods as $mod) { - if (!is_callable($mod, 'on_subscribe')) - continue; - call_user_func_array(array($mod, 'on_subscribe'), $args); + $page =& self::page(); + + $this->__mods['core']->handler_403($page); + $page->assign('platal', $this); + $page->run(); + } + + public function error404() + { + $page =& self::page(); + + $this->__mods['core']->handler_404($page); + $page->assign('platal', $this); + $page->run(); + } + + public static function notAllowed() + { + if (S::admin()) { + self::page()->trigWarning('Tu accèdes à cette page car tu es administrateur du site.'); + return false; + } else { + return true; + } + } + + public static function load($modname, $include = null) + { + global $platal; + $modname = strtolower($modname); + if (isset($platal->__mods[$modname])) { + if (is_null($include)) { + return; + } + $platal->__mods[$modname]->load($include); + } else { + if (is_null($include)) { + require_once PLModule::path($modname) . '.php'; + } else { + require_once PLModule::path($modname) . '/' . $include; + } + } + } + + public static function assert($cond, $error, $userfriendly) + { + global $globals; + if ($cond === false) { + header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error'); + $file = fopen($globals->spoolroot . '/spool/tmp/assert_erros', 'a'); + fwrite($file, '
' . pl_entities($error) . '
\n'); + fclose($file); + + Platal::page()->kill($userfriendly); } } + + public function &buildLogger($uid, $suid = 0) + { + if (defined('PL_LOGGER_CLASS')) { + $class = PL_LOGGER_CLASS; + return new $class($uid, $suid); + } else { + return PlLogger::dummy($uid, $suid); + } + } + + protected function &buildPage() + { + $pageclass = PL_PAGE_CLASS; + $page = new $pageclass(); + return $page; + } + + static public function &page() + { + if (is_null(self::$_page)) { + global $platal; + self::$_page = $platal->buildPage(); + } + return self::$_page; + } + + protected function &buildSession() + { + $sessionclass = PL_SESSION_CLASS; + $session = new $sessionclass(); + return $session; + } + + static public function &session() + { + global $session; + return $session; + } + + protected function &buildGlobals() + { + $globalclass = PL_GLOBALS_CLASS; + $globals = new $globalclass(); + return $globals; + } + + static public function &globals() + { + global $globals; + return $globals; + } } +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: ?>