Blob Blame History Raw
From 1bfea5967bb909e1b1bdc3267368e1465f7c9345 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 28 Sep 2022 12:45:52 +0200
Subject: [PATCH] ipatests: add negative test for otptoken-sync

Scenario:  call ipa otptoken-sync with
- an invalid password
- an invalid first token (containing non-digits)
- an invalid sequence of tokens

The test expects a return code = 1.

Related: https://pagure.io/freeipa/issue/9248
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 ipatests/test_integration/test_otp.py | 77 +++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
index 036b8d12c7e8d872204a31fa6b7ed0e151bed86b..32b41b79ad8bf44a298b28c259351d5a71a7e9ea 100644
--- a/ipatests/test_integration/test_otp.py
+++ b/ipatests/test_integration/test_otp.py
@@ -184,6 +184,83 @@ class TestOTPToken(IntegrationTest):
 
         del_otptoken(master, otpuid)
 
+    @pytest.fixture
+    def desynchronized_hotp(self):
+        """ Create an hotp token for user """
+        tasks.kinit_admin(self.master)
+        otpuid, hotp = add_otptoken(self.master, USER, otptype="hotp")
+
+        # skipping too many OTP fails
+        otp1 = hotp.generate(10).decode("ascii")
+        kinit_otp(self.master, USER, password=PASSWORD, otp=otp1, success=False)
+        # Now the token is desynchronized
+        yield (otpuid, hotp)
+
+        del_otptoken(self.master, otpuid)
+
+    def test_otptoken_sync_incorrect_password(self, desynchronized_hotp):
+        """ Test if sync fails when incorrect password is provided """
+        otpuid, hotp = desynchronized_hotp
+
+        otp2 = hotp.generate(20).decode("ascii")
+        otp3 = hotp.generate(21).decode("ascii")
+
+        # Try to sync with a wrong password
+        result = self.master.run_command(
+            ["ipa", "otptoken-sync", "--user", USER, otpuid],
+            stdin_text=f"invalidpwd\n{otp2}\n{otp3}\n", raiseonerr=False
+        )
+        assert result.returncode == 1
+        assert "Invalid Credentials!" in result.stderr_text
+
+        # Now sync with the right values
+        self.master.run_command(
+            ["ipa", "otptoken-sync", "--user", USER, otpuid],
+            stdin_text=f"{PASSWORD}\n{otp2}\n{otp3}\n"
+        )
+
+    def test_otptoken_sync_incorrect_first_value(self, desynchronized_hotp):
+        """ Test if sync fails when incorrect 1st token value is provided """
+        otpuid, hotp = desynchronized_hotp
+
+        otp2 = "12345a"
+        otp3 = hotp.generate(20).decode("ascii")
+        otp4 = hotp.generate(21).decode("ascii")
+
+        # Try to sync with a wrong first value (contains non-digit)
+        result = self.master.run_command(
+            ["ipa", "otptoken-sync", "--user", USER, otpuid],
+            stdin_text=f"{PASSWORD}\n{otp2}\n{otp3}\n", raiseonerr=False
+        )
+        assert result.returncode == 1
+        assert "Invalid Credentials!" in result.stderr_text
+
+        # Now sync with the right values
+        self.master.run_command(
+            ["ipa", "otptoken-sync", "--user", USER, otpuid],
+            stdin_text=f"{PASSWORD}\n{otp3}\n{otp4}\n"
+        )
+
+    def test_otptoken_sync_incorrect_second_value(self, desynchronized_hotp):
+        """ Test if sync fails when incorrect 2nd token value is provided """
+        otpuid, hotp = desynchronized_hotp
+
+        otp2 = hotp.generate(20).decode("ascii")
+        otp3 = hotp.generate(21).decode("ascii")
+        # Try to sync with wrong order
+        result = self.master.run_command(
+            ["ipa", "otptoken-sync", "--user", USER, otpuid],
+            stdin_text=f"{PASSWORD}\n{otp3}\n{otp2}\n", raiseonerr=False
+        )
+        assert result.returncode == 1
+        assert "Invalid Credentials!" in result.stderr_text
+
+        # Now sync with the right order
+        self.master.run_command(
+            ["ipa", "otptoken-sync", "--user", USER, otpuid],
+            stdin_text=f"{PASSWORD}\n{otp2}\n{otp3}\n"
+        )
+
     def test_totp(self):
         master = self.master
 
-- 
2.37.3