diff --git a/resources/init.php b/resources/init.php index c56c3d48..c295a7c1 100644 --- a/resources/init.php +++ b/resources/init.php @@ -15,6 +15,8 @@ use UnityWebPortal\lib\UnitySite; use UnityWebPortal\lib\exceptions\SSOException; +register_shutdown_function(array("UnityWebPortal\lib\UnitySite", "shutdown")); + session_start(); $REDIS = new UnityRedis(); @@ -30,19 +32,7 @@ $GITHUB = new UnityGithub(); if (isset($_SERVER["REMOTE_USER"])) { // Check if SSO is enabled on this page - try { - $SSO = UnitySSO::getSSO(); - } catch (SSOException $e) { - $errorid = uniqid("sso-"); - $eppn = $_SERVER["REMOTE_USER"]; - UnitySite::errorLog("SSO Failure", "{$e} ($errorid)"); - UnitySite::die( - "Invalid eppn: '$eppn'. Please contact support at " - . CONFIG["mail"]["support"] - . " (id: $errorid)", - true - ); - } + $SSO = UnitySSO::getSSO(); $_SESSION["SSO"] = $SSO; $OPERATOR = new UnityUser($SSO["user"], $LDAP, $SQL, $MAILER, $REDIS, $WEBHOOK); diff --git a/resources/lib/UnitySite.php b/resources/lib/UnitySite.php index 10b678fc..578a41ea 100644 --- a/resources/lib/UnitySite.php +++ b/resources/lib/UnitySite.php @@ -59,6 +59,7 @@ public static function badRequest($message) { self::headerResponseCode(400, "bad request"); self::errorLog("bad request", $message); + error_clear_last(); self::die($message); } @@ -66,9 +67,37 @@ public static function forbidden($message) { self::headerResponseCode(403, "forbidden"); self::errorLog("forbidden", $message); + error_clear_last(); self::die($message); } + // https://www.php.net/manual/en/function.register-shutdown-function.php + public static function shutdown() + { + if (!is_null($e = error_get_last())) { + self::headerResponseCode(500, "internal server error"); + $errorid = uniqid(); + $e["unity_error_id"] = $errorid; + self::errorLog("internal server error", json_encode($e)); + echo " +
+ Please notify a Unity admin at " + . CONFIG["mail"]["support"] + . ". Error ID: $errorid. +
+ "; + // if content already printed, status code will be ignored and alert text may not be + // shown in the webpage in an obvious way, so make a popup + self::alert( + "An internal server error has occurred. " + . "Please notify a Unity admin at " + . CONFIG["mail"]["support"] + . ". Error ID: $errorid." + ); + } + } + public static function arrayGetOrBadRequest(array $array, ...$keys) { $cursor = $array; @@ -83,6 +112,8 @@ public static function arrayGetOrBadRequest(array $array, ...$keys) return $cursor; } + // in firefox, the user can disable alert/confirm/prompt after the 2nd or 3rd popup + // after I disable alerts, if I quit and reopen my browser, the alerts come back public static function alert(string $message) { // json_encode escapes quotes diff --git a/test/functional/InvalidEPPNTest.php b/test/functional/InvalidEPPNTest.php index 658a88e8..239d9d91 100644 --- a/test/functional/InvalidEPPNTest.php +++ b/test/functional/InvalidEPPNTest.php @@ -1,6 +1,6 @@ expectException(PhpUnitNoDieException::class); - $this->expectExceptionMessageMatches("/.*Invalid eppn.*/"); + $this->expectException(SSOException::class); } try { $_SERVER["REMOTE_USER"] = $eppn;