Skip to content
2 changes: 1 addition & 1 deletion defaults/config.ini.default
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repo = "https://github.com/UnityHPC/unity-web-portal" ; Upstream URL for the we
[site]
prefix = "" ; prefix of website, no ending / should be included
name = "Unity Cluster" ; Name of the website
url = "https://127.0.0.1:8000/" ; URL of the website
url = "http://127.0.0.1:8000/" ; URL of the website
description = "The Unity Web Portal is a lightweight HPC cluster front-end" ; Description of the website
logo = "logo.png" ; path to logo file, in the webroot/assets/branding folder
terms_of_service_url = "https://github.com" ; this can be external or a portal page created with "content management"
Expand Down
2 changes: 1 addition & 1 deletion resources/lib/UnityHTTPD.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static function die(mixed $x = null, bool $show_user = false): never
*/
public static function redirect(?string $dest = null): never
{
$dest ??= pathJoin(CONFIG["site"]["prefix"], $_SERVER["REQUEST_URI"]);
$dest ??= getURL($_SERVER["REQUEST_URI"]);
$dest = htmlspecialchars($dest);
header("Location: $dest");
http_response_code(302);
Expand Down
2 changes: 0 additions & 2 deletions resources/lib/UnityMailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class UnityMailer extends PHPMailer
private string $template_dir = __DIR__ . "/../mail"; // location of all email templates
private string $override_template_dir = __DIR__ . "/../../deployment/mail_overrides";

private string $MSG_LINKREF;
private string $MSG_SENDER_EMAIL;
private string $MSG_SENDER_NAME;
private string $MSG_SUPPORT_EMAIL;
Expand All @@ -28,7 +27,6 @@ public function __construct()
parent::__construct();
$this->isSMTP();

$this->MSG_LINKREF = CONFIG["site"]["url"] . CONFIG["site"]["prefix"];
$this->MSG_SENDER_EMAIL = CONFIG["mail"]["sender"];
$this->MSG_SENDER_NAME = CONFIG["mail"]["sender_name"];
$this->MSG_SUPPORT_EMAIL = CONFIG["mail"]["support"];
Expand Down
5 changes: 0 additions & 5 deletions resources/lib/UnityWebhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ class UnityWebhook
private string $template_dir = __DIR__ . "/../mail";
private string $override_template_dir = __DIR__ . "/../../deployment/mail_overrides";
private string $url = CONFIG["webhook"]["url"];
private string $MSG_LINKREF;
private string $Subject; // set by template

public function __construct()
{
$this->MSG_LINKREF = CONFIG["site"]["url"] . CONFIG["site"]["prefix"];
}
public function htmlToMarkdown(string $html): string
{
// Define regex patterns for each markdown format
Expand Down
29 changes: 22 additions & 7 deletions resources/lib/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,28 @@ function mbDetectEncoding(string $string, ?array $encodings = null, mixed $_ = n
}

/* https://stackoverflow.com/a/15575293/18696276 */
function pathJoin()
function pathNormalize(string $path)
{
$paths = [];
foreach (func_get_args() as $arg) {
if ($arg !== "") {
$paths[] = $arg;
}
return preg_replace("#/+#", "/", $path);
}

function getURL(...$relative_url_components)
{
if (!preg_match("#^\w+://#", CONFIG["site"]["url"])) {
throw new RuntimeException('CONFIG[site][url] does not have a scheme! (ex: "https://")');
}
return preg_replace("#/+#", "/", join("/", $paths));
$matches = [];
preg_match("#(^\w+://)(.*)#", CONFIG["site"]["url"], $matches);
[$_, $site_url_scheme, $site_url_noscheme] = $matches;
$path = join("/", [$site_url_noscheme, CONFIG["site"]["prefix"], ...$relative_url_components]);
$path_normalized = pathNormalize($path);
return $site_url_scheme . $path_normalized;
}

function getHyperlink($text, ...$url_components)
{
$text = htmlspecialchars($text);
$url_components = array_map("htmlspecialchars", $url_components);
$url = getURL(...$url_components);
return "<a href='$url'>$text</a>";
}
2 changes: 1 addition & 1 deletion resources/mail/footer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
>
<span>
You are receiving this email because you have an account
on the <a target='_blank' href='<?php echo $this->MSG_LINKREF; ?>'>Unity Cluster</a>.
on the <?php echo getHyperlink("Unity Cluster", "/"); ?>.
If you would like to stop receiving these emails,
you may request to close your account by replying to this email.
</span>
Expand Down
2 changes: 1 addition & 1 deletion resources/mail/group_created.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<p>
Your request for a PI account on the Unity cluster has been approved.
You can access the management page for your group
<a href="<?php echo $this->MSG_LINKREF; ?>/panel/pi.php">on this page</a>.
<?php echo getHyperlink("on this page", "panel/pi.php"); ?>.
</p>

<p>Do not hesitate to reply if you have any questions!</p>
2 changes: 1 addition & 1 deletion resources/mail/group_request_admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@

<p>
You can approve this account
<a href="<?php echo $this->MSG_LINKREF; ?>/admin/pi-mgmt.php">here</a>
<?php echo getHyperlink("here", "admin/pi-mgmt.php"); ?>
.
</p>
2 changes: 1 addition & 1 deletion resources/mail/group_user_added.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<p>Hello,</p>

<p>You have been approved to join the PI group <?php echo $data["group"]; ?>.
Navigate to the <a href="<?php echo $this->MSG_LINKREF; ?>/panel/groups.php">my groups</a>
Navigate to the <?php echo getHyperlink("my groups", "panel/groups.php"); ?>
page to see your PI groups.</p>

<p>If you believe this to be a mistake, please reply to this email as soon as possible.</p>
2 changes: 1 addition & 1 deletion resources/mail/group_user_request_owner.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
</p>

<p>You can approve or deny this user on the
<a href="<?php echo $this->MSG_LINKREF; ?>/panel/pi.php">my users</a> page</p>
<?php echo getHyperlink("my users", "panel/pi.php"); ?> page</p>
2 changes: 1 addition & 1 deletion resources/mail/user_loginshell.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

<p>You have updated your login shell on the Unity cluster to <?php echo $data["new_shell"]; ?>.
You can view the login shell settings on the
<a href="<?php echo $this->MSG_LINKREF; ?>/panel/account.php">account settings</a> page</p>
<?php echo getHyperlink("account settings", "panel/account.php"); ?> page</p>

<p>If you believe this to be a mistake, please reply to this email as soon as possible.</p>
2 changes: 1 addition & 1 deletion resources/mail/user_qualified.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@

<p>Please login to the web portal to access Unity.
If you need console access, you will need to set your SSH keys in the
<a href="<?php echo $this->MSG_LINKREF; ?>/panel/account.php">account settings</a> page.</p>
<?php echo getHyperlink("account settings", "/panel/account.php"); ?> page.</p>

<p>If you believe this to be a mistake, please reply to this email as soon as possible.</p>
2 changes: 1 addition & 1 deletion resources/mail/user_sshkey.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<p>
You can view the SSH public keys attached to your account on the
<a href="<?php echo $this->MSG_LINKREF; ?>/panel/account.php">account settings</a>
<?php echo getHyperlink("account settings", "/panel/account.php"); ?>
page.
</p>

Expand Down
14 changes: 7 additions & 7 deletions resources/templates/footer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
for ($i = 0; $i < count($footer_logos); $i++) {
echo
"<a target='_blank' href='" . $footer_links[$i] . "'>
<img src='" . CONFIG["site"]["prefix"] . "/assets/" . $footer_logos[$i] . "'
<img src='" . getURL("assets", $footer_logos[$i]) . "'
draggable='false' title='" . $footer_titles[$i] . "'></a>";
}
?>
Expand All @@ -29,10 +29,10 @@
</footer>

</body>

<script src="<?php echo CONFIG["site"]["prefix"]; ?>/js/filter.js"></script>
<script src="<?php echo CONFIG["site"]["prefix"]; ?>/js/sort.js"></script>
<script src="<?php echo CONFIG["site"]["prefix"]; ?>/js/global.js"></script>
<script src="<?php echo CONFIG["site"]["prefix"]; ?>/js/tables.js"></script>

<?php
foreach (["filter", "sort", "global", "tables"] as $x) {
$url = getURL("js/$x.js");
echo "<script src='$url'></script>";
}
?>
</html>
44 changes: 19 additions & 25 deletions resources/templates/header.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
&& ($_POST["form_type"] ?? null) == "clearView"
) {
unset($_SESSION["viewUser"]);
UnityHTTPD::redirect(CONFIG["site"]["prefix"] . "/admin/user-mgmt.php");
UnityHTTPD::redirect(getURL("admin/user-mgmt.php"));
}
// Webroot files need to handle their own POSTs before loading the header
// so that they can do UnityHTTPD::badRequest before anything else has been printed.
Expand All @@ -24,7 +24,7 @@
!$_SESSION["user_exists"]
&& !str_ends_with($_SERVER['PHP_SELF'], "/panel/new_account.php")
) {
UnityHTTPD::redirect(CONFIG["site"]["prefix"] . "/panel/new_account.php");
UnityHTTPD::redirect(getURL("panel/new_account.php"));
}
}

Expand All @@ -49,15 +49,10 @@
</style>

<?php
$prefix = CONFIG["site"]["prefix"];
echo "
<link rel='stylesheet' type='text/css' href='$prefix/css/global.css'>
<link rel='stylesheet' type='text/css' href='$prefix/css/navbar.css'>
<link rel='stylesheet' type='text/css' href='$prefix/css/modal.css'>
<link rel='stylesheet' type='text/css' href='$prefix/css/tables.css'>
<link rel='stylesheet' type='text/css' href='$prefix/css/filters.css'>
<link rel='stylesheet' type='text/css' href='$prefix/css/messages.css'>
";
foreach (["global", "navbar", "modal", "tables", "filters", "messages"] as $x) {
$url = getURL("css/$x.css");
echo "<link rel='stylesheet' type='text/css' href='$url'>";
}
?>

<meta name="viewport" content="width=device-width, initial-scale=1.0">
Expand All @@ -70,21 +65,20 @@

<header>
<img id="imgLogo" draggable=false
src="<?php echo CONFIG["site"]["prefix"]; ?>/assets/<?php echo CONFIG["site"]["logo"]; ?>">
src="<?php echo getURL("assets", CONFIG["site"]["logo"]); ?>">
<button class="hamburger vertical-align">
<img
draggable="false"
src="<?php echo CONFIG["site"]["prefix"]; ?>/assets/menu.png"
src="<?php echo getURL("assets/menu.png") ?>"
alt="Menu Button"
>
</button>
</header>

<nav class="mainNav">
<?php
$prefix = CONFIG["site"]["prefix"];
// Public Items - Always Visible
echo "<a href='$prefix/index.php'>Home</a>";
echo getHyperlink("Home", "index.php");

$num_additional_items = count(CONFIG["menuitems"]["labels"]);
for ($i = 0; $i < $num_additional_items; $i++) {
Expand All @@ -94,13 +88,13 @@

if (isset($_SESSION["user_exists"]) && $_SESSION["user_exists"]) {
// Menu Items for Present Users
echo "<a href='$prefix/panel/support.php'>Support</a>";
echo "<a href='$prefix/panel/account.php'>Account Settings</a>";
echo "<a href='$prefix/panel/groups.php'>My PIs</a>";
echo getHyperlink("Support", "panel/support.php");
echo getHyperlink("Account Settings", "panel/account.php");
echo getHyperlink("My PIs", "panel/groups.php");

if (isset($_SESSION["is_pi"]) && $_SESSION["is_pi"]) {
// PI only pages
echo "<a href='$prefix/panel/pi.php'>My Users</a>";
echo getHyperlink("My Users", "panel/pi.php");
}

// additional branding items
Expand All @@ -116,13 +110,13 @@
) {
echo "<hr class='navHR'>";
// Admin only pages
echo "<a href='$prefix/admin/user-mgmt.php'>User Management</a>";
echo "<a href='$prefix/admin/pi-mgmt.php'>PI Management</a>";
echo "<a href='$prefix/admin/notices.php'>Cluster Notices</a>";
echo "<a href='$prefix/admin/content.php'>Content Management</a>";
echo getHyperlink("User Management", "admin/user-mgmt.php");
echo getHyperlink("PI Management", "admin/pi-mgmt.php");
echo getHyperlink("Cluster Notices", "admin/notices.php");
echo getHyperlink("Content Management", "admin/content.php");
}
} else {
echo "<a href='$prefix/panel/account.php'>Login / Request Account</a>";
echo getHyperlink("Login / Request Account", "panel/account.php");
}
?>
</nav>
Expand All @@ -136,7 +130,7 @@
<div class="modalBody"></div>
</div>
</div>
<script src="<?php echo CONFIG["site"]["prefix"]; ?>/js/modal.js"></script>
<script src="<?php echo getURL("js/modal.js"); ?>"></script>

<main>

Expand Down
25 changes: 25 additions & 0 deletions test/unit/UtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,29 @@ public function testTestValidSSHKey(bool $expected, string $key)
{
$this->assertEquals($expected, testValidSSHKey($key));
}

public static function URLComponentProvider()
{
if (CONFIG["site"]["url"] != "http://127.0.0.1:8000/") {
throw new RuntimeException("site url has changed!");
}
return [
[["", ""], "http://127.0.0.1:8000/"],
[["", "/"], "http://127.0.0.1:8000/"],
[["/", "a"], "http://127.0.0.1:8000/a"],
[["/", "/a"], "http://127.0.0.1:8000/a"],
[["abc", "def"], "http://127.0.0.1:8000/abc/def"],
[["abc", "/def"], "http://127.0.0.1:8000/abc/def"],
[["/abc", "def"], "http://127.0.0.1:8000/abc/def"],
[["/abc", "def///"], "http://127.0.0.1:8000/abc/def/"],
[["", "foo.jpg"], "http://127.0.0.1:8000/foo.jpg"],
[["dir", "0", "a.jpg"], "http://127.0.0.1:8000/dir/0/a.jpg"],
];
}

#[DataProvider("URLComponentProvider")]
public function testGetURL(array $relative_url_components, string $expected)
{
$this->assertEquals($expected, getURL(...$relative_url_components));
}
}
4 changes: 2 additions & 2 deletions webroot/admin/content.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@
.catch(error => {
console.error(error)
});
const prefix = '<?php echo CONFIG["site"]["prefix"]; ?>';
const url = '<?php echo getURL("admin/ajax/get_page_contents.php"); ?>';
$("#pageForm > select[name=pageSel]").change(function(e) {
$.ajax({
url: `${prefix}/admin/ajax/get_page_contents.php?pageid=` + $(this).val(),
url: `${url}?pageid=` + $(this).val(),
success: function(result) {
mainEditor.setData(result);
}});
Expand Down
2 changes: 1 addition & 1 deletion webroot/admin/pi-mgmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class="filterSearch"
}
});

var ajax_url = "<?php echo CONFIG["site"]["prefix"]; ?>/admin/ajax/get_group_members.php?gid=";
var ajax_url = "<?php echo getURL("admin/ajax/get_group_members.php"); ?>?gid=";
</script>

<?php
Expand Down
2 changes: 1 addition & 1 deletion webroot/admin/user-mgmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
switch ($_POST["form_type"]) {
case "viewAsUser":
$_SESSION["viewUser"] = $_POST["uid"];
UnityHTTPD::redirect(CONFIG["site"]["prefix"] . "/panel/account.php");
UnityHTTPD::redirect(getURL("panel/account.php"));
break;
}
}
Expand Down
8 changes: 4 additions & 4 deletions webroot/panel/account.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
echo "<p>You are curently a <strong>qualified user</strong> on the Unity Cluster</p>";
} else {
$tos_url = CONFIG["site"]["terms_of_service_url"];
$sitePrefix = CONFIG["site"]["prefix"];
$form_url = getURL("panel/groups.php");
echo "
<p>
You are currently an <strong>unqualified user</strong>, and will be
Expand All @@ -137,7 +137,7 @@
Do not request a PI group if you are a student.
</p>
<br>
<form action='$sitePrefix/panel/groups.php' method='GET'>
<form action='$form_url' method='GET'>
<label>
<input type='checkbox' name='tos' value='agree' required />
I have read and accept the
Expand Down Expand Up @@ -269,11 +269,11 @@
?>

<script>
const sitePrefix = '<?php echo CONFIG["site"]["prefix"]; ?>';
const url = '<?php echo getURL("panel/modal/new_key.php")?>';
const ldapLoginShell = '<?php echo $USER->getLoginShell(); ?>';

$("button.btnAddKey").click(function() {
openModal("Add New Key", `${sitePrefix}/panel/modal/new_key.php`);
openModal("Add New Key", url);
});

$("#loginSelector option").each(function(i, e) {
Expand Down
Loading