mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-03-26 03:24:28 -05:00
* Add Go macaroon library Signed-off-by: Anant Prakash <anantprakashjsr@gmail.com> * Add macaroon generation and serialization, for login token. Signed-off-by: Anant Prakash <anantprakashjsr@gmail.com> * Remove copyright, trim empty lines * Make Serialize functions private * Fix typos
204 lines
6 KiB
Go
204 lines
6 KiB
Go
package macaroon_test
|
|
|
|
import (
|
|
jc "github.com/juju/testing/checkers"
|
|
gc "gopkg.in/check.v1"
|
|
|
|
"gopkg.in/macaroon.v2"
|
|
)
|
|
|
|
type marshalSuite struct{}
|
|
|
|
var _ = gc.Suite(&marshalSuite{})
|
|
|
|
func (s *marshalSuite) TestMarshalUnmarshalMacaroonV1(c *gc.C) {
|
|
s.testMarshalUnmarshalWithVersion(c, macaroon.V1)
|
|
}
|
|
|
|
func (s *marshalSuite) TestMarshalUnmarshalMacaroonV2(c *gc.C) {
|
|
s.testMarshalUnmarshalWithVersion(c, macaroon.V2)
|
|
}
|
|
|
|
func (*marshalSuite) testMarshalUnmarshalWithVersion(c *gc.C, vers macaroon.Version) {
|
|
rootKey := []byte("secret")
|
|
m := MustNew(rootKey, []byte("some id"), "a location", vers)
|
|
|
|
// Adding the third party caveat before the first party caveat
|
|
// tests a former bug where the caveat wasn't zeroed
|
|
// before moving to the next caveat.
|
|
err := m.AddThirdPartyCaveat([]byte("shared root key"), []byte("3rd party caveat"), "remote.com")
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
err = m.AddFirstPartyCaveat([]byte("a caveat"))
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
b, err := m.MarshalBinary()
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
var um macaroon.Macaroon
|
|
err = um.UnmarshalBinary(b)
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
c.Assert(um.Location(), gc.Equals, m.Location())
|
|
c.Assert(string(um.Id()), gc.Equals, string(m.Id()))
|
|
c.Assert(um.Signature(), jc.DeepEquals, m.Signature())
|
|
c.Assert(um.Caveats(), jc.DeepEquals, m.Caveats())
|
|
c.Assert(um.Version(), gc.Equals, vers)
|
|
um.SetVersion(m.Version())
|
|
c.Assert(m, jc.DeepEquals, &um)
|
|
}
|
|
|
|
func (s *marshalSuite) TestMarshalBinaryRoundTrip(c *gc.C) {
|
|
// This data holds the V2 binary encoding of
|
|
data := []byte(
|
|
"\x02" +
|
|
"\x01\x0ehttp://mybank/" +
|
|
"\x02\x1cwe used our other secret key" +
|
|
"\x00" +
|
|
"\x02\x14account = 3735928559" +
|
|
"\x00" +
|
|
"\x01\x13http://auth.mybank/" +
|
|
"\x02'this was how we remind auth of key/pred" +
|
|
"\x04\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\x6e\xc5\x02\xe0\x58\x86\xd1\xf0\x27\x9f\x05\x5f\xa5\x25\x54\xd1\x6d\x16\xc1\xb1\x40\x74\xbb\xb8\x3f\xf0\xfd\xd7\x9d\xc2\xfe\x09\x8f\x0e\xd4\xa2\xb0\x91\x13\x0e\x6b\x5d\xb4\x6a\x20\xa8\x6b" +
|
|
"\x00" +
|
|
"\x00" +
|
|
"\x06\x20\xd2\x7d\xb2\xfd\x1f\x22\x76\x0e\x4c\x3d\xae\x81\x37\xe2\xd8\xfc\x1d\xf6\xc0\x74\x1c\x18\xae\xd4\xb9\x72\x56\xbf\x78\xd1\xf5\x5c",
|
|
)
|
|
var m macaroon.Macaroon
|
|
err := m.UnmarshalBinary(data)
|
|
c.Assert(err, gc.Equals, nil)
|
|
assertLibMacaroonsMacaroon(c, &m)
|
|
c.Assert(m.Version(), gc.Equals, macaroon.V2)
|
|
|
|
data1, err := m.MarshalBinary()
|
|
c.Assert(err, gc.Equals, nil)
|
|
c.Assert(data1, jc.DeepEquals, data)
|
|
}
|
|
|
|
func (s *marshalSuite) TestMarshalUnmarshalSliceV1(c *gc.C) {
|
|
s.testMarshalUnmarshalSliceWithVersion(c, macaroon.V1)
|
|
}
|
|
|
|
func (s *marshalSuite) TestMarshalUnmarshalSliceV2(c *gc.C) {
|
|
s.testMarshalUnmarshalSliceWithVersion(c, macaroon.V2)
|
|
}
|
|
|
|
func (*marshalSuite) testMarshalUnmarshalSliceWithVersion(c *gc.C, vers macaroon.Version) {
|
|
rootKey := []byte("secret")
|
|
m1 := MustNew(rootKey, []byte("some id"), "a location", vers)
|
|
m2 := MustNew(rootKey, []byte("some other id"), "another location", vers)
|
|
|
|
err := m1.AddFirstPartyCaveat([]byte("a caveat"))
|
|
c.Assert(err, gc.IsNil)
|
|
err = m2.AddFirstPartyCaveat([]byte("another caveat"))
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
macaroons := macaroon.Slice{m1, m2}
|
|
|
|
b, err := macaroons.MarshalBinary()
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
var unmarshaledMacs macaroon.Slice
|
|
err = unmarshaledMacs.UnmarshalBinary(b)
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
c.Assert(unmarshaledMacs, gc.HasLen, len(macaroons))
|
|
for i, m := range macaroons {
|
|
um := unmarshaledMacs[i]
|
|
c.Assert(um.Location(), gc.Equals, m.Location())
|
|
c.Assert(string(um.Id()), gc.Equals, string(m.Id()))
|
|
c.Assert(um.Signature(), jc.DeepEquals, m.Signature())
|
|
c.Assert(um.Caveats(), jc.DeepEquals, m.Caveats())
|
|
c.Assert(um.Version(), gc.Equals, vers)
|
|
um.SetVersion(m.Version())
|
|
}
|
|
c.Assert(macaroons, jc.DeepEquals, unmarshaledMacs)
|
|
|
|
// Check that appending a caveat to the first does not
|
|
// affect the second.
|
|
for i := 0; i < 10; i++ {
|
|
err = unmarshaledMacs[0].AddFirstPartyCaveat([]byte("caveat"))
|
|
c.Assert(err, gc.IsNil)
|
|
}
|
|
unmarshaledMacs[1].SetVersion(macaroons[1].Version())
|
|
c.Assert(unmarshaledMacs[1], jc.DeepEquals, macaroons[1])
|
|
c.Assert(err, gc.IsNil)
|
|
}
|
|
|
|
func (s *marshalSuite) TestSliceRoundTripV1(c *gc.C) {
|
|
s.testSliceRoundTripWithVersion(c, macaroon.V1)
|
|
}
|
|
|
|
func (s *marshalSuite) TestSliceRoundTripV2(c *gc.C) {
|
|
s.testSliceRoundTripWithVersion(c, macaroon.V2)
|
|
}
|
|
|
|
func (*marshalSuite) testSliceRoundTripWithVersion(c *gc.C, vers macaroon.Version) {
|
|
rootKey := []byte("secret")
|
|
m1 := MustNew(rootKey, []byte("some id"), "a location", vers)
|
|
m2 := MustNew(rootKey, []byte("some other id"), "another location", vers)
|
|
|
|
err := m1.AddFirstPartyCaveat([]byte("a caveat"))
|
|
c.Assert(err, gc.IsNil)
|
|
err = m2.AddFirstPartyCaveat([]byte("another caveat"))
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
macaroons := macaroon.Slice{m1, m2}
|
|
|
|
b, err := macaroons.MarshalBinary()
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
var unmarshaledMacs macaroon.Slice
|
|
err = unmarshaledMacs.UnmarshalBinary(b)
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
marshaledMacs, err := unmarshaledMacs.MarshalBinary()
|
|
c.Assert(err, gc.IsNil)
|
|
|
|
c.Assert(b, jc.DeepEquals, marshaledMacs)
|
|
}
|
|
|
|
var base64DecodeTests = []struct {
|
|
about string
|
|
input string
|
|
expect string
|
|
expectError string
|
|
}{{
|
|
about: "empty string",
|
|
input: "",
|
|
expect: "",
|
|
}, {
|
|
about: "standard encoding, padded",
|
|
input: "Z29+IQ==",
|
|
expect: "go~!",
|
|
}, {
|
|
about: "URL encoding, padded",
|
|
input: "Z29-IQ==",
|
|
expect: "go~!",
|
|
}, {
|
|
about: "standard encoding, not padded",
|
|
input: "Z29+IQ",
|
|
expect: "go~!",
|
|
}, {
|
|
about: "URL encoding, not padded",
|
|
input: "Z29-IQ",
|
|
expect: "go~!",
|
|
}, {
|
|
about: "standard encoding, too much padding",
|
|
input: "Z29+IQ===",
|
|
expectError: `illegal base64 data at input byte 8`,
|
|
}}
|
|
|
|
func (*marshalSuite) TestBase64Decode(c *gc.C) {
|
|
for i, test := range base64DecodeTests {
|
|
c.Logf("test %d: %s", i, test.about)
|
|
out, err := macaroon.Base64Decode([]byte(test.input))
|
|
if test.expectError != "" {
|
|
c.Assert(err, gc.ErrorMatches, test.expectError)
|
|
} else {
|
|
c.Assert(err, gc.Equals, nil)
|
|
c.Assert(string(out), gc.Equals, test.expect)
|
|
}
|
|
}
|
|
}
|