Repository: privacyidea/privacyidea

Issue:
Login with user@realm in webui not possible
This is a problem on the master branch we are currently working on.


Discussion:

Resolving patch:
diff --git a/privacyidea/api/auth.py b/privacyidea/api/auth.py
--- a/privacyidea/api/auth.py
+++ b/privacyidea/api/auth.py
@@ -116,7 +116,7 @@ def before_request():
         # On endpoints like /auth/rights, this is not available
         loginname, realm = split_user(username)
         # overwrite the split realm if we have a realm parameter. Default back to default_realm
-        realm = getParam(request.all_data, "realm", default=realm) or get_default_realm()
+        realm = getParam(request.all_data, "realm") or realm or get_default_realm()
         # Prefill the request.User. This is used by some pre-event handlers
         try:
             request.User = User(loginname, realm)


Test patch:
diff --git a/tests/test_api_auth.py b/tests/test_api_auth.py
--- a/tests/test_api_auth.py
+++ b/tests/test_api_auth.py
@@ -8,7 +8,8 @@
                                     delete_policy)
 from privacyidea.lib.auth import create_db_admin
 from privacyidea.lib.resolver import save_resolver, delete_resolver
-from privacyidea.lib.realm import set_realm, set_default_realm, delete_realm
+from privacyidea.lib.realm import (set_realm, set_default_realm, delete_realm,
+                                   get_default_realm)
 from privacyidea.lib.event import set_event, delete_event
 from privacyidea.lib.eventhandler.base import CONDITION
 from privacyidea.lib.token import get_tokens, remove_token
@@ -52,6 +53,9 @@ def test_01_auth_with_split(self):
             self.assertEqual(4031, result['error']['code'], result)
             self.assertEqual('Authentication failure. Wrong credentials',
                              result['error']['message'], result)
+        aentry = self.find_most_recent_audit_entry(action='POST /auth')
+        self.assertEqual(aentry['action'], 'POST /auth', aentry)
+        self.assertEqual(aentry['success'], 0, aentry)
 
         # test with realm added to user
         with self.app.test_request_context('/auth',
@@ -120,6 +124,8 @@ def test_01_auth_with_split(self):
             # realm1 should be the default realm
             self.assertEqual('realm1', result['value']['realm'], result)
 
+        # TODO: Add test with empty realm parameter and user@realm not in default realm
+
         # test with realm parameter and wrong realm added to user
         with mock.patch("logging.Logger.error") as mock_log:
             with self.app.test_request_context('/auth',
@@ -600,6 +606,48 @@ def test_05_local_admin_with_failing_resolver(self):
         delete_resolver("ldap1")
         ldap3mock.set_exception(False)
 
+    def test_06_auth_user_not_in_defrealm(self):
+        self.setUp_user_realms()
+        self.setUp_user_realm3()
+        set_default_realm(self.realm3)
+        # check that realm3 is the default realm
+        self.assertEqual(self.realm3, get_default_realm())
+        # authentication with "@realm1" works
+        with self.app.test_request_context('/auth',
+                                           method='POST',
+                                           data={"username": "selfservice@realm1",
+                                                 "password": "test"}):
+            res = self.app.full_dispatch_request()
+            self.assertEqual(res.status_code, 200, res)
+            result = res.json.get("result")
+            self.assertTrue(result.get("status"), result)
+            self.assertIn('token', result.get("value"), result)
+            self.assertEqual('realm1', result['value']['realm'], result)
+
+        # while authentication without a realm fails (user "selfservice"
+        # doesn't exist in default realm "realm3")
+        with self.app.test_request_context('/auth',
+                                           method='POST',
+                                           data={"username": "selfservice",
+                                                 "password": "test"}):
+            res = self.app.full_dispatch_request()
+            self.assertEqual(res.status_code, 401, res)
+            result = res.json.get("result")
+            self.assertFalse(result.get("status"), result)
+
+        # A given empty realm parameter should not change the realm of the user
+        with self.app.test_request_context('/auth',
+                                           method='POST',
+                                           data={"username": "selfservice@realm1",
+                                                 "password": "test",
+                                                 "realm": ""}):
+            res = self.app.full_dispatch_request()
+            self.assertEqual(res.status_code, 200, res)
+            result = res.json.get("result")
+            self.assertTrue(result.get("status"), result)
+            self.assertIn('token', result.get("value"), result)
+            self.assertEqual('realm1', result['value']['realm'], result)
+
 
 class AdminFromUserstore(OverrideConfigTestCase):
     class Config(TestingConfig):