Unity Web Portal is a PHP application built in top of MariaDB and LDAP which acts as a central user portal for high-performance-computing clusters.
Typical Usage:
- User registers an account
- LDAP entries are created
- User manages SSH public keys
- No passwords
- Github import, upload file, paste, generate and download private key
- User changes login shell
- User requests to join a PI group
- Requires PI approval
- User requests their own PI group
- Requires admin approval
- PI approves/denies requests to join their PI group
- PI removes members from their group
Admin Features:
- Automatic updating of LDAP to reflect current state of users, groups, organizations, PI groups
- Cluster notices
- Added to front page, mailed, and exposed via REST API
- WYSIWYG HTML editor for webpage contents, cluster notices
- Branding customization for multiple domains simultaneously
- Custom UIDNumber / GIDNumber mappings for specific users
- Login as another user
- Mailing
See the Docker Compose environment (tools/docker-dev/) for an (unsafe for production) example.
- OpenLDAP server
- Structure should be similar to
tools/docker-dev/identity/bootstrap.ldif - Also see
tools/docker-dev/identity/{config,ssh}.ldif - recommended openldap modules/overlays:
unique: prevent UIDNumber, GIDNumber conflictspw-sha2: allow the use of sha2 password hashing algorithms for bind
- Structure should be similar to
- MySQL / MariaDB server
- Structure should be similar to
tools/docker-dev/sql/bootstrap.sql
- Structure should be similar to
- SMTP server
- Web server
- This repository cloned
deployment/config/config.inishould be owned by the apache user (www-dataon Ubuntu), with mode0600- Submodules checked out (
git submodule update --checkout --init) - Composer (
apt install composeron Ubuntu) - Dependencies:
- PHP extensions
- curl, intl, ldap, mbstring, mysql, pdo, redis, xml (
apt install php-<extension>on Ubuntu)
- curl, intl, ldap, mbstring, mysql, pdo, redis, xml (
- Libraries
COMPOSER_ALLOW_SUPERUSER=1 composer --no-dev --no-scripts --no-plugins install
- PHP extensions
httpdDocumentRootset towebroot/httpdAuthentication- Any authentication will do as long as it defines
REMOTE_USER,givenName,sn, andmailREMOTE_USERmust take the formusername@orggivenNameis first name,snis last name
- Unity uses Shibboleth SP and the Apache Shibboleth module (
apt install shibboleth-sp-utils libapache2-mod-shibon Ubuntu)
- Any authentication will do as long as it defines
httpdAuthorization- Restricted access to
webroot/admin/ - Global access (with valid authentication) to
webroot/ - No access anywhere else
- Restricted access to
- Create
deployment/config/config.iniusing/deployment/defaults/config.inias a reference- Make sure this file is not world readable!
- If using mulitple domains, create
deployment/overrides/<domain>/config/config.ini - If using custom UIDNumber/GIDNumber mappings, create
deployment/custom_user_mappings/*.csv- The 1st column is UID, the 2nd column is both UIDNumber and GIDNumber
- Add logos to
webroot/assets/footer_logos/
The scope of this project ends at being responsible for the LDAP user database. We recommend production deployments to set up scripts which detect changes in LDAP and then perform further actions. For example, Unity uses such scripts to create home directories and add records to the Slurm account database.
We recommend a deployment where each version of the portal is its own clone, then just change a symlink to point to the new version. This way a rollback is much easier.
Example folder structure, where -> indicates a symlink:
/srv/www/
unity-web-portal -> unity-web-portal-1.1.0
unity-web-portal-1.1.0
unity-web-portal-1.2.0
Update instructions assuming the above structure:
url="https://..."
prod="/srv/www/unity-web"
old="/srv/www/unity-web-1.1.0"
new="/srv/www/unity-web-1.2.0"
mkdir "$new" && cd "$new"
git clone "$url" .
git submodule update --init --checkout
COMPOSER_ALLOW_SUPERUSER=1 composer --no-dev --no-scripts --no-plugins install
cp --preserve=all "$prod/deployment/config/config.ini" ./deployment/config/config.ini
rsync -a "$prod/deployment/custom_user_mappings/" ./deployment/custom_user_mappings/
rsync -a "$prod/deployment/overrides/" ./deployment/overrides/
rsync -a "$prod/webroot/assets/footer_logos/" ./footer_logos/
rm "$prod" && ln -s "$PWD" "$prod"Rollback:
rm "$prod" && ln -s "$old" "$prod"- the
[ldap]user_groupoption has been renamed to[ldap]qualified_user_group - the
user_createdmail template has been renamed touser_qualified - the
user_dequalifiedmail template has been added
In v1.2.1, we extended PI group requests and PI group join requests to store user info like name and email. This was necessary because LDAP entries were not created for users until they became "qualified" (become a PI or joined a PI group). While a user was unqualified, if the Redis cache was cleared, the user info would be lost. Now, LDAP entries are created immediately for every user, so this is no longer necessary.
- Shut down the web portal
systemctl stop apache2
- Create LDAP entries for all existing requests
use UnityWebPortal\lib\UnityUser; $_SERVER["HTTP_HOST"] = "worker"; // see deployment/overrides/worker/ $_SERVER["REMOTE_ADDR"] = "127.0.0.1"; require_once __DIR__ . "/../resources/autoload.php"; foreach ($SQL->getAllRequests() as $request) { $user = new UnityUser( $request["uid"], $LDAP, $SQL, $MAILER, $REDIS, $WEBHOOK, ); if (!$user->exists()) { echo "creating user: " . jsonEncode($request) . "\n"; $user->init( $request["firstname"], $request["lastname"], $request["email"], $request["org"], ); } }
- Remove columns from the
requeststable:ALTER TABLE `requests` DROP COLUMN `firstname`, DROP COLUMN `lastname`, DROP COLUMN `email`, DROP COLUMN `org`;
- Update the portal PHP code following the normal procedure
- Start the portal again
systemctl start apache2
- SQL:
- remove the
sitevarstable
- remove the
defaults/config.ini.defaulthas some new fields that need to be overriden:offset_UIDGIDoffset_PIGIDoffset_ORGGID
custom_user_mappingscan no longer match with just the 1st segment of the logged in user's UID, an exact match is required- LDAP:
- create the
gecosattribute for all users by concatenatinggivenNameandsn
- create the
- SQL:
- Add new columns to the
requeststable:ALTER TABLE `requests` ADD `firstname` VARCHAR(768) NOT NULL AFTER `timestamp`, ADD `lastname` VARCHAR(768) NOT NULL AFTER `firstname`, ADD `email` VARCHAR(768) NOT NULL AFTER `lastname`, ADD `org` VARCHAR(768) NOT NULL AFTER `email`;
- Add new columns to the
- SQL:
- Create the
sitevarstable (seebootstrap.sqlfor details) - Create the
audit_logtable (seebootstrap.sqlfor details) - Create the
account_deletion_requeststable (seebootstrap.sqlfor details) - Create the
user_last_loginstable (seebootstrap.sqlfor details) - Drop the
sso_logtable - Drop the
eventstable - Reduce the size of all
varchar(1000)columns tovarchar(768) - Delete the
privrow in thepagestable (if moving site policy to external site) - Add the
account_policyrow in thepagestable (if NOT moving site policy to external site)
- Create the
defaults/config.ini.defaulthas some new fields that may need to be overriden:ldap.user_groupsite.terms_of_service_url- example, created account policy page:
https://unity.rc.umass.edu/panel/account_policy.php
- example, created account policy page:
site.account_policy_url- example, using old site policy page:
https://unity.rc.umass.edu/panel/priv.php
- example, using old site policy page:
- LDAP:
- Create a new group defined by
ldap.user_groupin the config
- Create a new group defined by
- SQL:
- Add the
homecontent management row
- Add the
config/branding/config.ini.defaulthas some new fields that may need to be overriden:mail.pi_approve*page.home- The entire
loginshellsection
