/** * Return current user if it exists. * * @return User instance or false */ public static function user() { if (is_null(self::$user)) { // Not already cached self::$user = false; // Authentication logic $event = new Event('auth_check'); $auth = $event->trigger(function () { // No authentification is required by application if (!Config::get('auth_sp_type')) { return array(); } // Check for local authentificaiton (script) if (AuthLocal::isAuthenticated()) { return array('local', AuthLocal::attributes()); } // Check for remote application/user if ((Config::get('auth_remote_application_enabled') || Config::get('auth_remote_user_enabled')) && AuthRemote::isAuthenticated() && (AuthRemote::application() && Config::get('auth_remote_application_enabled') || !AuthRemote::application() && Config::get('auth_remote_user_enabled'))) { return array('remote', AuthRemote::attributes(), AuthRemote::application() && AuthRemote::isAdmin()); } // Check for SP autentification if (AuthSP::isAuthenticated()) { return array('sp', AuthSP::attributes()); } return array(); }); self::$type = array_shift($auth); self::$attributes = array_shift($auth); if (count($auth)) { self::$isAdmin = array_shift($auth); } if (self::$attributes && array_key_exists('uid', self::$attributes)) { $user_filter = Config::get('auth_user_filter'); if ($user_filter) { self::$allowed = false; if (is_string($user_filter)) { if (preg_match('`^([^:]+):(.+)$`', $user_filter, $p)) { self::$allowed = array_key_exists($p[1], self::$attributes) && preg_match('`' . $p[2] . '`', self::$attributes[$p[1]]); } } else { self::$allowed = !(bool) $user_filter; } if (!self::$allowed) { self::$type = null; return; } } // Set user if got uid attribute self::$user = User::fromAttributes(self::$attributes); // Save user additionnal attributes if enabled if (self::isSP() && Config::get('auth_sp_save_user_additional_attributes') && array_key_exists('additional', self::$attributes) && self::$user->additional_attributes != self::$attributes['additional']) { self::$user->additional_attributes = self::$attributes['additional']; self::$user->save(); } } } return self::$user; }
/** * Authentication check. * * @return bool */ public static function isAuthenticated() { if (is_null(self::$isAuthenticated)) { self::$isAuthenticated = false; // Do we have remote authentication data in the request ? if (!array_key_exists('signature', $_GET)) { return false; } if (!array_key_exists('timestamp', $_GET)) { return false; } $application = array_key_exists('remote_application', $_GET) ? $_GET['remote_application'] : null; $uid = array_key_exists('remote_user', $_GET) ? $_GET['remote_user'] : null; if (!$application && !$uid) { return false; } self::$attributes = array(); // Get data $received_signature = $_GET['signature']; $timestamp = (int) $_GET['timestamp']; if ($application) { // Check that application is known $applications = Config::get('auth_remote_applications'); if (!is_array($applications) || !array_key_exists($application, $applications)) { throw new AuthRemoteUknownApplicationException($application); } $application = new RemoteApplication($application, $applications[$application]); } // Check request time to avoid replays $late = time() - $timestamp - 15; if ($late > 0) { throw new AuthRemoteTooLateException($late); } // Get method from headers $method = null; foreach (array('X_HTTP_METHOD_OVERRIDE', 'REQUEST_METHOD') as $k) { if (!array_key_exists($k, $_SERVER)) { continue; } $method = strtolower($_SERVER[$k]); } // Build signed data $signed = $method . '&' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME'] . (array_key_exists('PATH_INFO', $_SERVER) ? $_SERVER['PATH_INFO'] : ''); $args = $_GET; unset($args['signature']); if (count($args)) { $signed .= '?' . implode('&', RestUtilities::flatten($args)); } $input = Request::body(); if ($input) { $signed .= '&' . $input; } // Check signature if ($application) { $secret = $application->secret; } else { // Get user, fail if unknown or no user secret try { $user = User::fromId($uid); } catch (UserNotFoundException $e) { throw new AuthRemoteUserRejectedException($uid, 'user not found'); } if (!$user->auth_secret) { throw new AuthRemoteUserRejectedException($user->id, 'no secret set'); } $secret = $user->auth_secret; } $algorithm = Config::get('auth_remote_signature_algorithm'); if (!$algorithm) { $algorithm = 'sha1'; } $signature = hash_hmac($algorithm, $signed, $secret); if ($received_signature !== $signature) { throw new AuthRemoteSignatureCheckFailedException($signed, $secret, $received_signature, $signature); } // Register user id if given if ($uid) { self::$attributes['uid'] = $uid; } // Register admin level if asked for and enabled if ($application) { self::$isAdmin = $application->isAdmin; self::$application = $application; self::$attributes['remote_application'] = $application->name; } self::$isAuthenticated = true; } return self::$isAuthenticated; }