".sprintf(_("%s Database Link Status"), \config\ConfAssistant::CONSORTIUM['display_name'])."
";
}
?>
@@ -299,8 +313,11 @@
$thefed = new \core\Federation($fedId);
/// nomenclature for 'federation', federation name, nomenclature for 'inst'
echo "
".sprintf(_("The following %s are in your %s %s:"), $uiElements->nomenclatureParticipant, $uiElements->nomenclatureFed, ''.$thefed->name.'')."
";
- echo "
". _("Quick search:")."
";
- echo "
". _("Only not linked"). "
";
+ echo "
". _("Quick search:")."
";
+ echo "
";
+ echo "
";
+ echo "
";
+ echo "
";
echo "
";
// extract only pending invitations for *this* fed
$display_pendings = FALSE;
@@ -320,22 +337,79 @@
foreach ($my_idps as $index => $my_idp) {
$idp_instance = $idps[$index]['instance'];
- $idpLinked = 'nosync';
+ // get max profile status
+ $profileClass = '';
+ if ($idp_instance->maxProfileStatus() >= \core\IdP::PROFILES_SHOWTIME) {
+ $status = \core\IdP::PROFILES_SHOWTIME;
+ $profileClass = 'profileok';
+ } elseif ($idp_instance->maxProfileStatus() >= \core\IdP::PROFILES_CONFIGURED) {
+ $status = \core\IdP::PROFILES_CONFIGURED;
+ $profileClass = 'profilewarn';
+ } else {
+ $status = \core\IdP::PROFILES_INCOMPLETE;
+ $profileClass = 'profilewarn';
+ }
+ $profileIconData = $uiElements->iconData(\core\IdP::PROFILES_INDEX[$status]);
+ $profileIcon = $uiElements->catIcon($profileIconData);
+
+ // verify the certificates status for this IdP
+ if (isset($certStatus[$index])) {
+ $certIconData = $uiElements->iconData(\core\AbstractProfile::CERT_STATUS_INDEX[$certStatus[$index]]);
+ if ($certStatus[$index] > 0) {
+ $certClass = 'certproblem';
+ } else {
+ $certClass = 'certok';
+ }
+ } else {
+ $certIconData = $uiElements->iconData('CERTS_NOT_SHOWN');
+ $certClass = 'certok';
+ }
+ $certIcon = $uiElements->catIcon($certIconData);
+
+ // verify DB sync status for this IdP
+ $linkClass = 'nosync';
+ $linkIcon = '';
// external DB sync, if configured as being necessary
if (\config\Master::DB['enforce-external-sync']) {
switch ($idp_instance->getExternalDBSyncState()) {
case \core\IdP::EXTERNAL_DB_SYNCSTATE_NOTSUBJECTTOSYNCING:
break;
case \core\IdP::EXTERNAL_DB_SYNCSTATE_SYNCED:
- $idpLinked = 'linked';
+ $linkClass = 'linked';
+ $linkIcon = $uiElements->catIcon($uiElements->iconData('IDP_LINKED'));
break;
case \core\IdP::EXTERNAL_DB_SYNCSTATE_NOT_SYNCED:
- $idpLinked = 'notlinked';
+ $linkClass = 'notlinked';
+ $linkIcon = $uiElements->catIcon($uiElements->iconData('IDP_NOT_LINKED'));
break;
}
- }
+ }
+
+ // verify the OpenRoaming status for this IdP
+ $orStatus = $idp_instance->maxOpenRoamingStatus();
+ $orClass = 'orok';
+ $orIcon = '';
+ switch ($orStatus) {
+ case \core\AbstractProfile::OVERALL_OPENROAMING_LEVEL_NO:
+ $orIcon = "-";
+ break;
+ case \core\AbstractProfile::OVERALL_OPENROAMING_LEVEL_GOOD:
+ break;
+ case \core\AbstractProfile::OVERALL_OPENROAMING_LEVEL_NOTE:
+ case \core\AbstractProfile::OVERALL_OPENROAMING_LEVEL_WARN:
+ case \core\AbstractProfile::OVERALL_OPENROAMING_LEVEL_ERROR:
+ $orClass = 'orwarn';
+ break;
+ default:
+ throw new \Exception("Impossible OpenRoaming status!");
+ }
+ if ($orIcon === "") {
+ $iconData = $uiElements->iconData(\core\AbstractProfile::OVERALL_OPENROAMING_INDEX[$status]);
+ $orIcon = $uiElements->catIcon($iconData);
+ }
+
// new row_id, with one IdP inside
- echo "
";
+ echo "
";
// name; and realm of silverbullet profiles if any
// instantiating all profiles is costly, so we only do this if
@@ -348,7 +422,7 @@
}
}
}
- echo "
+ echo "
"
. "".$my_idp.""
@@ -363,62 +437,23 @@
. "
";
// deployment status; need to dive into profiles for this
// show happy eyeballs if at least one profile is configured/showtime
- echo "
";
}
@@ -664,5 +672,39 @@ public function sanityTestResultHTML($test) {
}
return($out);
}
-
+ /**
+ * prepares data for icons
+ *
+ * @param string $index
+ * @return array
+ */
+ public function iconData($index) {
+ \core\common\Entity::intoThePotatoes();
+ $icons = [
+ 'CERT_STATUS_OK' => ['img' => 'Tabler/certificate-green.svg', 'text' => _("All certificates are valid long enough")],
+ 'CERT_STATUS_WARN' => ['img' => 'Tabler/certificate-red.svg', 'text' => _("At least one certificate is close to expiry")],
+ 'CERT_STATUS_ERROR' => ['img' => 'Tabler/certificate-off.svg', 'text' => _("At least one certificate either has expired or is very close to expiry")],
+ 'OVERALL_OPENROAMING_LEVEL_GOOD' => ['img' => 'Tabler/square-rounded-check-green.svg', 'text' => _("OpenRoaming appears to be configured properly")],
+ 'OVERALL_OPENROAMING_LEVEL_NOTE' => ['img' => 'Tabler/info-square-rounded-blue.svg', 'text' => _("There are some minor OpenRoaming configuration issues")],
+ 'OVERALL_OPENROAMING_LEVEL_WARN' => ['img' => 'Tabler/info-square-rounded-blue.svg', 'text' => _("There are some avarage level OpenRoaming configuration issues")],
+ 'OVERALL_OPENROAMING_LEVEL_ERROR' => ['img' => 'Tabler/alert-square-rounded-red.svg', 'text' => _("There are some critical OpenRoaming configuration issues")],
+ 'PROFILES_SHOWTIME' => ['img' => 'Tabler/checks-green.svg', 'text' => _("At least one profile is fully configured and visible in the user interface")],
+ 'PROFILES_CONFIGURED' => ['img' => 'Tabler/check-green.svg', 'text' => _("At least one profile is fully configured but none are set as production-ready therefore the institution is not visible in the user interface")],
+ 'PROFILES_INCOMPLETE' => ['img' => 'Tabler/access-point-off-red.svg', 'text' => _("No configured profiles")],
+ 'IDP_LINKED' => ['img' => 'Tabler/database-green.svg', 'text' => _("Linked")],
+ 'IDP_NOT_LINKED' => ['img' => 'Tabler/database-off-red.svg', 'text' => _("NOT linked")],
+ 'CERTS_NOT_SHOWN' => ['img' => 'Tabler/question-mark-blue.svg', 'text' => _("Not showing cert info if no profiles are visible")],
+ ];
+ \core\common\Entity::outOfThePotatoes();
+ return($icons[$index]);
+ }
+
+/**
+ * the HTML img element produced 0n the basis of a simple [src,title] array
+ * @param type array
+ * @return string the img element
+ */
+ public function catIcon($data) {
+ return "";
+ }
}
diff --git a/web/lib/common/InputValidation.php b/web/lib/common/InputValidation.php
index 397e8c083..558144f9c 100644
--- a/web/lib/common/InputValidation.php
+++ b/web/lib/common/InputValidation.php
@@ -55,7 +55,6 @@ private function inputValidationError($customtext)
*/
public function existingFederation($input, $owner = NULL)
{
-
$cat = new \core\CAT(); // initialises Entity static members
$fedIdentifiers = array_keys($cat->knownFederations);
if (!in_array(strtoupper($input), $fedIdentifiers)) {
@@ -78,6 +77,40 @@ public function existingFederation($input, $owner = NULL)
throw new Exception($this->inputValidationError(sprintf("User is not %s administrator!", \core\common\Entity::$nomenclature_fed)));
}
+ /**
+ * Is this a known Federation? Optionally, also check if the authenticated
+ * user is a federation admin of that federation
+ * @param mixed $input the ISO code of the federation
+ * @param string|NULL $owner the authenticated username, optional
+ * @return array(\core\Federation, string)
+ * @throws Exception
+ */
+ public function existingFederationInt($input, $owner = NULL)
+ {
+ $cat = new \core\CAT(); // initialises Entity static members
+ $fedIdentifiers = array_keys($cat->knownFederations);
+ if (!in_array(strtoupper($input), $fedIdentifiers)) {
+ throw new Exception($this->inputValidationError(sprintf("This %s does not exist!", \core\common\Entity::$nomenclature_fed)));
+ }
+ // totally circular, but this hopefully *finally* make Scrutinizer happier
+ $correctIndex = array_search(strtoupper($input), $fedIdentifiers);
+ $postFed = $fedIdentifiers[$correctIndex];
+ $temp = new \core\Federation($postFed);
+ if ($owner === NULL) {
+ return [$temp,'readonly'];
+ }
+ $user = new \core\User($owner);
+ foreach ($temp->listFederationAdmins() as $oneowner) {
+ if ($oneowner == $owner) {
+ return [$temp, 'fullaccess'];
+ }
+ }
+ if ($user->isSuperadmin()|| $user->isSupport()) {
+ $this->loggerInstance->debug(4, "You are the superadmin/support\n");
+ return [$temp,'readonly'];
+ }
+ throw new Exception($this->inputValidationError(sprintf("User is not %s administrator!", \core\common\Entity::$nomenclature_fed)));
+ }
/**
* Is this a known IdP? Optionally, also check if the authenticated
@@ -112,7 +145,7 @@ public function existingIdP($input, $owner = NULL, $claimedFedBinding = NULL)
/**
* Is this a known IdP? Optionally, also check if the authenticated
* user is an admin of that IdP or a federation admin for the parent federation
- * federaton admins get read-only access, superadmins get readonly access as well
+ * federaton admins superadmin and support get read-only access, superadmins get readonly access as well
* @param mixed $input the numeric ID of the IdP in the system
* @param string $owner the authenticated username, optional
* @param \core\Federation $claimedFedBinding if set, cross-check that IdP belongs to specified federation (useful in admin API mode)
@@ -137,8 +170,8 @@ public function existingIdPInt($input, $owner = NULL, $claimedFedBinding = NULL)
$this->loggerInstance->debug(4, "You are fed admin for this IdP\n");
return [$temp,'readonly'];
}
- if ($user->isSuperadmin()) {
- $this->loggerInstance->debug(4, "You are the superadmin\n");
+ if ($user->isSuperadmin() || $user->isSupport()) {
+ $this->loggerInstance->debug(4, "You are the superadmin/support\n");
return [$temp,'readonly'];
}
throw new Exception($this->inputValidationError("This IdP identifier is not accessible!"));
diff --git a/web/resources/css/cat.css.php b/web/resources/css/cat.css.php
index 8205b84a1..fa781fd11 100644
--- a/web/resources/css/cat.css.php
+++ b/web/resources/css/cat.css.php
@@ -964,12 +964,17 @@
padding-: 4px;
padding-: 4px;
}
+
table.user_overview td {
border-top-style: none;
padding-: 4px;
padding-: 4px;
- padding-top: 0px;
- height: 25px;
+ vertical-align: middle;
+ height: 28px;
+}
+
+table.user_overview img {
+ vertical-align: middle;
}
table.user_overview td:first-child {
diff --git a/web/resources/images/icons/LICENSE b/web/resources/images/icons/LICENSE
index afbb23a5a..2f6d799af 100644
--- a/web/resources/images/icons/LICENSE
+++ b/web/resources/images/icons/LICENSE
@@ -4,3 +4,5 @@ http://www.iconarchive.com/show/multipurpose-alphabet-icons-by-hydrattz.html
License: "Free for non-commercial use, Commercial Usage not allowed"
button_cancel.png: stock RESTENA image
+
+Tabler icons downloaded from https://tabler.io/ and are under the MIT license
diff --git a/web/resources/images/icons/Tabler/access-point-off-red.svg b/web/resources/images/icons/Tabler/access-point-off-red.svg
new file mode 100644
index 000000000..c3714e766
--- /dev/null
+++ b/web/resources/images/icons/Tabler/access-point-off-red.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/web/resources/images/icons/Tabler/certificate-green.svg b/web/resources/images/icons/Tabler/certificate-green.svg
index 7cc1f9512..da871b2e9 100644
--- a/web/resources/images/icons/Tabler/certificate-green.svg
+++ b/web/resources/images/icons/Tabler/certificate-green.svg
@@ -1,4 +1,4 @@
-