Browse Source

[Web] Add identity_provider option to disable auto-creation of users on login

FreddleSpl0it 3 months ago
parent
commit
1b2f424edc

+ 25 - 8
data/web/inc/functions.auth.inc.php

@@ -262,10 +262,6 @@ function user_login($user, $pass, $extra = null){
             return false;
           }
 
-          if (intval($row['attributes']['force_pw_update']) == 1) {
-            $_SESSION['pending_pw_update'] = true;
-          }
-
           // check for tfa authenticators
           $authenticators = get_tfa($user);
           if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0 && !$is_internal) {
@@ -318,10 +314,6 @@ function user_login($user, $pass, $extra = null){
           return false;
         }
 
-        if (intval($row['attributes']['force_pw_update']) == 1) {
-          $_SESSION['pending_pw_update'] = true;
-        }
-
         // check for tfa authenticators
         $authenticators = get_tfa($user);
         if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0 && !$is_internal) {
@@ -485,6 +477,9 @@ function keycloak_mbox_login_rest($user, $pass, $extra = null){
     }
     return false;
   }
+  if (!$iam_provider) {
+    return false;
+  }
 
   // get access_token for service account of mailcow client
   $admin_token = identity_provider("get-keycloak-admin-token");
@@ -554,6 +549,17 @@ function keycloak_mbox_login_rest($user, $pass, $extra = null){
     return 'user';
   }
 
+  // check if login provisioning is enabled before creating user
+  if (!$iam_settings['login_provisioning']){
+    if (!$is_internal){
+      $_SESSION['return'][] =  array(
+        'type' => 'danger',
+        'log' => array(__FUNCTION__, "Auto-create users on login is deactivated"),
+        'msg' => 'login_failed'
+      );
+    }
+    return false;
+  }
   // check if matching attribute exist
   if (empty($iam_settings['mappers']) || !$user_template || $mapper_key === false) {
     if (!empty($iam_settings['default_template'])) {
@@ -667,6 +673,17 @@ function ldap_mbox_login($user, $pass, $extra = null){
     return 'user';
   }
 
+  // check if login provisioning is enabled before creating user
+  if (!$iam_settings['login_provisioning']){
+    if (!$is_internal){
+      $_SESSION['return'][] =  array(
+        'type' => 'danger',
+        'log' => array(__FUNCTION__, "Auto-create users on login is deactivated"),
+        'msg' => 'login_failed'
+      );
+    }
+    return false;
+  }
   // check if matching attribute exist
   if (empty($iam_settings['mappers']) || !$user_template || $mapper_key === false) {
     if (!empty($iam_settings['default_tempalte'])) {

+ 20 - 4
data/web/inc/functions.inc.php

@@ -2294,6 +2294,7 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
           break;
           case "use_ssl":
           case "use_tls":
+          case "login_provisioning":
           case "ignore_ssl_errors":
             $settings[$row["key"]] = boolval($row["value"]);
           break;
@@ -2302,6 +2303,10 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
           break;
         }
       }
+      // set login_provisioning if not exists
+      if (!array_key_exists('login_provisioning', $settings)) {
+        $settings['login_provisioning'] = 1;
+      }
       // 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 mailcow_template";
@@ -2366,7 +2371,8 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
         return false;
       }
 
-      $_data['ignore_ssl_error']  = isset($_data['ignore_ssl_error']) ? boolval($_data['ignore_ssl_error']) : false;
+      $_data['ignore_ssl_error']    = isset($_data['ignore_ssl_error']) ? boolval($_data['ignore_ssl_error']) : false;
+      $_data['login_provisioning']  = isset($_data['login_provisioning']) ? boolval($_data['login_provisioning']) : false;
       switch ($_data['authsource']) {
         case "keycloak":
           $_data['server_url']        = (!empty($_data['server_url'])) ? rtrim($_data['server_url'], '/') : null;
@@ -2375,14 +2381,14 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
           $_data['import_users']      = isset($_data['import_users']) ? intval($_data['import_users']) : 0;
           $_data['sync_interval']     = (!empty($_data['sync_interval'])) ? intval($_data['sync_interval']) : 15;
           $_data['sync_interval']     = $_data['sync_interval'] < 1 ? 1 : $_data['sync_interval'];
-          $required_settings          = array('authsource', 'server_url', 'realm', 'client_id', 'client_secret', 'redirect_url', 'version', 'mailpassword_flow', 'periodic_sync', 'import_users', 'sync_interval', 'ignore_ssl_error');
+          $required_settings          = array('authsource', 'server_url', 'realm', 'client_id', 'client_secret', 'redirect_url', 'version', 'mailpassword_flow', 'periodic_sync', 'import_users', 'sync_interval', 'ignore_ssl_error', 'login_provisioning');
         break;
         case "generic-oidc":
           $_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 mailcow_template";
-          $required_settings          = array('authsource', 'authorize_url', 'token_url', 'client_id', 'client_secret', 'redirect_url', 'userinfo_url', 'client_scopes', 'ignore_ssl_error');
+          $required_settings          = array('authsource', 'authorize_url', 'token_url', 'client_id', 'client_secret', 'redirect_url', 'userinfo_url', 'client_scopes', 'ignore_ssl_error', 'login_provisioning');
         break;
         case "ldap":
           $_data['host']              = (!empty($_data['host'])) ? str_replace(" ", "", $_data['host']) : "";
@@ -2396,7 +2402,7 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
           $_data['use_tls']           = isset($_data['use_tls']) && !$_data['use_ssl'] ? boolval($_data['use_tls']) : false;
           $_data['sync_interval']     = (!empty($_data['sync_interval'])) ? intval($_data['sync_interval']) : 15;
           $_data['sync_interval']     = $_data['sync_interval'] < 1 ? 1 : $_data['sync_interval'];
-          $required_settings          = array('authsource', 'host', 'port', 'basedn', 'username_field', 'filter', 'attribute_field', 'binddn', 'bindpass', 'periodic_sync', 'import_users', 'sync_interval', 'use_ssl', 'use_tls', 'ignore_ssl_error');
+          $required_settings          = array('authsource', 'host', 'port', 'basedn', 'username_field', 'filter', 'attribute_field', 'binddn', 'bindpass', 'periodic_sync', 'import_users', 'sync_interval', 'use_ssl', 'use_tls', 'ignore_ssl_error', 'login_provisioning');
         break;
       }
 
@@ -2766,6 +2772,16 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
         return true;
       }
 
+      // user doesn't exist, check if login provisioning is enabled
+      if (!$iam_settings['login_provisioning']){
+        $_SESSION['return'][] =  array(
+          'type' => 'danger',
+          'log' => array(__FUNCTION__, "Auto-create users on login is deactivated"),
+          'msg' => 'login_failed'
+        );
+        return false;
+      }
+
       if (empty($iam_settings['mappers']) || empty($user_template) || $mapper_key === false){
         if (!empty($iam_settings['default_template'])) {
           $mbox_template = $iam_settings['default_template'];

+ 1 - 0
data/web/lang/lang.de-de.json

@@ -227,6 +227,7 @@
         "iam_host": "Host",
         "iam_host_info": "Gib einen oder mehrere LDAP-Hosts ein, getrennt durch Kommas.",
         "iam_import_users": "Importiere Benutzer",
+        "iam_login_provisioning": "Benutzer beim Login erstellen",
         "iam_mapping": "Attribut Mapping",
         "iam_bindpass": "Bind Passwort",
         "iam_periodic_full_sync": "Vollsynchronisation",

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

@@ -234,6 +234,7 @@
         "iam_host": "Host",
         "iam_host_info": "Enter one or more LDAP hosts, separated by commas.",
         "iam_import_users": "Import Users",
+        "iam_login_provisioning": "Auto-create users on login",
         "iam_mapping": "Attribute Mapping",
         "iam_bindpass": "Bind Password",
         "iam_periodic_full_sync": "Periodic Full Sync",

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

@@ -219,6 +219,16 @@
               </div>
             </div>
           </div>
+          <div class="row mb-2">
+            <div class="col-md-3 d-flex align-items-center justify-content-md-end">
+              <label class="control-label">{{ lang.admin.iam_login_provisioning }}</label>
+            </div>
+            <div class="col-12 col-md-9">
+              <div class="form-check form-switch">
+                <input class="form-check-input" type="checkbox" role="switch" name="login_provisioning"  value="1" {% if iam_settings.login_provisioning == 1 %}checked{% endif %}>
+              </div>
+            </div>
+          </div>
           <div class="row mb-2">
             <div class="col-md-3 d-flex align-items-center justify-content-md-end">
               <label class="control-label">{{ lang.admin.iam_periodic_full_sync }}</label>
@@ -430,7 +440,7 @@
               </div>
             </div>
           </div>
-          <div class="row mb-4">
+          <div class="row mb-2">
             <div class="col-md-3 d-flex align-items-center justify-content-md-end">
               <label class="control-label">{{ lang.admin.ignore_ssl_error }}</label>
             </div>
@@ -440,6 +450,16 @@
               </div>
             </div>
           </div>
+          <div class="row mb-4">
+            <div class="col-md-3 d-flex align-items-center justify-content-md-end">
+              <label class="control-label">{{ lang.admin.iam_login_provisioning }}</label>
+            </div>
+            <div class="col-12 col-md-9">
+              <div class="form-check form-switch">
+                <input class="form-check-input" type="checkbox" role="switch" name="login_provisioning"  value="1" {% if iam_settings.login_provisioning == 1 %}checked{% endif %}>
+              </div>
+            </div>
+          </div>
           <div class="row mt-4 mb-2">
             <div class="offset-md-3 col-12 col-md-9 d-flex flex-wrap">
               <div class="btn-group mb-2">
@@ -646,6 +666,16 @@
               </div>
             </div>
           </div>
+          <div class="row mb-2">
+            <div class="col-md-3 d-flex align-items-center justify-content-md-end">
+              <label class="control-label">{{ lang.admin.iam_login_provisioning }}</label>
+            </div>
+            <div class="col-12 col-md-9">
+              <div class="form-check form-switch">
+                <input class="form-check-input" type="checkbox" role="switch" name="login_provisioning"  value="1" {% if iam_settings.login_provisioning == 1 %}checked{% endif %}>
+              </div>
+            </div>
+          </div>
           <div class="row mb-2">
             <div class="col-md-3 d-flex align-items-center justify-content-md-end">
               <label class="control-label">{{ lang.admin.iam_periodic_full_sync }}</label>