package main import ( "encoding/hex" "testing" "github.com/stretchr/testify/require" "gopkg.in/macaroon.v2" ) var ( dummyMacStr = "0201047465737402067788991234560000062052d26ed139ea5af8" + "3e675500c4ccb2471f62191b745bab820f129e5588a255d2" dummyMac, _ = hex.DecodeString(dummyMacStr) encryptedEntry = &macaroonEntry{ Name: "encryptedMac", Data: "snacl:exX8xbUOb6Gih88ybL2jZGo+DBDPU2tYKkvo0eVVmbDGDoFP" + "zlv5xvqNK5eml0LKLcB8LdZRw43qXK1W2OLs/gBAAAAAAAAACAAA" + "AAAAAAABAAAAAAAAAA==:C8TN/aDOvSLiBCX+IdoPTx+UUWhVdGj" + "NQvbcaWp+KXQWqPfpRZpjJQ6B2PDx5mJxImcezJGPx8ShAqMdxWe" + "l2precU+1cOjk7HQFkYuu943eJ00s6JerAY+ssg==", } plaintextEntry = &macaroonEntry{ Name: "plaintextMac", Data: dummyMacStr, } testPassword = []byte("S3curePazzw0rd") pwCallback = func(string) ([]byte, error) { return testPassword, nil } noPwCallback = func(string) ([]byte, error) { return nil, nil } ) // TestMacaroonJarEncrypted tests that a macaroon can be stored and retrieved // safely by encrypting/decrypting it with a password. func TestMacaroonJarEncrypted(t *testing.T) { // Create a new macaroon entry from the dummy macaroon and encrypt it // with the test password. newEntry := &macaroonEntry{ Name: "encryptedMac", } err := newEntry.storeMacaroon(toMacaroon(t, dummyMac), testPassword) require.NoError(t, err) // Now decrypt it again and make sure we get the same content back. mac, err := newEntry.loadMacaroon(pwCallback) require.NoError(t, err) macBytes, err := mac.MarshalBinary() require.NoError(t, err) require.Equal(t, dummyMac, macBytes) // The encrypted data of the entry we just created shouldn't be the // same as our test entry because of the salt snacl uses. require.NotEqual(t, encryptedEntry.Data, newEntry.Data) // Decrypt the hard coded test entry and make sure the decrypted content // matches our created entry. mac, err = encryptedEntry.loadMacaroon(pwCallback) require.NoError(t, err) macBytes, err = mac.MarshalBinary() require.NoError(t, err) require.Equal(t, dummyMac, macBytes) } // TestMacaroonJarPlaintext tests that a macaroon can be stored and retrieved // as plaintext as well. func TestMacaroonJarPlaintext(t *testing.T) { // Create a new macaroon entry from the dummy macaroon and encrypt it // with the test password. newEntry := &macaroonEntry{ Name: "plaintextMac", } err := newEntry.storeMacaroon(toMacaroon(t, dummyMac), nil) require.NoError(t, err) // Now decrypt it again and make sure we get the same content back. mac, err := newEntry.loadMacaroon(noPwCallback) require.NoError(t, err) macBytes, err := mac.MarshalBinary() require.NoError(t, err) require.Equal(t, dummyMac, macBytes) require.Equal(t, plaintextEntry.Data, newEntry.Data) // Load the hard coded plaintext test entry and make sure the loaded // content matches our created entry. mac, err = plaintextEntry.loadMacaroon(noPwCallback) require.NoError(t, err) macBytes, err = mac.MarshalBinary() require.NoError(t, err) require.Equal(t, dummyMac, macBytes) } func toMacaroon(t *testing.T, macData []byte) *macaroon.Macaroon { mac := &macaroon.Macaroon{} err := mac.UnmarshalBinary(macData) require.NoError(t, err) return mac }