3 * Piwik - Open source web analytics
5 * @link http://piwik.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later
9 * @category Piwik_Plugins
13 namespace Piwik\Plugins\CASLogin;
20 use Piwik\Plugins\UsersManager\API;
24 * Class that implements an authentication mechanism via CAS (Central Authentication Services)
26 * @package Piwik_CASLogin
28 class Auth implements \Piwik\Auth
30 protected $login = null;
31 protected $token_auth = null;
32 private static $phpcas_client_called = false;
34 public function getName()
39 public function initSession($login, $md5Password, $rememberMe) {}
41 public function authenticate()
43 // Make sure Piwik session is started.
48 require_once PIWIK_INCLUDE_PATH . '/plugins/CASLogin/CAS/CAS.php';
52 // What happens here: in some piwik functionality, some additional API-style calls are
53 // made from a controller action, where the authenticate() method will be called *again*.
54 // This happens for instance when an admin changes some permissions in Settings->Users.
55 // The first authenticate() is from the page, and the second is due to an API call.
56 // This checks if there was already a phpcas instance already initialized, otherwize
57 // phpCAS::client() would fail.
58 if (!self::$phpcas_client_called) {
60 constant( Config::getInstance()->caslogin['protocol'] ),
61 Config::getInstance()->caslogin['host'],
62 (integer) Config::getInstance()->caslogin['port'],
66 self::$phpcas_client_called = true;
69 // no SSL validation for the CAS server
70 \phpCAS::setNoCasServerValidation();
72 // Handle single signout requests from CAS server
73 \phpCAS::handleLogoutRequests();
75 // force CAS authentication only if it has been requested by action argument
76 $action = Piwik::getAction();
78 $auth = \phpCAS::checkAuthentication();
80 if($action == 'redirectToCAS') {
81 phpCAS::forceAuthentication();
84 if($action != 'login' && Piwik::getModule() != 'CoreUpdater') {
85 Piwik::redirectToModule('CASLogin', 'login');
87 } elseif($action == 'redirectToCAS') {
88 phpCAS::forceAuthentication();
90 return new AuthResult( AuthResult::FAILURE, $user, NULL );
94 // Additional Attributes
95 // For future retrieval of attributes; they _might_ be of some use, but are highly
96 // dependable on a specific installation. CAS|piwik hackers can do some magic
97 // here with SAML attributes etc.
99 foreach (\phpCAS::getAttributes() as $key => $value) {
100 // syslog(LOG_DEBUG, "attribute: $key - ". print_r($value, true));
104 if (isset($_SESSION['phpCAS']) && isset($_SESSION['phpCAS']['user'])) {
105 $user = $_SESSION['phpCAS']['user'];
109 $db_user = Db::fetchRow('SELECT login, superuser_access FROM '.Common::prefixTable('user').' WHERE login = ?',
112 if($db_user === null) {
113 // ***User Autocreate***
114 // We can either add the authenticated but not-yet-authorized user to the piwik users
115 // database, or ignore that.
116 // TODO: make this a config option
117 $this->_populateDb($user);
122 $login = $db_user['login'];
123 $superuser = $db_user['superuser_access'];
128 $code = AuthResult::SUCCESS_SUPERUSER_AUTH_CODE;
129 else $code = AuthResult::SUCCESS;
130 return new AuthResult($code, $login, NULL );
134 return new AuthResult( AuthResult::FAILURE, $user, NULL );
137 public function setLogin($login)
139 $this->login = $login;
141 public function getLogin() {
145 public function setTokenAuth($token_auth)
147 $this->token_auth = $token_auth;
149 public function getTokenAuthSecret() {
150 return $this->token_auth;
154 * This method is used to inject user into Piwik's tables.
155 * @todo Alias could be the 'cn' returned from CAS attributes.
157 private function _populateDb($user)
160 $dummy = md5('abcd1234');
161 if ($this->_helper_userExists($user)) {
162 $this->_helper_updateUser($user, $dummy, '', $user);
164 $this->_helper_addUser($user, $dummy, '', $user);
169 ///// The following methods are taken from Piwik's UserManager, but in order to inject data into piwik's user and access tables, we need
170 ///// to make sure we don't wreck things. The UserManager API uses authenticate() to check if we're eligable to look this up,
171 ///// soi we can't use it - we need superuser permissions anyway.
173 ///// Warning - these methods are of course under Piwik's license.
174 private function _helper_userExists($name)
176 $count = Db::fetchOne("SELECT count(*)
177 FROM ".Common::prefixTable("user"). "
178 WHERE login = ?", $name);
182 private function _helper_updateUser( $userLogin, $password = false, $email = false, $alias = false )
184 $token_auth = API::getTokenAuth($userLogin, $password);
186 Db::get()->update( Common::prefixTable("user"),
188 'password' => $password,
191 'token_auth' => $token_auth,
193 "login = '$userLogin'"
197 private function _helper_addUser( $userLogin, $password, $email, $alias = false )
199 $token_auth = API::getTokenAuth($userLogin, $password);
201 Db::get()->insert( Common::prefixTable("user"), array(
202 'login' => $userLogin,
203 'password' => $password,
206 'token_auth' => $token_auth,
211 // Those methods are required by Piwik API.
212 public function setPassword($password) {}
213 public function setPasswordHash($passwordHash) {}