Add 'twofactor/' from commit 'c999bf35b0e47de4f63d59abbe0d7efc76c13ced'
git-subtree-dir: twofactor git-subtree-mainline:4dc135cfe0git-subtree-split:c999bf35b0
This commit is contained in:
136
twofactor/otp_test.go
Normal file
136
twofactor/otp_test.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package twofactor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHOTPString(t *testing.T) {
|
||||
hotp := NewHOTP(nil, 0, 6)
|
||||
hotpString := otpString(hotp)
|
||||
if hotpString != "OATH-HOTP, 6" {
|
||||
fmt.Println("twofactor: invalid OTP string")
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// This test generates a new OTP, outputs the URL for that OTP,
|
||||
// and attempts to parse that URL. It verifies that the two OTPs
|
||||
// are the same, and that they produce the same output.
|
||||
func TestURL(t *testing.T) {
|
||||
var ident = "testuser@foo"
|
||||
otp := NewHOTP(testKey, 0, 6)
|
||||
url := otp.URL("testuser@foo")
|
||||
otp2, id, err := FromURL(url)
|
||||
if err != nil {
|
||||
fmt.Printf("hotp: failed to parse HOTP URL\n")
|
||||
t.FailNow()
|
||||
} else if id != ident {
|
||||
fmt.Printf("hotp: bad label\n")
|
||||
fmt.Printf("\texpected: %s\n", ident)
|
||||
fmt.Printf("\t actual: %s\n", id)
|
||||
t.FailNow()
|
||||
} else if otp2.Counter() != otp.Counter() {
|
||||
fmt.Printf("hotp: OTP counters aren't synced\n")
|
||||
fmt.Printf("\toriginal: %d\n", otp.Counter())
|
||||
fmt.Printf("\t second: %d\n", otp2.Counter())
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
code1 := otp.OTP()
|
||||
code2 := otp2.OTP()
|
||||
if code1 != code2 {
|
||||
fmt.Printf("hotp: mismatched OTPs\n")
|
||||
fmt.Printf("\texpected: %s\n", code1)
|
||||
fmt.Printf("\t actual: %s\n", code2)
|
||||
}
|
||||
|
||||
// There's not much we can do test the QR code, except to
|
||||
// ensure it doesn't fail.
|
||||
_, err = otp.QR(ident)
|
||||
if err != nil {
|
||||
fmt.Printf("hotp: failed to generate QR code PNG (%v)\n", err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// This should fail because the maximum size of an alphanumeric
|
||||
// QR code with the lowest-level of error correction should
|
||||
// max out at 4296 bytes. 8k may be a bit overkill... but it
|
||||
// gets the job done. The value is read from the PRNG to
|
||||
// increase the likelihood that the returned data is
|
||||
// uncompressible.
|
||||
var tooBigIdent = make([]byte, 8192)
|
||||
_, err = io.ReadFull(PRNG, tooBigIdent)
|
||||
if err != nil {
|
||||
fmt.Printf("hotp: failed to read identity (%v)\n", err)
|
||||
t.FailNow()
|
||||
} else if _, err = otp.QR(string(tooBigIdent)); err == nil {
|
||||
fmt.Println("hotp: QR code should fail to encode oversized URL")
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// This test makes sure we can generate codes for padded and non-padded
|
||||
// entries
|
||||
func TestPaddedURL(t *testing.T) {
|
||||
var urlList = []string{
|
||||
"otpauth://hotp/?secret=ME",
|
||||
"otpauth://hotp/?secret=MEFR",
|
||||
"otpauth://hotp/?secret=MFRGG",
|
||||
"otpauth://hotp/?secret=MFRGGZA",
|
||||
"otpauth://hotp/?secret=a6mryljlbufszudtjdt42nh5by=======",
|
||||
"otpauth://hotp/?secret=a6mryljlbufszudtjdt42nh5by",
|
||||
"otpauth://hotp/?secret=a6mryljlbufszudtjdt42nh5by%3D%3D%3D%3D%3D%3D%3D",
|
||||
}
|
||||
var codeList = []string{
|
||||
"413198",
|
||||
"770938",
|
||||
"670717",
|
||||
"402378",
|
||||
"069864",
|
||||
"069864",
|
||||
"069864",
|
||||
}
|
||||
|
||||
for i := range urlList {
|
||||
if o, id, err := FromURL(urlList[i]); err != nil {
|
||||
fmt.Println("hotp: URL should have parsed successfully (id=", id, ")")
|
||||
fmt.Printf("\turl was: %s\n", urlList[i])
|
||||
t.FailNow()
|
||||
fmt.Printf("\t%s, %s\n", o.OTP(), id)
|
||||
} else {
|
||||
code2 := o.OTP()
|
||||
if code2 != codeList[i] {
|
||||
fmt.Printf("hotp: mismatched OTPs\n")
|
||||
fmt.Printf("\texpected: %s\n", codeList[i])
|
||||
fmt.Printf("\t actual: %s\n", code2)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This test attempts a variety of invalid urls against the parser
|
||||
// to ensure they fail.
|
||||
func TestBadURL(t *testing.T) {
|
||||
var urlList = []string{
|
||||
"http://google.com",
|
||||
"",
|
||||
"-",
|
||||
"foo",
|
||||
"otpauth:/foo/bar/baz",
|
||||
"://",
|
||||
"otpauth://hotp/?digits=",
|
||||
"otpauth://hotp/?secret=MFRGGZDF&digits=ABCD",
|
||||
"otpauth://hotp/?secret=MFRGGZDF&counter=ABCD",
|
||||
}
|
||||
|
||||
for i := range urlList {
|
||||
if _, _, err := FromURL(urlList[i]); err == nil {
|
||||
fmt.Println("hotp: URL should not have parsed successfully")
|
||||
fmt.Printf("\turl was: %s\n", urlList[i])
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user