diff --git a/lib/API.php b/lib/API.php index 24c9f902d3d2584186737e0078f60efecc77b62d..958f2b4d205d4694cc628b9e7c7991adc02a1878 100644 --- a/lib/API.php +++ b/lib/API.php @@ -1187,9 +1187,15 @@ Click action names for a full description.</p>'; $F = $edugain->FEDS; ksort($F, SORT_STRING | SORT_FLAG_CASE); foreach ($F as $fed => $A) { - $out[$fed] = ['code' => $fed, 'status' => $A['status'], 'country_code' => $A['country_code']]; + if (!isset($A['country_code'])) { + error_log("Missing 'country_code' for federation: $fed"); + } + $out[$fed] = [ + 'code' => $fed, + 'status' => $A['status'], + 'country_code' => $A['country_code'] ?? 'unknown', + ]; } - return $out; } private function action_show_map() { diff --git a/lib/Utils.php b/lib/Utils.php index 50ebfd9c7f17fc8f6cecce7833314f2fed056ec0..f78278731e3626d1831207a59e83a8f636da168c 100644 --- a/lib/Utils.php +++ b/lib/Utils.php @@ -37,11 +37,17 @@ class Utils { * @return sting formatted time or 0 if no arg is provided */ public static function getTime($tm) { - if ($tm == '0000-00-00 00:00:00') + if ($tm == '0000-00-00 00:00:00') { return 0; - return strftime("%Y%m%dT%H%M%SZ", strtotime($tm)); - } + } + // Create a DateTime object from the input string + $dateTime = new DateTime($tm); + + // Format the date and time in the desired format + return $dateTime->format("Ymd\THis\Z"); + } + /** * Prepare time boarders to het eduGAIN history. Takes care of defaults that * may be missing in the query @@ -77,8 +83,11 @@ class Utils { } $startTimestamp = $startTimestamp < $startEdugain ? $startEdugain : $startTimestamp; $endTimestamp = $endTimestamp > $today ? $today : $endTimestamp; - $startDate = strftime('%Y-%m-%d', $startTimestamp); - $endDate = strftime('%Y-%m-%d', $endTimestamp) . ' 23:59:59'; + + // Using DateTime::format() instead of strftime() + $startDate = (new DateTime("@$startTimestamp"))->format('Y-m-d'); + $endDate = (new DateTime("@$endTimestamp"))->format('Y-m-d') . ' 23:59:59'; + return [$startTimestamp, $endTimestamp, $startDate, $endDate]; } } \ No newline at end of file diff --git a/lib/eduGAIN_manage.php b/lib/eduGAIN_manage.php index 5c2180218579f4ce03bfbae5a6be04ecfa942cbc..b1c81c6b80bbd7a2361805aef96fab07b8e59c58 100644 --- a/lib/eduGAIN_manage.php +++ b/lib/eduGAIN_manage.php @@ -227,54 +227,68 @@ class eduGAIN_manage extends eduGAIN { } private function updatePersonTable() { - $Person = []; - $noUpdates = true; - foreach ([ - 'tsg_delegate_0_0', - 'tsg_delegate_0_1', - 'tsg_delegate_0_2', - 'tsg_delegate_0_3', - 'tsg_deputy_0_0', - 'tsg_deputy_0_1', - 'tsg_deputy_0_2', - 'tsg_deputy_0_3', - 'tsg_delegate_1_0', - 'tsg_delegate_1_1', - 'tsg_delegate_1_2', - 'tsg_delegate_1_3', - 'tsg_deputy_1_0', - 'tsg_deputy_1_1', - 'tsg_deputy_1_2', - 'tsg_deputy_1_3', - ] as $key) { + $Person = []; // Array to store person data + $noUpdates = true; // Flag to check if there are updates + + // List of keys to process + $keys = [ + 'tsg_delegate_0_0', 'tsg_delegate_0_1', 'tsg_delegate_0_2', 'tsg_delegate_0_3', + 'tsg_deputy_0_0', 'tsg_deputy_0_1', 'tsg_deputy_0_2', 'tsg_deputy_0_3', + 'tsg_delegate_1_0', 'tsg_delegate_1_1', 'tsg_delegate_1_2', 'tsg_delegate_1_3', + 'tsg_deputy_1_0', 'tsg_deputy_1_1', 'tsg_deputy_1_2', 'tsg_deputy_1_3', + ]; + + foreach ($keys as $key) { + // Check if the key exists in the input arguments + if (!isset($this->args[$key])) { + continue; // Skip if the key is missing + } + + // Split the key to extract function, index, and field information $m = explode('_', $key); - $function = $m[1]; - $functionIndex = $m[2]; - $functionField = $m[3]; + $function = $m[1]; // Delegate or deputy + $functionIndex = $m[2]; // Index number + $functionField = $m[3]; // Field type (e.g., 0, 1, 2, 3) + + // Retrieve and sanitize the value from $this->args $v = $this->args[$key]; - $v = is_numeric($v) ? $v : "'$v'"; + $v = is_numeric($v) ? $v : "'" . addslashes($v) . "'"; $Person[$function][$functionIndex][$functionField] = $v; + + // Check if the current field is in the list of changed fields if (in_array($key, $this->changedFields)) { - $noUpdates = false; + $noUpdates = false; // Mark as having updates } } + + // If there are no updates, return early if ($noUpdates) { return; } + + // Table name where data will be updated $table = 'person'; - $q = "DELETE FROM $table WHERE code = '$this->code'"; + + // Delete existing records for the current code + $q = "DELETE FROM $table WHERE code = '" . addslashes($this->code) . "'"; $this->databaseQuery($q); + + // Insert new records into the table foreach ($Person as $function => $PR) { foreach ($PR as $p) { - // we assume that the person must have a last-name - if ($p[1] == "''") { - continue; + // Ensure that the person has a last name (index 1) + if (!isset($p[1]) || $p[1] == "''") { + continue; // Skip if the last name is missing } - $q = "INSERT INTO $table (given_name, last_name, email, show_email, code, role) VALUES (" . join(',', $p) . ",'$this->code','tsg_$function')"; + + // Build the SQL query for inserting new data + $q = "INSERT INTO $table (given_name, last_name, email, show_email, code, role) VALUES (" + . join(',', $p) . ", '" . addslashes($this->code) . "', 'tsg_$function')"; + + // Execute the query $this->databaseQuery($q); } } - } private function updatePolicyTable() { diff --git a/lib/eduGAIN_map.php b/lib/eduGAIN_map.php index f55fb437c1044b5c0b4b64329d3757699eba29a6..8a31cf4bbcfa81779f781b3a3f7371cf26104ec6 100644 --- a/lib/eduGAIN_map.php +++ b/lib/eduGAIN_map.php @@ -3,26 +3,34 @@ class eduGAIN_map { static function make_maps($active_only = 0) { + // Debugging message to indicate map creation has started Utils::debug(4, "making maps"); + + // Set paths for maps and map source files $maps_dir = TECHNICAL_HOME."/web/maps/"; $maps_source = TECHNICAL_HOME."/lib/Map_source/"; + + // Map files for Europe and World $europe_in = "eduGAIN-Europe.svg"; $world_in = "worldHigh.svg"; + // Define the color mapping based on the status values $Colours = [ - 0 => "#d0d0d0", - 1 => "#1e73be", - 4 => "#81d742", - 5 => "#d93", - 6 => "#d93", + 0 => "#d0d0d0", // Default color (grey) + 1 => "#1e73be", // Color for status 1 (blue) + 4 => "#81d742", // Color for status 4 (green) + 5 => "#d93", // Color for status 5 (orange) + 6 => "#d93", // Color for status 6 (orange) ]; + // Special colors for specific country codes $Colour = []; $Colour['va'] = '#c0c0c0'; $Colour['im'] = '#c0c0c0'; $Colour['gg'] = '#c0c0c0'; $Colour['je'] = '#c0c0c0'; + // Fetch data for federations based on whether we want only active ones or all if ($active_only == 1) { $json = json_decode(file_get_contents(ROOT_URL."/api.php?action=list_federation_map_codes&opt=1")); $file_suffix = '_active'; @@ -30,45 +38,60 @@ class eduGAIN_map { $json = json_decode(file_get_contents(ROOT_URL."/api.php?action=list_federation_map_codes")); $file_suffix = ''; } + + // Initialize array to store the status of countries $Status = []; + + // Loop through the JSON data to process the country status foreach ($json as $key => $element) { $countries = $element->country_code; if (empty($countries)) { continue; } foreach ($countries as $country) { + // Get the current status or default to 0 $c = isset($Status[$country]) ? $Status[$country] : 0; + // Update the status for this country $s = $Status[$country] = max($c, $element->status); + // Set the color for the country based on status $Colour[$country] = empty($Colours[$s]) ? 'none' : $Colours[$s]; } } -// Generate Europe - + // Generate Europe Map $svg_if = fopen($maps_source.$europe_in, "r"); $png_out = 'europe'.$file_suffix.'.png'; $svg_out = 'europe'.$file_suffix.'.svg'; + // Initialize empty SVG content $svg = ''; $path = 0; + + // Read the SVG file and apply colors based on the status of each country while ($buffer = fgets($svg_if)) { - if (preg_match('/^ *<path/', $buffer)) + if (preg_match('/^ *<path/', $buffer)) { $path = 1; - if (preg_match('/^ +id="([\w]+).*"$/', $buffer, $m)) + } + if (preg_match('/^ +id="([\w]+).*"$/', $buffer, $m)) { $id = $m[1]; + } $out = $buffer; + // Apply fill color based on status if (preg_match('/^ +style=".*fill:#[^;]+;.*\/>/', $buffer)) { if ($path) { - if ($id == "Large") - $c = '#ffffff'; - else - $c = empty($Colour[$id]) ? "#c0c0c0" : $Colour[$id]; + if ($id == "Large") { + $c = '#ffffff'; // Color for "Large" id + } else { + $c = empty($Colour[$id]) ? "#c0c0c0" : $Colour[$id]; // Use country color or default + } $out = preg_replace('/(style=".*fill:)#[^;]+;/', '$1'.$c.';', $buffer); } $path = 0; } $svg .= $out; } + + // Convert SVG to PNG format and save the file $png = new Imagick(); $png->setBackgroundColor(new ImagickPixel("transparent")); $png->readImageBlob($svg); @@ -81,20 +104,25 @@ class eduGAIN_map { return(false); }; -// Generate world - + // Generate World Map $png_out = 'world_s'.$file_suffix.'.png'; $svg_out = 'world'.$file_suffix.'.svg'; $png_out_l = 'world_l'.$file_suffix.'.png'; + + // Load the world map SVG $xml = simplexml_load_file($maps_source.$world_in); + + // Loop through the countries and update the fill color based on their status for ($i = 0; $i < count($xml->g->path); $i++) { $buffer = $xml->g->path[$i]; $id = strtolower($buffer->attributes()->id); if (isset($Status["$id"]) && isset($Colours[$Status["$id"]])) { + // Apply the color style for each country $xml->g->path[$i]->attributes()->style = "fill: ".$Colours[$Status["$id"]].";"; } } + // Convert updated world SVG to XML and PNG $svg = $xml->asXML(); $png = new Imagick(); $png->setBackgroundColor(new ImagickPixel("transparent")); @@ -107,10 +135,13 @@ class eduGAIN_map { if (file_put_contents($maps_dir.$svg_out, $svg) === false) { return(false); } + + // Resize the world map PNG for smaller version $png->scaleImage(420, 350, true); if (file_put_contents($maps_dir.$png_out, $png) === false) { return(false); } + return(true); } } \ No newline at end of file diff --git a/lib/localAuth.php b/lib/localAuth.php index 8bd6d86c500622149fa587ccb8e9169c6bab359a..d0a3d713d5b513dc914462ae4fd98b860dbffc6e 100644 --- a/lib/localAuth.php +++ b/lib/localAuth.php @@ -1,53 +1,69 @@ <?php session_start(); -use Exception; - class localAuth { - + public function isAuthenticated() { + // Check if the session variable 'auth_ok' is set to 'authenticated' if (isset($_SESSION['auth_ok']) && $_SESSION['auth_ok'] == 'authenticated') { return true; } else { return false; } - } - + public function authenticate() { - Utils::debug(3,"Authenticating locally\n"); + Utils::debug(3, "Authenticating locally\n"); require_once(eduGAIN_config . "admin.php"); + + // Check if the 'user' POST parameter is set if (isset($_POST['user'])) { + // Check if the user exists in the $admins array if (array_key_exists($_POST['user'], $admins)) { - Utils::debug(3,"local AUTH testing\n"); + Utils::debug(3, "local AUTH testing\n"); + + // Validate the password using password_verify if (isset($_POST['passwd']) && password_verify($_POST['passwd'], $admins[$_POST['user']]['hash'])) { - Utils::debug(3,"local AUTH testing1\n"); + Utils::debug(3, "local AUTH testing1\n"); + // Set session variables if authentication is successful $_SESSION['auth_ok'] = 'authenticated'; $user = [ - 'user' => $admins[$_POST['useśr']]['mail'], + 'user' => $_POST['user'], // Corrected the corrupted key 'groups' => $admins[$_POST['user']]['groups'], 'email' => $admins[$_POST['user']]['mail'] ]; $_SESSION['user'] = $user; - Utils::debug(3,"local AUTH successful\n"); - header("Location: ".ROOT_URL."/authenticate"); + Utils::debug(3, "local AUTH successful\n"); + + // Redirect to the authenticate page + header("Location: " . ROOT_URL . "/authenticate"); exit; } } - Utils::debug(3,"local AUTH failed\n"); - header("Location: ".ROOT_URL."/authenticate?retry"); + // If authentication failed, redirect with a retry parameter + Utils::debug(3, "local AUTH failed\n"); + header("Location: " . ROOT_URL . "/authenticate?retry"); exit; } } - + public function getUser() { + // Check if the user session is set + if (!isset($_SESSION['user'])) { + return null; // Return null if the user session does not exist + } + require_once(eduGAIN_config . "admin.php"); $user = $_SESSION['user']; - $email = $admins[$user['user']]['mail']; - return(['user' => $user, 'groups' => $user['groups'], 'email' => $email]); - } - -} - + // Ensure the email is correctly fetched from the $admins array + $email = isset($admins[$user['user']]) ? $admins[$user['user']]['mail'] : null; + + return [ + 'user' => $user, + 'groups' => $user['groups'], + 'email' => $email + ]; + } +} \ No newline at end of file diff --git a/page-logic/manage.php b/page-logic/manage.php index 193e81b9859d049464eaa533124a1e7f40404544..d84676f7d95af731bfa38f5600919d40a28a65b7 100644 --- a/page-logic/manage.php +++ b/page-logic/manage.php @@ -9,25 +9,46 @@ Utils::debug(3,"Starting MANAGE\n"); class Management { public function __construct() { - $this->otpCode = filter_var($_POST['second_factor'], FILTER_SANITIZE_NUMBER_INT); + // Check if 'second_factor' is set in the POST request + $this->otpCode = isset($_POST['second_factor']) ? filter_var($_POST['second_factor'], FILTER_SANITIZE_NUMBER_INT) : null; + + // Include admin configuration require(eduGAIN_config . "admin.php"); - if (isset($_SESSION['user'])) { + + // Check if 'user' is set in the session and ensure it is an array + if (isset($_SESSION['user']) && is_array($_SESSION['user'])) { $this->user = $_SESSION['user']; $this->groups = $this->user['groups']; + } else { + // Handle the case where the user session is not set or is invalid + $this->user = null; + $this->groups = []; } + + // Set user role $this->setUserRole(); + + // Check if 'critical_save' is set in the POST request if (isset($_POST['critical_save']) && $_POST['critical_save'] == 1) { $this->criticalSave = 1; } } - + public function setMFA() { - Utils::debug(3,$_SESSION['mfa_authenticated'], "MFA auth: ", "\n"); - if (!isset($_SESSION['mfa_authenticated']) || $_SESSION['mfa_authenticated'] != 1) { - if ($this->verifyOtp($this->user, $this->otpCode) == 3) { - $this->authOtp(); - } - } + // Check if the 'mfa_authenticated' session key is set and if it's equal to 1 + if (isset($_SESSION['mfa_authenticated'])) { + Utils::debug(3, $_SESSION['mfa_authenticated'], "MFA auth: ", "\n"); + } else { + Utils::debug(3, "MFA authentication not set in session.\n"); + } + + // Proceed if MFA is not authenticated + if (!isset($_SESSION['mfa_authenticated']) || $_SESSION['mfa_authenticated'] != 1) { + // Verify OTP (One-Time Password) + if ($this->verifyOtp($this->user, $this->otpCode) == 3) { + $this->authOtp(); + } + } } public function verifyMFASetup() {