瀏覽代碼

[Web] Improve auth logging and language strings

FreddleSpl0it 5 月之前
父節點
當前提交
2596b9d386

+ 49 - 17
data/web/inc/functions.auth.inc.php

@@ -216,7 +216,7 @@ function user_login($user, $pass, $extra = null){
             unset($_SESSION['ldelay']);
             $_SESSION['return'][] =  array(
               'type' => 'success',
-              'log' => array(__FUNCTION__, $user, '*'),
+              'log' => array(__FUNCTION__, $user, '*', 'Provider: Keycloak'),
               'msg' => array('logged_in_as', $user)
             );
             return "pending";
@@ -229,7 +229,7 @@ function user_login($user, $pass, $extra = null){
               $stmt->execute(array(':user' => $user));
               $_SESSION['return'][] =  array(
                 'type' => 'success',
-                'log' => array(__FUNCTION__, $user, '*'),
+                'log' => array(__FUNCTION__, $user, '*', 'Provider: Keycloak'),
                 'msg' => array('logged_in_as', $user)
               );
             }
@@ -255,7 +255,7 @@ function user_login($user, $pass, $extra = null){
           unset($_SESSION['ldelay']);
           $_SESSION['return'][] =  array(
             'type' => 'success',
-            'log' => array(__FUNCTION__, $user, '*'),
+            'log' => array(__FUNCTION__, $user, '*', 'Provider: LDAP'),
             'msg' => array('logged_in_as', $user)
           );
           return "pending";
@@ -268,7 +268,7 @@ function user_login($user, $pass, $extra = null){
             $stmt->execute(array(':user' => $user));
             $_SESSION['return'][] =  array(
               'type' => 'success',
-              'log' => array(__FUNCTION__, $user, '*'),
+              'log' => array(__FUNCTION__, $user, '*', 'Provider: LDAP'),
               'msg' => array('logged_in_as', $user)
             );
           }
@@ -290,7 +290,7 @@ function user_login($user, $pass, $extra = null){
           unset($_SESSION['ldelay']);
           $_SESSION['return'][] =  array(
             'type' => 'success',
-            'log' => array(__FUNCTION__, $user, '*'),
+            'log' => array(__FUNCTION__, $user, '*', 'Provider: mailcow'),
             'msg' => array('logged_in_as', $user)
           );
           return "pending";
@@ -303,7 +303,7 @@ function user_login($user, $pass, $extra = null){
             $stmt->execute(array(':user' => $user));
             $_SESSION['return'][] =  array(
               'type' => 'success',
-              'log' => array(__FUNCTION__, $user, '*'),
+              'log' => array(__FUNCTION__, $user, '*', 'Provider: mailcow'),
               'msg' => array('logged_in_as', $user)
             );
           }
@@ -434,12 +434,27 @@ function keycloak_mbox_login_rest($user, $pass, $extra = null){
   $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
   curl_close($curl);
   if ($code != 200) {
+    $_SESSION['return'][] =  array(
+      'type' => 'danger',
+      'log' => array(__FUNCTION__, $user, '*', 'Identity Provider returned HTTP ' . $code),
+      'msg' => 'generic_server_error'
+    );
     return false;
   }
   if (!isset($user_res['attributes']['mailcow_password']) || !is_array($user_res['attributes']['mailcow_password'])){
+    $_SESSION['return'][] =  array(
+      'type' => 'danger',
+      'log' => array(__FUNCTION__, $user, '*', 'User has no mailcow_password attribute'),
+      'msg' => 'generic_server_error'
+    );
     return false;
   }
   if (empty($user_res['attributes']['mailcow_password'][0])){
+    $_SESSION['return'][] =  array(
+      'type' => 'danger',
+      'log' => array(__FUNCTION__, $user, '*', "User's mailcow_password attribute is empty"),
+      'msg' => 'generic_server_error'
+    );
     return false;
   }
 
@@ -469,8 +484,14 @@ function keycloak_mbox_login_rest($user, $pass, $extra = null){
   }
 
   // check if matching attribute exist
-  if (empty($iam_settings['mappers']) || !$user_template) return false;
-  if ($mapper_key === false) return false;
+  if (empty($iam_settings['mappers']) || !$user_template || $mapper_key === false) {
+    $_SESSION['return'][] =  array(
+      'type' => 'danger',
+      'log' => array(__FUNCTION__, $user, '*', 'No matching attribute mapping was found'),
+      'msg' => 'generic_server_error'
+    );
+    return false;
+  }
 
   // create mailbox
   $_SESSION['access_all_exception'] = '1';
@@ -484,6 +505,11 @@ function keycloak_mbox_login_rest($user, $pass, $extra = null){
   $_SESSION['access_all_exception'] = '0';
   if (!$create_res){
     clear_session();
+    $_SESSION['return'][] =  array(
+      'type' => 'danger',
+      'log' => array(__FUNCTION__, $user, '*', 'Could not create mailbox on login'),
+      'msg' => 'generic_server_error'
+    );
     return false;
   }
 
@@ -526,17 +552,12 @@ function ldap_mbox_login($user, $pass, $extra = null){
     $_SESSION['return'][] =  array(
       'type' => 'danger',
       'log' => array(__FUNCTION__, $user, '*', $e->getMessage()),
-      'msg' => 'ldap_error'
+      'msg' => 'generic_server_error'
     );
     return false;
   }
   try {
     if (!$iam_provider->auth()->attempt($user_res['dn'], $pass)) {
-      $_SESSION['return'][] =  array(
-        'type' => 'danger',
-        'log' => array(__FUNCTION__, $user, '*', $user_res),
-        'msg' => 'ldap_auth_failed'
-      );
       return false;
     }
   } catch (Exception $e) {
@@ -545,7 +566,7 @@ function ldap_mbox_login($user, $pass, $extra = null){
     $_SESSION['return'][] =  array(
       'type' => 'danger',
       'log' => array(__FUNCTION__, $user, '*', $e->getMessage()),
-      'msg' => 'ldap_error'
+      'msg' => 'generic_server_error'
     );
     return false;
   }
@@ -570,8 +591,14 @@ function ldap_mbox_login($user, $pass, $extra = null){
   }
 
   // check if matching attribute exist
-  if (empty($iam_settings['mappers']) || !$user_template) return false;
-  if ($mapper_key === false) return false;
+  if (empty($iam_settings['mappers']) || !$user_template || $mapper_key === false) {
+    $_SESSION['return'][] =  array(
+      'type' => 'danger',
+      'log' => array(__FUNCTION__, $user, '*', 'No matching attribute mapping was found'),
+      'msg' => 'generic_server_error'
+    );
+    return false;
+  }
 
   // create mailbox
   $_SESSION['access_all_exception'] = '1';
@@ -585,6 +612,11 @@ function ldap_mbox_login($user, $pass, $extra = null){
   $_SESSION['access_all_exception'] = '0';
   if (!$create_res){
     clear_session();
+    $_SESSION['return'][] =  array(
+      'type' => 'danger',
+      'log' => array(__FUNCTION__, $user, '*', 'Could not create mailbox on login'),
+      'msg' => 'generic_server_error'
+    );
     return false;
   }
 

+ 19 - 21
data/web/inc/functions.inc.php

@@ -2271,7 +2271,7 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
       }
       // return default client_scopes for generic-oidc if none is set
       if ($settings["authsource"] == "generic-oidc" && empty($settings["client_scopes"])){
-        $settings["client_scopes"] = "openid profile email";
+        $settings["client_scopes"] = "openid profile email mailcow_template";
       }
       if ($_extra['hide_sensitive']){
         $settings['client_secret'] = '';
@@ -2348,7 +2348,7 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
           $_data['authorize_url']     = (!empty($_data['authorize_url'])) ? $_data['authorize_url'] : null;
           $_data['token_url']         = (!empty($_data['token_url'])) ? $_data['token_url'] : null;
           $_data['userinfo_url']      = (!empty($_data['userinfo_url'])) ? $_data['userinfo_url'] : null;
-          $_data['client_scopes']     = (!empty($_data['client_scopes'])) ? $_data['client_scopes'] : "openid profile email";
+          $_data['client_scopes']     = (!empty($_data['client_scopes'])) ? $_data['client_scopes'] : "openid profile email mailcow_template";
           $required_settings          = array('authsource', 'authorize_url', 'token_url', 'client_id', 'client_secret', 'redirect_url', 'userinfo_url', 'client_scopes', 'ignore_ssl_error');
         break;
         case "ldap":
@@ -2619,8 +2619,8 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
       if ($iam_settings['authsource'] != 'keycloak' && $iam_settings['authsource'] != 'generic-oidc'){
         $_SESSION['return'][] =  array(
           'type' => 'danger',
-          'log' => array(__FUNCTION__),
-          'msg' => array('login_failed', "no OIDC provider configured")
+          'log' => array(__FUNCTION__, "no OIDC provider configured"),
+          'msg' => 'login_failed'
         );
         return false;
       }
@@ -2633,13 +2633,20 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
       } catch (Throwable $e) {
         $_SESSION['return'][] =  array(
           'type' => 'danger',
-          'log' => array(__FUNCTION__),
-          'msg' => array('login_failed', $e->getMessage())
+          'log' => array(__FUNCTION__, $e->getMessage()),
+          'msg' => 'login_failed'
         );
         return false;
       }
       // check if email address is given
-      if (empty($info['email'])) return false;
+      if (empty($info['email'])) {
+        $_SESSION['return'][] =  array(
+          'type' => 'danger',
+          'log' => array(__FUNCTION__, 'No email address found for user'),
+          'msg' => 'login_failed'
+        );
+        return false;
+      }
 
       // get mapped template
       $user_template = $info['mailcow_template'];
@@ -2678,21 +2685,12 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
         return true;
       }
 
-      if (empty($iam_settings['mappers']) || empty($user_template)){
+      if (empty($iam_settings['mappers']) || empty($user_template) || $mapper_key === false){
         clear_session();
         $_SESSION['return'][] =  array(
           'type' => 'danger',
-          'log' => array(__FUNCTION__, $info['email']),
-          'msg' => array('login_failed', 'empty attribute mapping or missing template attribute')
-        );
-        return false;
-      }
-      if ($mapper_key === false) {
-        clear_session();
-        $_SESSION['return'][] =  array(
-          'type' => 'danger',
-          'log' => array(__FUNCTION__, $info['email']),
-          'msg' => array('login_failed', 'specified template not found')
+          'log' => array(__FUNCTION__, $info['email'], 'No matching attribute mapping was found'),
+          'msg' => 'login_failed'
         );
         return false;
       }
@@ -2711,8 +2709,8 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
         clear_session();
         $_SESSION['return'][] =  array(
           'type' => 'danger',
-          'log' => array(__FUNCTION__, $info['email']),
-          'msg' => array('login_failed', 'mailbox creation failed')
+          'log' => array(__FUNCTION__, $info['email'], 'Could not create mailbox on login'),
+          'msg' => 'login_failed'
         );
         return false;
       }

+ 5 - 3
data/web/lang/lang.de-de.json

@@ -219,10 +219,10 @@
         "iam_extra_permission": "Damit die folgenden Einstellungen funktionieren, benötigt der mailcow Client in Keycloak ein <code>Service-Konto</code> und die Berechtigung <code>view-users</code>.",
         "iam_host": "Host",
         "iam_host_info": "Gib einen oder mehrere LDAP-Hosts ein, getrennt durch Kommas.",
-        "iam_import_users": "Import Users",
+        "iam_import_users": "Importiere Benutzer",
         "iam_mapping": "Attribut Mapping",
         "iam_bindpass": "Bind Passwort",
-        "iam_periodic_full_sync": "Periodic Full Sync",
+        "iam_periodic_full_sync": "Vollsynchronisation",
         "iam_port": "Port",
         "iam_realm": "Realm",
         "iam_redirect_url": "Redirect Url",
@@ -238,7 +238,7 @@
         "iam_use_ssl": "Benutze SSL",
         "iam_use_tls": "Benutze TLS",
         "iam_version": "Version",
-        "ignore_ssl_error": "Ignoriere SSL Errors",
+        "ignore_ssl_error": "Ignoriere SSL Fehler",
         "import": "Importieren",
         "import_private_key": "Private Key importieren",
         "in_use_by": "Verwendet von",
@@ -406,6 +406,7 @@
         "aliases_in_use": "Maximale Anzahl an Aliassen muss größer oder gleich %d sein",
         "app_name_empty": "App-Name darf nicht leer sein",
         "app_passwd_id_invalid": "App-Passwort ID %s ist ungültig",
+        "authsource_in_use": "Der Identity Provider kann nicht geändert oder gelöscht werden, da er derzeit von einem oder mehreren Benutzern verwendet wird.",
         "bcc_empty": "BCC-Ziel darf nicht leer sein",
         "bcc_exists": "Ein BCC-Map-Eintrag %s existiert bereits als Typ %s",
         "bcc_must_be_email": "BCC-Ziel %s ist keine gültige E-Mail-Adresse",
@@ -430,6 +431,7 @@
         "file_open_error": "Datei kann nicht zum Schreiben geöffnet werden",
         "filter_type": "Falscher Filtertyp",
         "from_invalid": "Die Absenderadresse muss eine gültige E-Mail-Adresse sein",
+        "generic_server_error": "Ein unerwarteter Serverfehler ist aufgetreten. Bitte kontaktieren Sie Ihren Administrator.",
         "global_filter_write_error": "Kann Filterdatei nicht schreiben: %s",
         "global_map_invalid": "Rspamd-Map %s ist ungültig",
         "global_map_write_error": "Kann globale Map ID %s nicht schreiben: %s",

+ 1 - 0
data/web/lang/lang.en-gb.json

@@ -433,6 +433,7 @@
         "file_open_error": "File cannot be opened for writing",
         "filter_type": "Wrong filter type",
         "from_invalid": "Sender must not be empty",
+        "generic_server_error": "An unexpected server error occurred. Please contact your administrator.",
         "global_filter_write_error": "Could not write filter file: %s",
         "global_map_invalid": "Global map ID %s invalid",
         "global_map_write_error": "Could not write global map ID %s: %s",

+ 1 - 1
data/web/templates/admin/tab-config-identity-provider.twig

@@ -265,7 +265,7 @@
               <label class="control-label" for="iam_client_scopes">{{ lang.admin.iam_client_scopes }}:</label>
             </div>
             <div class="col-12 col-md-9 col-lg-4">
-              <input type="text" placeholder="openid profile email" class="form-control" id="iam_client_scopes" name="client_scopes" value="{{ iam_settings.client_scopes }}">
+              <input type="text" placeholder="openid profile email mailcow_template" class="form-control" id="iam_client_scopes" name="client_scopes" value="{{ iam_settings.client_scopes }}">
             </div>
           </div>
           <div class="row mb-2">