summaryrefslogtreecommitdiff
path: root/app/src/test
diff options
context:
space:
mode:
authorHarsh Shandilya <msfjarvis@gmail.com>2020-06-29 12:08:59 +0530
committerGitHub <noreply@github.com>2020-06-29 12:08:59 +0530
commit063c1a1144bb50845ecfb7d56eea16e4db4540e4 (patch)
treeeb237a470953264a54f2854f0e534bb2ab682927 /app/src/test
parent56c301dc7c5353d7f7021e04441104cfe42c063f (diff)
Reintroduce TOTP support (#890)
Co-authored-by: Fabian Henneke <fabian@henneke.me>
Diffstat (limited to 'app/src/test')
-rw-r--r--app/src/test/java/com/zeapo/pwdstore/PasswordEntryTest.kt63
-rw-r--r--app/src/test/java/com/zeapo/pwdstore/model/PasswordEntryTest.kt107
-rw-r--r--app/src/test/java/com/zeapo/pwdstore/utils/OtpTest.kt50
3 files changed, 157 insertions, 63 deletions
diff --git a/app/src/test/java/com/zeapo/pwdstore/PasswordEntryTest.kt b/app/src/test/java/com/zeapo/pwdstore/PasswordEntryTest.kt
deleted file mode 100644
index 2074f40b..00000000
--- a/app/src/test/java/com/zeapo/pwdstore/PasswordEntryTest.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-package com.zeapo.pwdstore
-
-import org.junit.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertFalse
-import kotlin.test.assertNull
-import kotlin.test.assertTrue
-
-class PasswordEntryTest {
- @Test fun testGetPassword() {
- assertEquals("fooooo", PasswordEntry("fooooo\nbla\n").password)
- assertEquals("fooooo", PasswordEntry("fooooo\nbla").password)
- assertEquals("fooooo", PasswordEntry("fooooo\n").password)
- assertEquals("fooooo", PasswordEntry("fooooo").password)
- assertEquals("", PasswordEntry("\nblubb\n").password)
- assertEquals("", PasswordEntry("\nblubb").password)
- assertEquals("", PasswordEntry("\n").password)
- assertEquals("", PasswordEntry("").password)
- }
-
- @Test fun testGetExtraContent() {
- assertEquals("bla\n", PasswordEntry("fooooo\nbla\n").extraContent)
- assertEquals("bla", PasswordEntry("fooooo\nbla").extraContent)
- assertEquals("", PasswordEntry("fooooo\n").extraContent)
- assertEquals("", PasswordEntry("fooooo").extraContent)
- assertEquals("blubb\n", PasswordEntry("\nblubb\n").extraContent)
- assertEquals("blubb", PasswordEntry("\nblubb").extraContent)
- assertEquals("", PasswordEntry("\n").extraContent)
- assertEquals("", PasswordEntry("").extraContent)
- }
-
- @Test fun testGetUsername() {
- for (field in PasswordEntry.USERNAME_FIELDS) {
- assertEquals("username", PasswordEntry("\n$field username").username)
- assertEquals("username", PasswordEntry("\n${field.toUpperCase()} username").username)
- }
- assertEquals(
- "username",
- PasswordEntry("secret\nextra\nlogin: username\ncontent\n").username)
- assertEquals(
- "username",
- PasswordEntry("\nextra\nusername: username\ncontent\n").username)
- assertEquals(
- "username", PasswordEntry("\nUSERNaMe: username\ncontent\n").username)
- assertEquals("username", PasswordEntry("\nlogin: username").username)
- assertEquals("foo@example.com", PasswordEntry("\nemail: foo@example.com").username)
- assertEquals("username", PasswordEntry("\nidentity: username\nlogin: another_username").username)
- assertEquals("username", PasswordEntry("\nLOGiN:username").username)
- assertNull(PasswordEntry("secret\nextra\ncontent\n").username)
- }
-
- @Test fun testHasUsername() {
- assertTrue(PasswordEntry("secret\nextra\nlogin: username\ncontent\n").hasUsername())
- assertFalse(PasswordEntry("secret\nextra\ncontent\n").hasUsername())
- assertFalse(PasswordEntry("secret\nlogin failed\n").hasUsername())
- assertFalse(PasswordEntry("\n").hasUsername())
- assertFalse(PasswordEntry("").hasUsername())
- }
-}
diff --git a/app/src/test/java/com/zeapo/pwdstore/model/PasswordEntryTest.kt b/app/src/test/java/com/zeapo/pwdstore/model/PasswordEntryTest.kt
new file mode 100644
index 00000000..f31709df
--- /dev/null
+++ b/app/src/test/java/com/zeapo/pwdstore/model/PasswordEntryTest.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+package com.zeapo.pwdstore.model
+
+import com.zeapo.pwdstore.utils.Otp
+import com.zeapo.pwdstore.utils.TotpFinder
+import org.junit.Test
+import java.util.Date
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
+import kotlin.test.assertTrue
+
+class PasswordEntryTest {
+ private fun makeEntry(content: String) = PasswordEntry(content, testFinder)
+
+ @Test fun testGetPassword() {
+ assertEquals("fooooo", makeEntry("fooooo\nbla\n").password)
+ assertEquals("fooooo", makeEntry("fooooo\nbla").password)
+ assertEquals("fooooo", makeEntry("fooooo\n").password)
+ assertEquals("fooooo", makeEntry("fooooo").password)
+ assertEquals("", makeEntry("\nblubb\n").password)
+ assertEquals("", makeEntry("\nblubb").password)
+ assertEquals("", makeEntry("\n").password)
+ assertEquals("", makeEntry("").password)
+ }
+
+ @Test fun testGetExtraContent() {
+ assertEquals("bla\n", makeEntry("fooooo\nbla\n").extraContent)
+ assertEquals("bla", makeEntry("fooooo\nbla").extraContent)
+ assertEquals("", makeEntry("fooooo\n").extraContent)
+ assertEquals("", makeEntry("fooooo").extraContent)
+ assertEquals("blubb\n", makeEntry("\nblubb\n").extraContent)
+ assertEquals("blubb", makeEntry("\nblubb").extraContent)
+ assertEquals("", makeEntry("\n").extraContent)
+ assertEquals("", makeEntry("").extraContent)
+ }
+
+ @Test fun testGetUsername() {
+ for (field in PasswordEntry.USERNAME_FIELDS) {
+ assertEquals("username", makeEntry("\n$field username").username)
+ assertEquals("username", makeEntry("\n${field.toUpperCase()} username").username)
+ }
+ assertEquals(
+ "username",
+ makeEntry("secret\nextra\nlogin: username\ncontent\n").username)
+ assertEquals(
+ "username",
+ makeEntry("\nextra\nusername: username\ncontent\n").username)
+ assertEquals(
+ "username", makeEntry("\nUSERNaMe: username\ncontent\n").username)
+ assertEquals("username", makeEntry("\nlogin: username").username)
+ assertEquals("foo@example.com", makeEntry("\nemail: foo@example.com").username)
+ assertEquals("username", makeEntry("\nidentity: username\nlogin: another_username").username)
+ assertEquals("username", makeEntry("\nLOGiN:username").username)
+ assertNull(makeEntry("secret\nextra\ncontent\n").username)
+ }
+
+ @Test fun testHasUsername() {
+ assertTrue(makeEntry("secret\nextra\nlogin: username\ncontent\n").hasUsername())
+ assertFalse(makeEntry("secret\nextra\ncontent\n").hasUsername())
+ assertFalse(makeEntry("secret\nlogin failed\n").hasUsername())
+ assertFalse(makeEntry("\n").hasUsername())
+ assertFalse(makeEntry("").hasUsername())
+ }
+
+ @Test fun testGeneratesOtpFromTotpUri() {
+ val entry = makeEntry("secret\nextra\n$TOTP_URI")
+ assertTrue(entry.hasTotp())
+ val code = Otp.calculateCode(
+ entry.totpSecret!!,
+ // The hardcoded date value allows this test to stay reproducible.
+ Date(8640000).time / (1000 * entry.totpPeriod),
+ entry.totpAlgorithm,
+ entry.digits
+ )
+ assertNotNull(code) { "Generated OTP cannot be null" }
+ assertEquals(entry.digits.toInt(), code.length)
+ assertEquals("545293", code)
+ }
+
+ companion object {
+ const val TOTP_URI = "otpauth://totp/ACME%20Co:john@example.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm=SHA1&digits=6&period=30"
+
+ // This implementation is hardcoded for the URI above.
+ val testFinder = object : TotpFinder {
+ override fun findSecret(content: String): String? {
+ return "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"
+ }
+
+ override fun findDigits(content: String): String {
+ return "6"
+ }
+
+ override fun findPeriod(content: String): Long {
+ return 30
+ }
+
+ override fun findAlgorithm(content: String): String {
+ return "SHA1"
+ }
+ }
+ }
+}
diff --git a/app/src/test/java/com/zeapo/pwdstore/utils/OtpTest.kt b/app/src/test/java/com/zeapo/pwdstore/utils/OtpTest.kt
new file mode 100644
index 00000000..710b0845
--- /dev/null
+++ b/app/src/test/java/com/zeapo/pwdstore/utils/OtpTest.kt
@@ -0,0 +1,50 @@
+package com.zeapo.pwdstore.utils
+
+import org.junit.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
+
+class OtpTest {
+
+ @Test
+ fun testOtpGeneration6Digits() {
+ assertEquals("953550", Otp.calculateCode("JBSWY3DPEHPK3PXP", 1593333298159 / (1000 * 30), "SHA1", "6"))
+ assertEquals("275379", Otp.calculateCode("JBSWY3DPEHPK3PXP", 1593333571918 / (1000 * 30), "SHA1", "6"))
+ assertEquals("867507", Otp.calculateCode("JBSWY3DPEHPK3PXP", 1593333600517 / (1000 * 57), "SHA1", "6"))
+ }
+
+ @Test
+ fun testOtpGeneration10Digits() {
+ assertEquals("0740900914", Otp.calculateCode("JBSWY3DPEHPK3PXP", 1593333655044 / (1000 * 30), "SHA1", "10"))
+ assertEquals("0070632029", Otp.calculateCode("JBSWY3DPEHPK3PXP", 1593333691405 / (1000 * 30), "SHA1", "10"))
+ assertEquals("1017265882", Otp.calculateCode("JBSWY3DPEHPK3PXP", 1593333728893 / (1000 * 83), "SHA1", "10"))
+ }
+
+ @Test
+ fun testOtpGenerationIllegalInput() {
+ assertNull(Otp.calculateCode("JBSWY3DPEHPK3PXP", 10000, "SHA0", "10"))
+ assertNull(Otp.calculateCode("JBSWY3DPEHPK3PXP", 10000, "SHA1", "a"))
+ assertNull(Otp.calculateCode("JBSWY3DPEHPK3PXP", 10000, "SHA1", "5"))
+ assertNull(Otp.calculateCode("JBSWY3DPEHPK3PXP", 10000, "SHA1", "11"))
+ assertNull(Otp.calculateCode("JBSWY3DPEHPK3PXPAAAAB", 10000, "SHA1", "6"))
+ }
+
+ @Test
+ fun testOtpGenerationUnusualSecrets() {
+ assertEquals("127764", Otp.calculateCode("JBSWY3DPEHPK3PXPAAAAAAAA", 1593367111963 / (1000 * 30), "SHA1", "6"))
+ assertEquals("047515", Otp.calculateCode("JBSWY3DPEHPK3PXPAAAAA", 1593367171420 / (1000 * 30), "SHA1", "6"))
+ }
+
+ @Test
+ fun testOtpGenerationUnpaddedSecrets() {
+ // Secret was generated with `echo 'string with some padding needed' | base32`
+ // We don't care for the resultant OTP's actual value, we just want both the padded and
+ // unpadded variant to generate the same one.
+ val unpaddedOtp = Otp.calculateCode("ON2HE2LOM4QHO2LUNAQHG33NMUQHAYLEMRUW4ZZANZSWKZDFMQFA", 1593367171420 / (1000 * 30), "SHA1", "6")
+ val paddedOtp = Otp.calculateCode("ON2HE2LOM4QHO2LUNAQHG33NMUQHAYLEMRUW4ZZANZSWKZDFMQFA====", 1593367171420 / (1000 * 30), "SHA1", "6")
+ assertNotNull(unpaddedOtp)
+ assertNotNull(paddedOtp)
+ assertEquals(unpaddedOtp, paddedOtp)
+ }
+}