diff options
Diffstat (limited to 'engine/classes/ElggPAM.php')
| -rw-r--r-- | engine/classes/ElggPAM.php | 105 | 
1 files changed, 105 insertions, 0 deletions
| diff --git a/engine/classes/ElggPAM.php b/engine/classes/ElggPAM.php new file mode 100644 index 000000000..f07095fc1 --- /dev/null +++ b/engine/classes/ElggPAM.php @@ -0,0 +1,105 @@ +<?php +/** + * ElggPAM Pluggable Authentication Module + * + * @package    Elgg.Core + * @subpackage Authentication + */ +class ElggPAM { +	/** +	 * @var string PAM policy type: user, api or plugin-defined policies +	 */ +	protected $policy; + +	/** +	 * @var array Failure mesages +	 */ +	protected $messages; + +	/** +	 * ElggPAM constructor +	 *  +	 * @param string $policy PAM policy type: user, api, or plugin-defined policies +	 */ +	public function __construct($policy) { +		$this->policy = $policy; +		$this->messages = array('sufficient' => array(), 'required' => array()); +	} + +	/** +	 * Authenticate a set of credentials against a policy +	 * This function will process all registered PAM handlers or stop when the first +	 * handler fails. A handler fails by either returning false or throwing an +	 * exception. The advantage of throwing an exception is that it returns a message +	 * that can be passed to the user. The processing order of the handlers is +	 * determined by the order that they were registered. +	 * +	 * If $credentials are provided, the PAM handler should authenticate using the +	 * provided credentials. If not, then credentials should be prompted for or +	 * otherwise retrieved (eg from the HTTP header or $_SESSION). +	 * +	 * @param array $credentials Credentials array dependant on policy type +	 * @return bool +	 */ +	public function authenticate($credentials = array()) { +		global $_PAM_HANDLERS; + +		if (!isset($_PAM_HANDLERS[$this->policy]) || +			!is_array($_PAM_HANDLERS[$this->policy])) { +			return false; +		} + +		$authenticated = false; + +		foreach ($_PAM_HANDLERS[$this->policy] as $k => $v) { +			$handler = $v->handler; +			if (!is_callable($handler)) { +				continue; +			} +			/* @var callable $handler */ + +			$importance = $v->importance; + +			try { +				// Execute the handler +				// @todo don't assume $handler is a global function +				$result = call_user_func($handler, $credentials); +				if ($result) { +					$authenticated = true; +				} elseif ($result === false) { +					if ($importance == 'required') { +						$this->messages['required'][] = "$handler:failed"; +						return false; +					} else { +						$this->messages['sufficient'][] = "$handler:failed"; +					} +				} +			} catch (Exception $e) { +				if ($importance == 'required') { +					$this->messages['required'][] = $e->getMessage(); +					return false; +				} else { +					$this->messages['sufficient'][] = $e->getMessage(); +				} +			} +		} + +		return $authenticated; +	} + +	/** +	 * Get a failure message to display to user +	 *  +	 * @return string +	 */ +	public function getFailureMessage() { +		$message = elgg_echo('auth:nopams'); +		if (!empty($this->messages['required'])) { +			$message = $this->messages['required'][0]; +		} elseif (!empty($this->messages['sufficient'])) { +			$message = $this->messages['sufficient'][0]; +		} + +		return elgg_trigger_plugin_hook('fail', 'auth', $this->messages, $message); +	} +} | 
