phpPoA2
[ class tree: phpPoA2 ] [ index: phpPoA2 ] [ all elements ]

Source for file PoA.php

Documentation is available at PoA.php

  1. <?php
  2. /**
  3.  * @copyright Copyright 2005-2010 RedIRIS, http://www.rediris.es/
  4.  *
  5.  *  This file is part of phpPoA2.
  6.  *
  7.  *  phpPoA2 is free software: you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation, either version 3 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  phpPoA2 is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with phpPoA2. If not, see <http://www.gnu.org/licenses/>.
  19.  *
  20.  * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
  21.  * @version 2.0
  22.  * @author Jaime Perez <jaime.perez@rediris.es>
  23.  * @filesource
  24.  */
  25.  
  26. /**
  27.  * @ignore
  28.  */
  29. set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).
  30.                                     PATH_SEPARATOR.dirname(__FILE__)."/messages".
  31.                                     PATH_SEPARATOR.dirname(__FILE__)."/lib".
  32.                                     PATH_SEPARATOR.dirname(__FILE__)."/lib/db".
  33.                                     PATH_SEPARATOR.dirname(__FILE__)."/lib/crypto".
  34.                                     PATH_SEPARATOR.dirname(__FILE__)."/lib/authn".
  35.                                     PATH_SEPARATOR.dirname(__FILE__)."/lib/authz");
  36.  
  37. require_once("definitions.php");
  38. require_once("PoAUtils.php");
  39. require_once("PoAEventHandler.php");
  40. include_once("AutoPoA.php");
  41. include_once("LitePoA.php");
  42.  
  43. /**
  44.  * Standard class that implements all the functionallity of the phpPoA.
  45.  * @package phpPoA2
  46.  */
  47. class PoA {
  48.     protected $local_site;
  49.     protected $cfg;
  50.     protected $log;
  51.     protected $authn_engine;
  52.     protected $attributes;
  53.     protected $authz_engines;
  54.     protected $db_manager;
  55.     protected $autoload;
  56.     protected $handler;
  57.  
  58.     /**
  59.      * Main constructor. Configures the PoA and performs initialization.
  60.      * @param site The identifier to determine which configuration to apply.
  61.      * @param file The path to the configuration file.
  62.      */
  63.     public function __construct($site$file null{
  64.         $this->local_site = $site;
  65.  
  66.         // manage generic session
  67.         if (!isset($_COOKIE[$site.'_session'])) {
  68.             $id mt_rand();
  69.             @setcookie($site.'_session'$id);
  70.             $_COOKIE[$site.'_session'$id;
  71.         }
  72.  
  73.         $this->handler = new PoAEventHandler($site);
  74.  
  75.         // register autoload function
  76.         spl_autoload_register(array($this->handler,"autoloadHandler"));
  77.  
  78.         // configure
  79.         try {
  80.             $this->cfg = new PoAConfigurator($site$file);
  81.         catch (Exception $e// unrecoverable!!
  82.             // we have no logging, so do our best here
  83.             // put a message in the error log and in STDOUT and exit
  84.             error_log($e);
  85.             $this->handler->abort(E_USER_ERROR$e);
  86.         }
  87.  
  88.         // initialize logger
  89.         $this->log = new PoALog($this->cfg->getLogLevel()$this->cfg->getLogFile());
  90.  
  91.         // initialize error handling
  92.         $this->handler->setDebug($this->cfg->isDebug());
  93.         $this->handler->setLogger($this->log);
  94.         set_exception_handler(array($this->handler"exceptionHandler"));
  95.         set_error_handler(array($this->handler"errorHandler"));
  96.  
  97.         // load authentication engine
  98.         $engine $this->cfg->getAuthnEngine();
  99.         if (class_exists($engine)) {
  100.             $this->authn_engine = new $engine($this->cfg->getAuthnEngineConfFile()$site);
  101.             $this->authn_engine->setHandler($this->handler);
  102.         }
  103.  
  104.         // load authorization engines
  105.         $engines $this->cfg->getAuthzEngines();
  106.         foreach ($engines as $engine{
  107.             $this->authz_engines[$enginenew $engine($this->cfg->getAuthzEngineConfFile($engine)$site);
  108.             $this->authz_engines[$engine]->setHandler($this->handler);
  109.         }
  110.  
  111.         $this->clean();
  112.     }
  113.  
  114.     protected function clean({
  115.         // clean
  116.         restore_exception_handler();
  117.         restore_error_handler();
  118.     }
  119.  
  120.     /**
  121.      * Attach a hook object to the appropriate entry point of the available
  122.      * authentication or authorization engines.
  123.      * @param name The name of the hook. Refer to each individual engine
  124.      *  for a complete list of available hooks.
  125.      * @param hook A hook object with the function or method to attach.
  126.      * @return true if the hook was successfully attached, false otherwise.
  127.      */
  128.     public function addHook($name$hook{
  129.         // register autoload function
  130.         set_exception_handler(array($this->handler"exceptionHandler"));
  131.         set_error_handler(array($this->handler"errorHandler"));
  132.  
  133.         // add hook for authentication engine
  134.         $result $this->authn_engine->addHook($name$hook);
  135.  
  136.         // add hook for authorization engines
  137.         foreach ($this->authz_engines as $engine{
  138.             $result |= $engine->addHook($name$hook);
  139.         }
  140.  
  141.         $this->clean();
  142.         return $result;
  143.     }
  144.  
  145.     /**
  146.      * Remove a hook from the specified entry point of the available
  147.      * authentication or authorization engines.
  148.      * @param name The name of the hook. Refer to each individual engine
  149.      *  for a complete list of available hooks.
  150.      * @param hook The hook object which shall be removed.
  151.      * @return true if the hook was successfully removed, false otherwise.
  152.      */
  153.     public function removeHook($name$hook{
  154.         // register autoload function
  155.         set_exception_handler(array($this->handler"exceptionHandler"));
  156.         set_error_handler(array($this->handler"errorHandler"));
  157.  
  158.         // remove hook from authentication engine
  159.         $result $this->authn_engine->removeHook($name$hook);
  160.  
  161.         // remove hook from authorization engines
  162.         foreach ($this->authz_engines as $engine{
  163.             $result |= $engine->removeHook($name$hook);
  164.         }
  165.  
  166.         $this->clean();
  167.         return $result;
  168.     }
  169.  
  170.     /****************************
  171.      * Authentication interface *
  172.      ****************************/
  173.  
  174.     /**
  175.      * Perform a federated login for the user.
  176.      * @return AUTHN_SUCCESS if authentication succeeds, AUTHN_FAILED in
  177.      *  any other case.
  178.      */
  179.     public function authenticate({
  180.         // register autoload function
  181.         set_exception_handler(array($this->handler"exceptionHandler"));
  182.         set_error_handler(array($this->handler"errorHandler"));
  183.  
  184.         // check if we have an authentication engine configured
  185.         if (empty($this->authn_engine)) {
  186.             trigger_error(PoAUtils::msg('authn-engine-err'array())E_USER_WARNING);
  187.             $this->clean();
  188.             return AUTHN_FAILED;
  189.         }
  190.  
  191.         trigger_error(PoAUtils::msg("authenticating-via"array($this->cfg->getAuthnEngine())));
  192.  
  193.         $result false;
  194.         try {
  195.             $result $this->authn_engine->authenticate();
  196.         catch (PoAException $e{
  197.             trigger_error($eE_USER_WARNING);
  198.         }
  199.         if ($result{
  200.             trigger_error(PoAUtils::msg('authn-success'array($this->cfg->getAuthnEngine()))E_USER_WARNING);
  201.         else {
  202.             trigger_error(PoAUtils::msg('authn-err'array())E_USER_WARNING);
  203.         }
  204.  
  205.         $this->clean();
  206.     return $result;
  207.     }
  208.  
  209.     /**
  210.      * Query the current status of the user in the federation.
  211.      * @return AUTHN_SUCCESS if authentication succeeded, AUTHN_FAILED in
  212.      *  any other case.
  213.      */
  214.     public function isAuthenticated({
  215.         // register autoload function
  216.         set_exception_handler(array($this->handler"exceptionHandler"));
  217.         set_error_handler(array($this->handler"errorHandler"));
  218.  
  219.         // check if we have an authentication engine configured
  220.         if (empty($this->authn_engine)) {
  221.             trigger_error(PoAUtils::msg('authn-engine-err'array())E_USER_WARNING);
  222.             $this->clean();
  223.             return AUTHN_FAILED;
  224.         }
  225.  
  226.         trigger_error(PoAUtils::msg("check-authn-status"array($this->cfg->getAuthnEngine())));
  227.  
  228.         $result $this->authn_engine->isAuthenticated();
  229.         if ($result{
  230.             trigger_error(PoAUtils::msg('authn-success'array($this->cfg->getAuthnEngine()))E_USER_WARNING);
  231.         else {
  232.             trigger_error(PoAUtils::msg('authn-err'array())E_USER_WARNING);
  233.         }
  234.  
  235.         $this->clean();
  236.     return $result;
  237.     }
  238.  
  239.     /**
  240.      * Retrieve the attributes provided by the user when logged in.
  241.      * @return an associative array containing all attributes.
  242.      */
  243.     public function getAttributes({
  244.         // register autoload function
  245.         set_exception_handler(array($this->handler"exceptionHandler"));
  246.         set_error_handler(array($this->handler"errorHandler"));
  247.  
  248.         // check if we have an authentication engine configured
  249.         if (empty($this->authn_engine)) {
  250.             trigger_error(PoAUtils::msg('authn-engine-err'array())E_USER_WARNING);
  251.             $this->clean();
  252.             return array();
  253.         }
  254.  
  255.         $this->clean();
  256.         return $this->authn_engine->getAttributes();
  257.     }
  258.  
  259.     /**
  260.      * Get the value (or values) of an attribute, if present.
  261.      * @param name The name of the attribute.
  262.      * @param namespace The namespace of the attribute, if any.
  263.      * @return the attribute value or an array containing all values.
  264.      *  Null in any other case.
  265.      */
  266.     public function getAttribute($name$namespace{
  267.         // register autoload function
  268.         set_exception_handler(array($this->handler"exceptionHandler"));
  269.         set_error_handler(array($this->handler"errorHandler"));
  270.  
  271.         // check if we have an authentication engine configured
  272.         if (empty($this->authn_engine)) {
  273.             trigger_error(PoAUtils::msg('authn-engine-err'array())E_USER_WARNING);
  274.             $this->clean();
  275.             return null;
  276.         }
  277.  
  278.         $this->clean();
  279.         return $this->authn_engine->getAttribute($name$namespace);
  280.     }
  281.  
  282.     /**
  283.      * Remove the user's session and trigger a logout for the specified authentication
  284.      * protocol.
  285.      * @param slo Whether to perform a Single Log Out or a local logout.
  286.      * @return true if success, false in any other case.
  287.      */
  288.     public function logout($slo{
  289.         // register autoload function
  290.         set_exception_handler(array($this->handler"exceptionHandler"));
  291.         set_error_handler(array($this->handler"errorHandler"));
  292.  
  293.         // check if we have an authentication engine configured
  294.         if (empty($this->authn_engine)) {
  295.             trigger_error(PoAUtils::msg('authn-engine-err'array())E_USER_WARNING);
  296.             $this->clean();
  297.             return AUTHN_FAILED;
  298.         }
  299.  
  300.         $this->clean();
  301.         return $this->authn_engine->logout($slo);
  302.     }
  303.  
  304.     /***************************
  305.      * Authorization interface *
  306.      ***************************/
  307.  
  308.     /**
  309.      * Perform authorization for the a given subject.
  310.      * Multiple authorization engines are supported, so
  311.      * authorization will succeed if any of these succeeds.
  312.      * @param user The subject queried.
  313.      * @param attrs The attributes of the user.
  314.      * @param engine The authorization engine(s) to use. All engines are used if none specified.
  315.      *  If more than one engine should be checked then this must be an array.
  316.      * @return AUTHZ_SUCCESS if any of the supported (or selected) engines succeeds or if no
  317.      *  authorization engine is configured. AUTHZ_FAILED if all the engines fail.
  318.      */
  319.     public function isAuthorized($user$attrs$engine null{
  320.         // register autoload function
  321.         set_exception_handler(array($this->handler"exceptionHandler"));
  322.         set_error_handler(array($this->handler"errorHandler"));
  323.  
  324.         // bypass if no authorization engine
  325.         if (empty($engine&& empty($this->authz_engines))
  326.             return true;
  327.  
  328.         $result false;
  329.         // check specific engines
  330.         if (!empty($engine)) {
  331.             $engines $engine;
  332.             if (!is_array($engine)) $engines array($engine);
  333.  
  334.             // iterate over engines
  335.             foreach ($engines as $e{
  336.                 if (!isset($this->authz_engines[$e])) {
  337.                     trigger_error(PoAUtils::msg("authz-engine-err"array($e))E_USER_ERROR);
  338.                 }
  339.                 trigger_error(PoAUtils::msg("query-authz-via"array($e)));
  340.                 $result |= $this->authz_engines[$e]->isAuthorized($user$attrs);
  341.             }
  342.         // check all configured engines
  343.         else {
  344.             trigger_error(PoAUtils::msg("query-authz"array()));
  345.             // iterate over engines
  346.             foreach ($this->authz_engines as $e{
  347.                 $result |= $e->isAuthorized($user$attrs);
  348.             }
  349.         }
  350.  
  351.         if ($result{
  352.             trigger_error(PoAUtils::msg('user-authz-ok'array($user))E_USER_WARNING);
  353.         else {
  354.             trigger_error(PoAUtils::msg('user-authz-err'array($user))E_USER_WARNING);
  355.         }
  356.  
  357.         $this->clean();
  358.         return $result;
  359.     }
  360.  
  361.     /**
  362.      * Authorize a given subject with the data retrieved from federated login.
  363.      * Multiple authorization engines are supported, so
  364.      * authorization will be done in all of them.
  365.      * @param user The subject of authorization.
  366.      * @param attrs The attributes of the user.
  367.      * @param reference An internal reference that may be valuable for the engine, tipically
  368.      *  referring to a previous invitation or similar.
  369.      * @param expires The time (POSIX) when authorization will expire. Use 0 if authorization
  370.      *  should never expire. Defaults to 0.
  371.      * @param engine The authorization engine(s) to use. All engines are used if none specified.
  372.      *  If more than one engine should be checked then this must be an array.
  373.      * @return AUTHZ_SUCCESS if any of the supported engines succeeds or if no
  374.      *  authorization engine is configured. AUTHZ_FAILED if all the engines fail.
  375.      */
  376.     public function authorize($user$attrs$reference null$expires 0$engine null{
  377.         // register autoload function
  378.         set_exception_handler(array($this->handler"exceptionHandler"));
  379.         set_error_handler(array($this->handler"errorHandler"));
  380.  
  381.         $result false;
  382.         // check specific engines
  383.         if (!empty($engine)) {
  384.             $engines $engine;
  385.             if (!is_array($engine)) $engines array($engine);
  386.  
  387.             // iterate over engines
  388.             foreach ($engines as $e{
  389.                 if (!isset($this->authz_engines[$e])) {
  390.                     trigger_error(PoAUtils::msg("authz-engine-err"array($e))E_USER_ERROR);
  391.                 }
  392.                 trigger_error(PoAUtils::msg("authorize-user-via"array($user$e)));
  393.                 $result |= $this->authz_engines[$e]->authorize($user$attrs$reference$expires);
  394.             }
  395.         // check all configured engines
  396.         else {
  397.             // iterate over engines
  398.             foreach ($this->authz_engines as $name => $e{
  399.                 trigger_error(PoAUtils::msg("authorize-user-via"array($user$name)));
  400.                 $result |= $e->authorize($user$attrs$reference$expires);
  401.             }
  402.         }
  403.  
  404.         $this->clean();
  405.         return $result;
  406.     }
  407.  
  408.     /**
  409.      * Revoke authorization for a given subject identified by an e-mail.
  410.      * @param mail The e-mail of the user.
  411.      * @param engine The authorization engine(s) to use. All engines are used if none specified.
  412.      *  If more than one engine should be checked then this must be an array.
  413.      * @return true if authorization is revoked correctly for all authorization
  414.      *  engines, false in any other case.
  415.      */
  416.     public function revoke($mail$engine null{
  417.         // register autoload function
  418.         set_exception_handler(array($this->handler"exceptionHandler"));
  419.         set_error_handler(array($this->handler"errorHandler"));
  420.  
  421.         $result false;
  422.         // check specific engines
  423.         if (!empty($engine)) {
  424.             $engines $engine;
  425.             if (!is_array($engine)) $engines array($engine);
  426.  
  427.             // iterate over engines
  428.             foreach ($engines as $e{
  429.                 if (!isset($this->authz_engines[$e])) {
  430.                     trigger_error(PoAUtils::msg("authz-engine-err"array($e))E_USER_ERROR);
  431.                 }
  432.                 trigger_error(PoAUtils::msg("revoke-user-via"array($e)));
  433.                 $result |= $this->authz_engines[$e]->revoke($user);
  434.             }
  435.         // check all configured engines
  436.         else {
  437.             trigger_error(PoAUtils::msg("revoke"array()));
  438.             // iterate over engines
  439.             foreach ($this->authz_engines as $e{
  440.                 $result |= $e->revoke($user);
  441.             }
  442.         }
  443.  
  444.         $this->clean();
  445.         return $result;
  446.     }
  447.  
  448.     /**
  449.      * Returns the authorization engines configured for the current PoA, or
  450.      * the one specified.
  451.      * @param engine The name of the authorization engine to retrieve.
  452.      *  If more than one engine should be returned then this must be an array.
  453.      * @return The authorization engine(s) requested if it was previously configured.
  454.      *  If none was specified, all configured engines will be returned. An empty
  455.      *  array will be returned if no authorization engines were found.
  456.      */
  457.     public function getAuthorizationEngines($engine null{
  458.         // register autoload function
  459.         set_exception_handler(array($this->handler"exceptionHandler"));
  460.         set_error_handler(array($this->handler"errorHandler"));
  461.  
  462.         $list $this->authz_engines;
  463.         // check specific engines
  464.         if (!empty($engine)) {
  465.             $list array();
  466.             $engines $engine;
  467.             if (!is_array($engine)) $engines array($engine);
  468.  
  469.             // iterate over engines
  470.             foreach ($engines as $e{
  471.                 if (!isset($this->authz_engines[$e])) {
  472.                     trigger_error(PoAUtils::msg("authz-engine-err"array($e))E_USER_ERROR);
  473.                 }
  474.                 $list[$e$this->authz_engines[$e];
  475.             }
  476.         }
  477.  
  478.         $this->clean();
  479.         return $list;
  480.     }
  481.  
  482.     /**
  483.      * Get the authorization levels that match for the user specified, according to the configuration.
  484.      * An array with the names of the levels matching the user is returned. An empty array is
  485.      * returned if no match is found.
  486.      * @param user The user identifier.
  487.      * @param attributes An array of attributes available for the user.
  488.      * @return An array with the names of the levels matching the user, if any. An empty array will
  489.      *  be returned if no match. Exception will be raised if no levels are defined for this PoA.
  490.      */
  491.     public function getAuthorizationLevels($user$attributes{
  492.         // register autoload function
  493.         set_exception_handler(array($this->handler"exceptionHandler"));
  494.         set_error_handler(array($this->handler"errorHandler"));
  495.  
  496.         $levels $this->cfg->getAuthzLevels();
  497.         $verified array();
  498.         if (empty($levels)) {
  499.             trigger_error(PoAUtils::msg('authz-levels-err'array())E_USER_ERROR);
  500.         }
  501.  
  502.         foreach ($levels as $level{
  503.             // TODO
  504.         }
  505.  
  506.         return $verified;
  507.     }
  508.  
  509. }
  510.  
  511. ?>

Documentation generated on Fri, 11 Feb 2011 10:58:04 +0100 by phpDocumentor 1.4.3