Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8c66a53
1st attempt
simonLeary42 Jul 5, 2025
13c1d83
replace LDAPConn->search with LDAPEntry->search
simonLeary42 Jul 6, 2025
8973092
unityLDAP store base DN / base OU
simonLeary42 Jul 6, 2025
e73b949
replace/rewrite getGroups
simonLeary42 Jul 6, 2025
a126def
fix bugs
simonLeary42 Jul 6, 2025
0d9aeb1
remove cache from pi-mgmt
simonLeary42 Jul 6, 2025
1ec2818
fix bug
simonLeary42 Jul 6, 2025
0935f28
more readable
simonLeary42 Jul 6, 2025
1b943dc
specific escape
simonLeary42 Jul 6, 2025
0bdcc8b
remove extra variable
simonLeary42 Jul 6, 2025
d19c9f5
comment
simonLeary42 Jul 6, 2025
2109205
shorter
simonLeary42 Jul 6, 2025
42ff407
lowercase
simonLeary42 Jul 6, 2025
e4489b0
list -> array
simonLeary42 Jul 6, 2025
fef0f3c
query only for attributes that we need
simonLeary42 Jul 6, 2025
f1602cb
style
simonLeary42 Jul 6, 2025
afa75c8
"entry" is the wrong word
simonLeary42 Jul 7, 2025
d4afbf6
fix missing return
simonLeary42 Jul 7, 2025
4fb8d57
rename "arrays" to "attributes", make attribute getters consistent
simonLeary42 Jul 7, 2025
a103c18
no need for recursive
simonLeary42 Jul 7, 2025
679c8ef
no need for recursive
simonLeary42 Jul 7, 2025
e591e72
remove default value for attributes
simonLeary42 Jul 13, 2025
ab0c123
getuid is gone
simonLeary42 Jul 13, 2025
f3c84e1
remove multiple calls to getPIGroupGIDs
simonLeary42 Jul 13, 2025
065ace8
fix bug?
simonLeary42 Aug 5, 2025
41331b4
typo
simonLeary42 Aug 26, 2025
bc6d635
remove newline
simonLeary42 Aug 26, 2025
395d7aa
function name has changed
simonLeary42 Aug 26, 2025
402f18e
use nested table instead of <br>
simonLeary42 Aug 26, 2025
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
1 change: 1 addition & 0 deletions resources/init.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
$CONFIG["ldap"]["user"],
$CONFIG["ldap"]["pass"],
__DIR__ . "/../deployment/custom_user_mappings",
$CONFIG["ldap"]["basedn"],
$CONFIG["ldap"]["user_ou"],
$CONFIG["ldap"]["group_ou"],
$CONFIG["ldap"]["pigroup_ou"],
Expand Down
89 changes: 86 additions & 3 deletions resources/lib/UnityLDAP.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ class UnityLDAP extends ldapConn
);

// string vars for OUs
private $STR_BASEOU;
private $STR_USEROU;
private $STR_GROUPOU;
private $STR_PIGROUPOU;
private $STR_ORGGROUPOU;
private $STR_ADMINGROUP;

// Instance vars for various ldapEntry objects
private $baseOU;
private $userOU;
private $groupOU;
private $pi_groupOU;
Expand All @@ -49,6 +51,7 @@ public function __construct(
$dn,
$pass,
$custom_user_mappings,
$base_ou,
$user_ou,
$group_ou,
$pigroup_ou,
Expand All @@ -59,13 +62,15 @@ public function __construct(
) {
parent::__construct($host, $dn, $pass);

$this->STR_BASEOU = $base_ou;
$this->STR_USEROU = $user_ou;
$this->STR_GROUPOU = $group_ou;
$this->STR_PIGROUPOU = $pigroup_ou;
$this->STR_ORGGROUPOU = $orggroup_ou;
$this->STR_ADMINGROUP = $admin_group;

// Get Global Entries
$this->baseOU = $this->getEntry($base_ou);
$this->userOU = $this->getEntry($user_ou);
$this->groupOU = $this->getEntry($group_ou);
$this->pi_groupOU = $this->getEntry($pigroup_ou);
Expand Down Expand Up @@ -219,6 +224,13 @@ public function getUnassignedID($uid, $UnitySQL)
return $next_uid;
}

public function getAllUsersUIDs()
{
// should not use $user_ou->getChildren or $base_ou->getChildren(objectClass=posixAccount)
// Unity users might be outside user ou, and not all users in LDAP tree are unity users
return $this->userGroup->getAttribute("memberuid");
}

//
// Functions that return user/group objects
//
Expand All @@ -232,21 +244,35 @@ public function getAllUsers($UnitySQL, $UnityMailer, $UnityRedis, $UnityWebhook,
foreach ($users as $user) {
array_push($out, new UnityUser($user, $this, $UnitySQL, $UnityMailer, $UnityRedis, $UnityWebhook));
}

return $out;
}
}

$users = $this->userGroup->getAttribute("memberuid");
$users = $this->getAllUsersUIDs();
sort($users);
foreach ($users as $user) {
$params = array($user, $this, $UnitySQL, $UnityMailer, $UnityRedis, $UnityWebhook);
array_push($out, new UnityUser(...$params));
}

return $out;
}

public function getAllUsersAttributes($attributes)
{
$include_uids = $this->getAllUsersUIDs();
$user_attributes = $this->baseOU->getChildrenArray(
$attributes,
true, // recursive
"objectClass=posixAccount"
);
foreach ($user_attributes as $i => $attributes) {
if (!in_array($attributes["uid"][0], $include_uids)) {
unset($user_attributes[$i]);
}
}
return $user_attributes;
}

public function getAllPIGroups($UnitySQL, $UnityMailer, $UnityRedis, $UnityWebhook, $ignorecache = false)
{
$out = array();
Expand Down Expand Up @@ -279,6 +305,58 @@ public function getAllPIGroups($UnitySQL, $UnityMailer, $UnityRedis, $UnityWebho
return $out;
}

public function getAllPIGroupsAttributes($attributes)
{
return $this->pi_groupOU->getChildrenArray($attributes);
}

public function getPIGroupGIDsWithMemberUID($uid)
{
return array_map(
fn($x) => $x["cn"][0],
$this->pi_groupOU->getChildrenArray(
["cn"],
false,
"(memberuid=" . ldap_escape($uid, LDAP_ESCAPE_FILTER) . ")",
)
);
}

public function getAllPIGroupOwnerAttributes($attributes)
{
// get the PI groups, filter for just the GIDs, then map the GIDs to owner UIDs
$owner_uids = array_map(
fn($x) => UnityGroup::GID2OwnerUID($x),
array_map(
fn($x) => $x["cn"][0],
$this->pi_groupOU->getChildrenArray(["cn"]),
),
);
$owner_attributes = $this->getAllUsersAttributes($attributes);
foreach ($owner_attributes as $i => $attributes) {
if (!in_array($attributes["uid"][0], $owner_uids)) {
unset($owner_attributes[$i]);
}
}
return $owner_attributes;
}

/** Returns an associative array where keys are UIDs and values are arrays of PI GIDs */
public function getAllUID2PIGIDs()
{
// initialize output so each UID is a key with an empty array as its value
$uids = $this->getAllUsersUIDs();
$uid2pigids = array_combine($uids, array_fill(0, count($uids), []));
// for each PI group, append that GID to the member list for each of its member UIDs
foreach ($this->getAllPIGroupsAttributes(["cn", "memberuid"]) as $array) {
$gid = $array["cn"][0];
foreach ($array["memberuid"] as $uid) {
array_push($uid2pigids[$uid], $gid);
}
}
return $uid2pigids;
}

public function getAllOrgGroups($UnitySQL, $UnityMailer, $UnityRedis, $UnityWebhook, $ignorecache = false)
{
$out = array();
Expand Down Expand Up @@ -310,6 +388,11 @@ public function getAllOrgGroups($UnitySQL, $UnityMailer, $UnityRedis, $UnityWebh
return $out;
}

public function getAllOrgGroupsAttributes($attributes)
{
return $this->org_groupOU->getChildrenArray($attributes);
}

public function getUserEntry($uid)
{
$uid = ldap_escape($uid, LDAP_ESCAPE_DN);
Expand Down
39 changes: 6 additions & 33 deletions resources/lib/UnityUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -575,48 +575,21 @@ public function getOrgGroup()

/**
* Gets the groups this user is assigned to, can be more than one
* @return [type]
* @return string[]
*/
public function getGroups($ignorecache = false)
public function getPIGroupGIDs($ignorecache = false)
{
$out = array();

if (!$ignorecache) {
$cached_val = $this->REDIS->getCache($this->uid, "groups");
if (!is_null($cached_val)) {
$groups = $cached_val;
foreach ($groups as $group) {
$group_obj = new UnityGroup(
$group,
$this->LDAP,
$this->SQL,
$this->MAILER,
$this->REDIS,
$this->WEBHOOK
);
array_push($out, $group_obj);
}

return $out;
}
}

$all_pi_groups = $this->LDAP->getAllPIGroups($this->SQL, $this->MAILER, $this->REDIS, $ignorecache);

$cache_arr = array();

foreach ($all_pi_groups as $pi_group) {
if (in_array($this->uid, $pi_group->getGroupMemberUIDs())) {
array_push($out, $pi_group);
array_push($cache_arr, $pi_group->gid);
return $cached_val;
}
}

$gids = $this->LDAP->getPIGroupGIDsWithMemberUID($this->uid);
if (!$ignorecache) {
$this->REDIS->setCache($this->uid, "groups", $cache_arr);
$this->REDIS->setCache($this->uid, "groups", $gids);
}

return $out;
return $gids;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions test/functional/AccountDeletionRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function testRequestAccountDeletionUserHasNoGroups()
{
global $USER, $SQL;
switchUser(...getUserHasNotRequestedAccountDeletionHasNoGroups());
$this->assertEmpty($USER->getGroups());
$this->assertEmpty($USER->getPIGroupGIDs());
$this->assertNumberAccountDeletionRequests(0);
try {
http_post(
Expand All @@ -59,7 +59,7 @@ public function testRequestAccountDeletionUserHasGroup()
// FIXME this should be an error
global $USER, $SQL;
switchUser(...getUserHasNotRequestedAccountDeletionHasGroup());
$this->assertNotEmpty($USER->getGroups());
$this->assertNotEmpty($USER->getPIGroupGIDs());
$this->assertNumberAccountDeletionRequests(0);
try {
http_post(
Expand Down
19 changes: 6 additions & 13 deletions webroot/admin/pi-mgmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,13 @@
</tr>

<?php
$accounts = $LDAP->getAllPIGroups($SQL, $MAILER, $REDIS, $WEBHOOK);

usort($accounts, function ($a, $b) {
return strcmp($a->gid, $b->gid);
});

foreach ($accounts as $pi_group) {
$pi_user = $pi_group->getOwner();

$owner_attributes = $LDAP->getAllPIGroupOwnerAttributes(["uid", "gecos", "mail"]);
usort($owner_attributes, fn($a, $b) => strcmp($a["uid"][0], $b["uid"][0]));
foreach ($owner_attributes as $attributes) {
echo "<tr class='expandable'>";
echo "<td><button class='btnExpand'>&#9654;</button>" . $pi_user->getFirstname() .
" " . $pi_user->getLastname() . "</td>";
echo "<td>" . $pi_group->gid . "</td>";
echo "<td><a href='mailto:" . $pi_user->getMail() . "'>" . $pi_user->getMail() . "</a></td>";
echo "<td><button class='btnExpand'>&#9654;</button>" . $attributes["gecos"][0] . "</td>";
echo "<td>" . UnityGroup::OwnerUID2GID($attributes["uid"][0]) . "</td>";
echo "<td><a href='mailto:" . $attributes["mail"][0] . "'>" . $attributes["mail"][0] . "</a></td>";
echo "</tr>";
}
?>
Expand Down
36 changes: 17 additions & 19 deletions webroot/admin/user-mgmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,36 +37,34 @@
</tr>

<?php
$users = $LDAP->getAllUsers($SQL, $MAILER, $REDIS, $WEBHOOK);

usort($users, function ($a, $b) {
return strcmp($a->uid, $b->uid);
});

foreach ($users as $user) {
if ($user->hasRequestedAccountDeletion()) {
$UID2PIGIDs = $LDAP->getAllUID2PIGIDs();
$user_attributes = $LDAP->getAllUsersAttributes(["uid", "gecos", "o", "mail"]);
usort($user_attributes, fn ($a, $b) => strcmp($a["uid"][0], $b["uid"][0]));
foreach ($user_attributes as $attributes) {
$uid = $attributes["uid"][0];
if ($SQL->accDeletionRequestExists($uid)) {
echo "<tr style='color:grey; font-style: italic'>";
} else {
echo "<tr>";
}
echo "<td>" . $user->getFirstname() . " " . $user->getLastname() . "</td>";
echo "<td>" . $user->uid . "</td>";
echo "<td>" . $user->getOrg() . "</td>";
echo "<td><a href='mailto:" . $user->getMail() . "'>" . $user->getMail() . "</a></td>";
echo "<td>" . $attributes["gecos"][0] . "</td>";
echo "<td>" . $uid . "</td>";
echo "<td>" . $attributes["o"][0] . "</td>";
echo "<td><a href='mailto:" . $attributes["mail"][0] . "'>" . $attributes["mail"][0] . "</a></td>";
echo "<td>";
$cur_user_groups = $user->getGroups();
foreach ($cur_user_groups as $cur_group) {
echo "<a href='mailto:" . $cur_group->getOwner()->getMail() . "'>" . $cur_group->gid . "</a>";
if ($cur_group !== array_key_last($cur_user_groups)) {
echo '<br>';
if (count($UID2PIGIDs[$uid]) > 0) {
echo "<table>";
foreach ($UID2PIGIDs[$uid] as $gid) {
echo "<tr><td>$gid</td></tr>";
}
echo "</table>";
}
echo "</td>";
echo "<td>";
echo "<form class='viewAsUserForm' action='' method='POST'
onsubmit='return confirm(\"Are you sure you want to switch to the user " . $user->uid . "?\");'>
onsubmit='return confirm(\"Are you sure you want to switch to the user '$uid'?\");'>
<input type='hidden' name='form_type' value='viewAsUser'>
<input type='hidden' name='uid' value='" . $user->uid . "'>
<input type='hidden' name='uid' value='$uid'>
<input type='submit' name='action' value='Access'>
</form>";
echo "</td>";
Expand Down
Loading