Skip to content

Commit 9728bb1

Browse files
committed
Merge branch 'main' into validate-ssh-keys
2 parents 880edc7 + 03934e0 commit 9728bb1

25 files changed

+1839
-141
lines changed

.github/workflows/phpunit.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ jobs:
1313
uses: shivammathur/setup-php@v2
1414
with:
1515
php-version: "8.3"
16-
# php extensions also listed in tools/docker-dev/web/Dockerfile
17-
extensions: curl,mysql,ldap,pdo,redis
16+
# php extensions also listed in tools/docker-dev/web/Dockerfile and README.md
17+
extensions: curl,mysql,ldap,pdo,redis,intl
1818
tools: composer:v2
1919
- name: Install dependencies
2020
run: composer install --prefer-dist --no-progress

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@ Unity Web Portal is a PHP application built in top of MariaDB and LDAP which act
2121
1. Some HTTP Authentication mechanism (such as Shibboleth SP)
2222
1. Composer (`apt install composer` on Ubuntu)
2323
1. PHP Extensions
24+
1. `php-cli`
25+
1. `php-curl`
26+
1. `php-intl`
2427
1. `php-ldap`
25-
2. `php-curl`
26-
3. `php-redis`
27-
4. `php-cli`
28-
5. `php-mysql`
29-
6. `php-pdo`
28+
1. `php-mbstring`
29+
1. `php-mysql`
30+
1. `php-pdo`
31+
1. `php-redis`
32+
1. `php-xml`
3033
2. Composer packages
3134
1. `cd` to this repository
3235
1. Setup git submodules `git submodule update --init --checkout`

defaults/config.ini.default

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ url = "https://127.0.0.1:8000/" ; URL of the website
1212
description = "The Unity Web Portal is a lightweight HPC cluster front-end" ; Description of the website
1313
logo = "logo.png" ; path to logo file, in the webroot/assets/branding folder
1414
terms_of_service_url = "https://github.com" ; this can be external or a portal page created with "content management"
15+
account_policy_url = "https://github.com" ; this can be external or a portal page created with "content management"
1516

1617
[ldap]
1718
uri = "ldap://identity" ; URI of remote LDAP server
1819
user = "cn=admin,dc=unityhpc,dc=test" ; Admin bind DN LDAP user
1920
pass = "password" ; Admin bind password
2021
basedn = "dc=unityhpc,dc=test" ; Base search DN
21-
user_ou = "ou=users,dc=unityhpc,dc=test" ; User organizational unit
22+
user_ou = "ou=users,dc=unityhpc,dc=test" ; User organizational unit (may contain more than user group)
23+
user_group = "cn=unityusers,dc=unityhpc,dc=test" ; User group
2224
group_ou = "ou=groups,dc=unityhpc,dc=test" ; Group organizational unit
2325
pigroup_ou = "ou=pi_groups,dc=unityhpc,dc=test" ; PI Group organizational unit
2426
orggroup_ou = "ou=org_groups,dc=unityhpc,dc=test" ; ORG group organizational unit

resources/init.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
$CONFIG["ldap"]["pigroup_ou"],
4646
$CONFIG["ldap"]["orggroup_ou"],
4747
$CONFIG["ldap"]["admin_group"],
48+
$CONFIG["ldap"]["user_group"],
4849
$CONFIG["ldap"]["def_user_shell"]
4950
);
5051

resources/lib/UnityGroup.php

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,41 @@ public function denyGroup($operator = null, $send_mail = true)
198198
}
199199
}
200200

201+
public function cancelGroupRequest($send_mail = true)
202+
{
203+
if (!$this->SQL->requestExists($this->getOwner()->getUID())) {
204+
return;
205+
}
206+
207+
$this->SQL->removeRequest($this->getOwner()->getUID());
208+
209+
if ($send_mail) {
210+
// send email to requestor
211+
$this->MAILER->sendMail(
212+
"admin",
213+
"group_request_cancelled"
214+
);
215+
}
216+
}
217+
218+
public function cancelGroupJoinRequest($user, $send_mail = true)
219+
{
220+
if (!$this->requestExists($user)) {
221+
return;
222+
}
223+
224+
$this->SQL->removeRequest($user->getUID(), $this->pi_uid);
225+
226+
if ($send_mail) {
227+
// send email to requestor
228+
$this->MAILER->sendMail(
229+
$this->getOwner()->getMail(),
230+
"group_join_request_cancelled",
231+
["group" => $this->pi_uid]
232+
);
233+
}
234+
}
235+
201236
// /**
202237
// * This method will delete the group, either by admin action or PI action
203238
// */
@@ -218,8 +253,7 @@ public function denyGroup($operator = null, $send_mail = true)
218253
// // now we delete the ldap entry
219254
// $ldapPiGroupEntry = $this->getLDAPPiGroup();
220255
// if ($ldapPiGroupEntry->exists()) {
221-
// ldapPiGroupEntry->delete();
222-
256+
// $ldapPiGroupEntry->delete();
223257
// $this->REDIS->removeCacheArray("sorted_groups", "", $this->getPIUID());
224258
// foreach ($users as $user) {
225259
// $this->REDIS->removeCacheArray($user->getUID(), "groups", $this->getPIUID());
@@ -252,7 +286,7 @@ public function approveUser($new_user, $send_mail = true)
252286
$this->addUserToGroup($new_user);
253287

254288
// remove request, this will fail silently if the request doesn't exist
255-
$this->removeRequest($new_user->getUID());
289+
$this->SQL->removeRequest($new_user->getUID(), $this->pi_uid);
256290

257291
// send email to the requestor
258292
if ($send_mail) {
@@ -284,7 +318,7 @@ public function denyUser($new_user, $send_mail = true)
284318
}
285319

286320
// remove request, this will fail silently if the request doesn't exist
287-
$this->removeRequest($new_user->getUID());
321+
$this->SQL->removeRequest($new_user->getUID(), $this->pi_uid);
288322

289323
if ($send_mail) {
290324
// send email to the user
@@ -523,11 +557,6 @@ private function addRequest($uid)
523557
$this->SQL->addRequest($uid, $this->pi_uid);
524558
}
525559

526-
private function removeRequest($uid)
527-
{
528-
$this->SQL->removeRequest($uid, $this->pi_uid);
529-
}
530-
531560
//
532561
// Public helper functions
533562
//

resources/lib/UnityLDAP.php

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class UnityLDAP extends ldapConn
3838
private $pi_groupOU;
3939
private $org_groupOU;
4040
private $adminGroup;
41+
private $userGroup;
4142

4243
private $custom_mappings_path;
4344

@@ -53,6 +54,7 @@ public function __construct(
5354
$pigroup_ou,
5455
$orggroup_ou,
5556
$admin_group,
57+
$user_group_dn,
5658
$def_user_shell
5759
) {
5860
parent::__construct($host, $dn, $pass);
@@ -69,6 +71,7 @@ public function __construct(
6971
$this->pi_groupOU = $this->getEntry($pigroup_ou);
7072
$this->org_groupOU = $this->getEntry($orggroup_ou);
7173
$this->adminGroup = $this->getEntry($admin_group);
74+
$this->userGroup = $this->getEntry($user_group_dn);
7275

7376
$this->custom_mappings_path = $custom_user_mappings;
7477

@@ -103,6 +106,11 @@ public function getAdminGroup()
103106
return $this->adminGroup;
104107
}
105108

109+
public function getUserGroup()
110+
{
111+
return $this->userGroup;
112+
}
113+
106114
public function getDefUserShell()
107115
{
108116
return $this->def_user_shell;
@@ -236,10 +244,10 @@ public function getAllUsers($UnitySQL, $UnityMailer, $UnityRedis, $UnityWebhook,
236244
}
237245
}
238246

239-
$users = $this->userOU->getChildren(true);
240-
247+
$users = $this->userGroup->getAttribute("memberuid");
248+
sort($users);
241249
foreach ($users as $user) {
242-
$params = array($user->getAttribute("cn")[0], $this, $UnitySQL, $UnityMailer, $UnityRedis, $UnityWebhook);
250+
$params = array($user, $this, $UnitySQL, $UnityMailer, $UnityRedis, $UnityWebhook);
243251
array_push($out, new UnityUser(...$params));
244252
}
245253

@@ -312,28 +320,24 @@ public function getAllOrgGroups($UnitySQL, $UnityMailer, $UnityRedis, $UnityWebh
312320
public function getUserEntry($uid)
313321
{
314322
$uid = ldap_escape($uid, LDAP_ESCAPE_DN);
315-
$ldap_entry = new LDAPEntry($this->getConn(), unityLDAP::RDN . "=$uid," . $this->STR_USEROU);
316-
return $ldap_entry;
323+
return $this->getEntry(unityLDAP::RDN . "=$uid," . $this->STR_USEROU);
317324
}
318325

319326
public function getGroupEntry($gid)
320327
{
321-
$uid = ldap_escape($gid, LDAP_ESCAPE_DN);
322-
$ldap_entry = new LDAPEntry($this->getConn(), unityLDAP::RDN . "=$gid," . $this->STR_GROUPOU);
323-
return $ldap_entry;
328+
$gid = ldap_escape($gid, LDAP_ESCAPE_DN);
329+
return $this->getEntry(unityLDAP::RDN . "=$gid," . $this->STR_GROUPOU);
324330
}
325331

326332
public function getPIGroupEntry($gid)
327333
{
328-
$uid = ldap_escape($gid, LDAP_ESCAPE_DN);
329-
$ldap_entry = new LDAPEntry($this->getConn(), unityLDAP::RDN . "=$gid," . $this->STR_PIGROUPOU);
330-
return $ldap_entry;
334+
$gid = ldap_escape($gid, LDAP_ESCAPE_DN);
335+
return $this->getEntry(unityLDAP::RDN . "=$gid," . $this->STR_PIGROUPOU);
331336
}
332337

333338
public function getOrgGroupEntry($gid)
334339
{
335-
$uid = ldap_escape($gid, LDAP_ESCAPE_DN);
336-
$ldap_entry = new LDAPEntry($this->getConn(), unityLDAP::RDN . "=$gid," . $this->STR_ORGGROUPOU);
337-
return $ldap_entry;
340+
$gid = ldap_escape($gid, LDAP_ESCAPE_DN);
341+
return $this->getEntry(unityLDAP::RDN . "=$gid," . $this->STR_ORGGROUPOU);
338342
}
339343
}

resources/lib/UnitySQL.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class UnitySQL
2020

2121

2222
// FIXME this string should be changed to something more intuitive, requires production sql change
23-
private const REQUEST_BECOME_PI = "admin";
23+
public const REQUEST_BECOME_PI = "admin";
2424

2525
private $conn;
2626

resources/lib/UnitySite.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@ public static function die($x = null)
2626

2727
public static function redirect($destination)
2828
{
29-
if ($_SERVER["PHP_SELF"] != $destination) {
30-
header("Location: $destination");
31-
self::die("Redirect failed, click <a href='$destination'>here</a> to continue.");
32-
}
29+
header("Location: $destination");
30+
self::die("Redirect failed, click <a href='$destination'>here</a> to continue.");
3331
}
3432

3533
private static function headerResponseCode(int $code, string $reason)

resources/lib/UnityUser.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ public function init($send_mail = true)
7171
$ldapUserEntry->setAttribute("uid", $this->uid);
7272
$ldapUserEntry->setAttribute("givenname", $this->getFirstname());
7373
$ldapUserEntry->setAttribute("sn", $this->getLastname());
74+
$ldapUserEntry->setAttribute(
75+
"gecos",
76+
\transliterator_transliterate("Latin-ASCII", "{$this->getFirstname()} {$this->getLastname()}")
77+
);
7478
$ldapUserEntry->setAttribute("mail", $this->getMail());
7579
$ldapUserEntry->setAttribute("o", $this->getOrg());
7680
$ldapUserEntry->setAttribute("homedirectory", self::HOME_DIR . $this->uid);
@@ -102,6 +106,10 @@ public function init($send_mail = true)
102106
$orgEntry->addUser($this);
103107
}
104108

109+
// add to user group as well as user OU
110+
$this->LDAP->getUserGroup()->appendAttribute("memberuid", $this->getUID());
111+
$this->LDAP->getUserGroup()->write();
112+
105113
// add user to cache
106114
$this->REDIS->appendCacheArray("sorted_users", "", $this->getUID());
107115

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
// This template is sent to the user cancelling the request
4+
$this->Subject = "Unity Account Request Cancelled";
5+
?>
6+
7+
<p>Hello,</p>
8+
9+
<p>Your request to join group '<?php echo $data["group"]; ?>' on the Unity Cluster has been cancelled per your request.
10+
</p>
11+

0 commit comments

Comments
 (0)