Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ repos:
files: \.php$
exclude: |
(?x)^(
resources/lib/UnitySite\.php$|
resources/lib/UnityHTTPD\.php$|
workers/.*|
)$
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* The maximum line length for any PHP file is 100 characters, instead of PSR-12's 120 characters.
* Comments should be used sparingly.
* Empty lines should be used sparingly.
* No code should call `die()` or `exit()`, instead `UnitySite::die()`. This will avoid the premature death of our automated testing processes.
* No code should call `die()` or `exit()`, instead `UnityHTTPD::die()`. This will avoid the premature death of our automated testing processes.
* Instead of `assert`, use `\ensure`. This will enforce conditions even in production.

This repository will automatically check PRs for linting compliance.
Expand Down
2 changes: 1 addition & 1 deletion coverage.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
return [
new MinCoverageRule(
pattern: '*',
minCoverage: 63,
minCoverage: 62,
exitOnLowCoverage: true
),
];
2 changes: 1 addition & 1 deletion resources/autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
require_once __DIR__ . "/lib/UnitySQL.php";
require_once __DIR__ . "/lib/UnityMailer.php";
require_once __DIR__ . "/lib/UnitySSO.php";
require_once __DIR__ . "/lib/UnitySite.php";
require_once __DIR__ . "/lib/UnityHTTPD.php";
require_once __DIR__ . "/lib/UnityConfig.php";
require_once __DIR__ . "/lib/UnityWebhook.php";
require_once __DIR__ . "/lib/UnityRedis.php";
Expand Down
4 changes: 2 additions & 2 deletions resources/init.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
use UnityWebPortal\lib\UnityRedis;
use UnityWebPortal\lib\UnityWebhook;
use UnityWebPortal\lib\UnityGithub;
use UnityWebPortal\lib\UnitySite;
use UnityWebPortal\lib\UnityHTTPD;

register_shutdown_function(array("UnityWebPortal\lib\UnitySite", "shutdown"));
register_shutdown_function(array("UnityWebPortal\lib\UnityHTTPD", "shutdown"));
// shutdown function logs errors, don't want duplicate output
ini_set("log_errors", false);

Expand Down
4 changes: 2 additions & 2 deletions resources/lib/UnityGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -349,11 +349,11 @@ public function newUserRequest(
$send_mail = true
) {
if ($this->userExists($new_user)) {
UnitySite::errorLog("warning", "user '$new_user' already in group");
UnityHTTPD::errorLog("warning", "user '$new_user' already in group");
return;
}
if ($this->requestExists($new_user)) {
UnitySite::errorLog("warning", "user '$new_user' already requested group membership");
UnityHTTPD::errorLog("warning", "user '$new_user' already requested group membership");
return;
}
if ($this->SQL->accDeletionRequestExists($new_user->uid)) {
Expand Down
27 changes: 1 addition & 26 deletions resources/lib/UnitySite.php → resources/lib/UnityHTTPD.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

namespace UnityWebPortal\lib;

use phpseclib3\Crypt\PublicKeyLoader;
use UnityWebPortal\lib\exceptions\NoDieException;
use UnityWebPortal\lib\exceptions\ArrayKeyException;

class UnitySite
class UnityHTTPD
{
public static function die($x = null, $show_user = false)
{
Expand Down Expand Up @@ -172,28 +171,4 @@ public static function alert(string $message)
// json_encode escapes quotes
echo "<script type='text/javascript'>alert(" . json_encode($message) . ");</script>";
}

public static function testValidSSHKey($key_str)
{
// key loader still throws, these just mute warnings for phpunit
// https://github.com/phpseclib/phpseclib/issues/2079
if ($key_str == "") {
return false;
}
// https://github.com/phpseclib/phpseclib/issues/2076
// https://github.com/phpseclib/phpseclib/issues/2077
// there are actually valid JSON keys (JWK), but I don't think anybody uses it
if (!is_null(@json_decode($key_str))) {
return false;
}
try {
PublicKeyLoader::load($key_str);
return true;
// phpseclib should throw only NoKeyLoadedException but that is not the case
// https://github.com/phpseclib/phpseclib/pull/2078
// } catch (\phpseclib3\Exception\NoKeyLoadedException $e) {
} catch (\Throwable $e) {
return false;
}
}
}
8 changes: 4 additions & 4 deletions resources/lib/UnityLDAP.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public function getNextUIDGIDNumber($uid)
return $customMappedID;
}
if (!is_null($customMappedID) && in_array($customMappedID, $IDNumsInUse)) {
UnitySite::errorLog(
UnityHTTPD::errorLog(
"warning",
"user '$uid' has a custom mapped IDNumber $customMappedID but it's already in use!",
);
Expand Down Expand Up @@ -157,7 +157,7 @@ private function getCustomIDMappings()
array_push($output, $row);
}
} else {
UnitySite::errorLog(
UnityHTTPD::errorLog(
"warning",
"custom ID mapping file '$filename' ignored, extension != .csv",
);
Expand Down Expand Up @@ -330,7 +330,7 @@ public function getAllPIGroupOwnerAttributes($attributes)
array_map(fn($x) => $x["uid"][0], $owner_attributes)
);
if (count($owners_not_found) > 0) {
UnitySite::errorLog(
UnityHTTPD::errorLog(
"warning",
"PI group owners not found: " . json_encode($owners_not_found) . "\n"
);
Expand All @@ -353,7 +353,7 @@ public function getAllUID2PIGIDs()
if (array_key_exists($uid, $uid2pigids)) {
array_push($uid2pigids[$uid], $gid);
} else {
UnitySite::errorLog(
UnityHTTPD::errorLog(
"warning",
"user '$uid' is a member of a PI group but is not a Unity user!"
);
Expand Down
2 changes: 1 addition & 1 deletion resources/lib/UnityRedis.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function setCache($object, $key, $data)
$keyStr = $object;
}
if (is_null($data)) {
UnitySite::errorLog("warning", "setting '$keyStr' to null");
UnityHTTPD::errorLog("warning", "setting '$keyStr' to null");
}
$this->client->set($keyStr, serialize($data));
}
Expand Down
25 changes: 25 additions & 0 deletions resources/lib/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use UnityWebPortal\lib\exceptions\ArrayKeyException;
use UnityWebPortal\lib\exceptions\EnsureException;
use phpseclib3\Crypt\PublicKeyLoader;

function arrayGet($array, ...$keys)
{
Expand All @@ -28,3 +29,27 @@ function ensure(bool $condition, ?string $message = null)
throw new EnsureException($message ?? "ensure condition is false");
}
}

function testValidSSHKey($key_str)
{
// key loader still throws, these just mute warnings for phpunit
// https://github.com/phpseclib/phpseclib/issues/2079
if ($key_str == "") {
return false;
}
// https://github.com/phpseclib/phpseclib/issues/2076
// https://github.com/phpseclib/phpseclib/issues/2077
// there are actually valid JSON keys (JWK), but I don't think anybody uses it
if (!is_null(@json_decode($key_str))) {
return false;
}
try {
PublicKeyLoader::load($key_str);
return true;
// phpseclib should throw only NoKeyLoadedException but that is not the case
// https://github.com/phpseclib/phpseclib/pull/2078
// } catch (\phpseclib3\Exception\NoKeyLoadedException $e) {
} catch (\Throwable $e) {
return false;
}
}
10 changes: 5 additions & 5 deletions resources/templates/header.php
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
<?php

use UnityWebPortal\lib\UnitySite;
use UnityWebPortal\lib\UnityHTTPD;

if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (
($_SESSION["is_admin"] ?? false) == true
&& ($_POST["form_type"] ?? null) == "clearView"
) {
unset($_SESSION["viewUser"]);
UnitySite::redirect(CONFIG["site"]["prefix"] . "/admin/user-mgmt.php");
UnityHTTPD::redirect(CONFIG["site"]["prefix"] . "/admin/user-mgmt.php");
}
// Webroot files need to handle their own POSTs before loading the header
// so that they can do UnitySite::badRequest before anything else has been printed.
// so that they can do UnityHTTPD::badRequest before anything else has been printed.
// They also must not redirect like standard PRG practice because this
// header also needs to handle POST data. So this header does the PRG redirect
// for all pages.
unset($_POST); // unset ensures that header must not come before POST handling
UnitySite::redirect(CONFIG["site"]["prefix"] . $_SERVER['REQUEST_URI']);
UnityHTTPD::redirect(CONFIG["site"]["prefix"] . $_SERVER['REQUEST_URI']);
}

if (isset($SSO)) {
if (
!$_SESSION["user_exists"]
&& !str_ends_with($_SERVER['PHP_SELF'], "/panel/new_account.php")
) {
UnitySite::redirect(CONFIG["site"]["prefix"] . "/panel/new_account.php");
UnityHTTPD::redirect(CONFIG["site"]["prefix"] . "/panel/new_account.php");
}
}

Expand Down
6 changes: 3 additions & 3 deletions test/assert-no-die-exit.bash
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ rc=0

# --color=never because magit git output log doesn't support it
die_occurrences="$(
grep -H --color=never --line-number -P '\bdie\s*[\(;]' "$@" | grep -v -P 'UnitySite::die'
grep -H --color=never --line-number -P '\bdie\s*[\(;]' "$@" | grep -v -P 'UnityHTTPD::die'
)" || true
if [ -n "$die_occurrences" ]; then
echo "die is not allowed! use UnitySite::die() instead."
echo "die is not allowed! use UnityHTTPD::die() instead."
echo "$die_occurrences"
rc=1
fi

# --color=never because magit git output log doesn't support it
exit_occurrences="$(grep -H --color=never --line-number -P '\bexit\s*[\(;]' "$@")" || true
if [ -n "$exit_occurrences" ]; then
echo "exit is not allowed! use UnitySite::die() instead."
echo "exit is not allowed! use UnityHTTPD::die() instead."
echo "$exit_occurrences"
rc=1
fi
Expand Down
2 changes: 1 addition & 1 deletion test/functional/ViewAsUserTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

use UnityWebPortal\lib\UnitySite;
use UnityWebPortal\lib\UnityHTTPD;
use PHPUnit\Framework\TestCase;

class ViewAsUserTest extends TestCase
Expand Down
2 changes: 1 addition & 1 deletion test/phpunit-bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
require_once __DIR__ . "/../resources/lib/UnitySQL.php";
require_once __DIR__ . "/../resources/lib/UnityMailer.php";
require_once __DIR__ . "/../resources/lib/UnitySSO.php";
require_once __DIR__ . "/../resources/lib/UnitySite.php";
require_once __DIR__ . "/../resources/lib/UnityHTTPD.php";
require_once __DIR__ . "/../resources/lib/UnityConfig.php";
require_once __DIR__ . "/../resources/lib/UnityWebhook.php";
require_once __DIR__ . "/../resources/lib/UnityRedis.php";
Expand Down
2 changes: 1 addition & 1 deletion test/unit/AjaxSshValidateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class AjaxSshValidateTest extends TestCase
{
public static function providerTestSshValidate()
{
// sanity check only, see UnitySiteTest for more comprehensive test cases
// sanity check only, see UnityHTTPDTest for more comprehensive test cases
return [
[false, "foobar"],
[true, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB+XqO25MUB9x/pS04I3JQ7rMGboWyGXh0GUzkOrTi7a"],
Expand Down
6 changes: 2 additions & 4 deletions test/unit/UnitySiteTest.php → test/unit/UnityHTTPDTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
// use PHPUnit\Framework\Attributes\BackupGlobals;
// use PHPUnit\Framework\Attributes\RunTestsInSeparateProcess;

class UnitySiteTest extends TestCase
class UnityHTTPDTest extends TestCase
{
public static function SSHKeyProvider()
{
Expand Down Expand Up @@ -77,6 +75,6 @@ public static function SSHKeyProvider()
#[DataProvider("SSHKeyProvider")]
public function testTestValidSSHKey(bool $expected, string $key)
{
$this->assertEquals($expected, UnitySite::testValidSSHKey($key));
$this->assertEquals($expected, testValidSSHKey($key));
}
}
6 changes: 3 additions & 3 deletions webroot/admin/ajax/get_group_members.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
require_once __DIR__ . "/../../../resources/autoload.php";

use UnityWebPortal\lib\UnityGroup;
use UnityWebPortal\lib\UnitySite;
use UnityWebPortal\lib\UnityHTTPD;

if (!$USER->isAdmin()) {
UnitySite::forbidden("not an admin");
UnityHTTPD::forbidden("not an admin");
}

if (!isset($_GET["gid"])) {
UnitySite::badRequest("PI UID not set");
UnityHTTPD::badRequest("PI UID not set");
}

$group = new UnityGroup($_GET["gid"], $LDAP, $SQL, $MAILER, $REDIS, $WEBHOOK);
Expand Down
6 changes: 3 additions & 3 deletions webroot/admin/ajax/get_page_contents.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

require_once __DIR__ . "/../../../resources/autoload.php";

use UnityWebPortal\lib\UnitySite;
use UnityWebPortal\lib\UnityHTTPD;

if (!$USER->isAdmin()) {
UnitySite::forbidden("not an admin");
UnityHTTPD::forbidden("not an admin");
}

if (!isset($_GET["pageid"])) {
UnitySite::badRequest("Pageid not found");
UnityHTTPD::badRequest("Pageid not found");
}

$page = $SQL->getPage($_GET["pageid"]);
Expand Down
4 changes: 2 additions & 2 deletions webroot/admin/content.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

require_once __DIR__ . "/../../resources/autoload.php";

use UnityWebPortal\lib\UnitySite;
use UnityWebPortal\lib\UnityHTTPD;

if (!$USER->isAdmin()) {
UnitySite::forbidden("not an admin");
UnityHTTPD::forbidden("not an admin");
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
Expand Down
4 changes: 2 additions & 2 deletions webroot/admin/notices.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

require_once __DIR__ . "/../../resources/autoload.php";

use UnityWebPortal\lib\UnitySite;
use UnityWebPortal\lib\UnityHTTPD;

if (!$USER->isAdmin()) {
UnitySite::forbidden("not an admin");
UnityHTTPD::forbidden("not an admin");
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
Expand Down
4 changes: 2 additions & 2 deletions webroot/admin/pi-mgmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

use UnityWebPortal\lib\UnityUser;
use UnityWebPortal\lib\UnityGroup;
use UnityWebPortal\lib\UnitySite;
use UnityWebPortal\lib\UnityHTTPD;

if (!$USER->isAdmin()) {
UnitySite::forbidden("not an admin");
UnityHTTPD::forbidden("not an admin");
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
Expand Down
6 changes: 3 additions & 3 deletions webroot/admin/user-mgmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

require_once __DIR__ . "/../../resources/autoload.php";

use UnityWebPortal\lib\UnitySite;
use UnityWebPortal\lib\UnityHTTPD;

if (!$USER->isAdmin()) {
UnitySite::forbidden("not an admin");
UnityHTTPD::forbidden("not an admin");
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
switch ($_POST["form_type"]) {
case "viewAsUser":
$_SESSION["viewUser"] = $_POST["uid"];
UnitySite::redirect(CONFIG["site"]["prefix"] . "/panel/account.php");
UnityHTTPD::redirect(CONFIG["site"]["prefix"] . "/panel/account.php");
break;
}
}
Expand Down
Loading