Skip to content

Commit

Permalink
Merge pull request #20 from rogpeppe/019-better-example
Browse files Browse the repository at this point in the history
bakery/example/idservice: new package
  • Loading branch information
rogpeppe committed Oct 20, 2014
2 parents d6445a2 + 1891800 commit 155185a
Show file tree
Hide file tree
Showing 17 changed files with 1,341 additions and 113 deletions.
34 changes: 34 additions & 0 deletions bakery/discharge.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package bakery
import (
"fmt"

"github.com/juju/errgo"

"github.com/rogpeppe/macaroon"
)

Expand Down Expand Up @@ -46,3 +48,35 @@ func (d *Discharger) Discharge(id string) (*macaroon.Macaroon, error) {
}
return d.Factory.NewMacaroon(id, rootKey, caveats)
}

// DischargeAll gathers discharge macaroons for all the third party caveats
// in m (and any subsequent caveats required by those) using getDischarge to
// acquire each discharge macaroon.
func DischargeAll(
m *macaroon.Macaroon,
getDischarge func(firstPartyLocation string, cav macaroon.Caveat) (*macaroon.Macaroon, error),
) ([]*macaroon.Macaroon, error) {
var discharges []*macaroon.Macaroon
var need []macaroon.Caveat
addCaveats := func(m *macaroon.Macaroon) {
for _, cav := range m.Caveats() {
if cav.Location == "" {
continue
}
need = append(need, cav)
}
}
addCaveats(m)
firstPartyLocation := m.Location()
for len(need) > 0 {
cav := need[0]
need = need[1:]
dm, err := getDischarge(firstPartyLocation, cav)
if err != nil {
return nil, errgo.NoteMask(err, fmt.Sprintf("cannot get discharge from %q", cav.Location), errgo.Any)
}
discharges = append(discharges, dm)
addCaveats(dm)
}
return discharges, nil
}
72 changes: 72 additions & 0 deletions bakery/discharge_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package bakery_test

import (
"fmt"

gc "gopkg.in/check.v1"

"github.com/rogpeppe/macaroon"
"github.com/rogpeppe/macaroon/bakery"
)

type DischargeSuite struct{}

var _ = gc.Suite(&DischargeSuite{})

func alwaysOK(string) error {
return nil
}

func (*DischargeSuite) TestDischargeAllNoDischarges(c *gc.C) {
rootKey := []byte("root key")
m, err := macaroon.New(rootKey, "id0", "loc0")
c.Assert(err, gc.IsNil)
getDischarge := func(string, macaroon.Caveat) (*macaroon.Macaroon, error) {
c.Errorf("getDischarge called unexpectedly")
return nil, fmt.Errorf("nothing")
}
ms, err := bakery.DischargeAll(m, getDischarge)
c.Assert(err, gc.IsNil)
c.Assert(ms, gc.HasLen, 0)

err = m.Verify(rootKey, alwaysOK, ms)
c.Assert(err, gc.IsNil)
}

func (*DischargeSuite) TestDischargeAllManyDischarges(c *gc.C) {
rootKey := []byte("root key")
m0, err := macaroon.New(rootKey, "id0", "location0")
c.Assert(err, gc.IsNil)
totalRequired := 40
id := 1
addCaveats := func(m *macaroon.Macaroon) {
for i := 0; i < 2; i++ {
if totalRequired == 0 {
break
}
cid := fmt.Sprint("id", id)
err := m.AddThirdPartyCaveat([]byte("root key "+cid), cid, "somewhere")
c.Assert(err, gc.IsNil)
id++
totalRequired--
}
}
addCaveats(m0)
getDischarge := func(loc string, cav macaroon.Caveat) (*macaroon.Macaroon, error) {
c.Assert(loc, gc.Equals, "location0")
m, err := macaroon.New([]byte("root key "+cav.Id), cav.Id, "")
c.Assert(err, gc.IsNil)
addCaveats(m)
return m, nil
}
ms, err := bakery.DischargeAll(m0, getDischarge)
c.Assert(err, gc.IsNil)
c.Assert(ms, gc.HasLen, 40)

for _, m := range ms {
m.Bind(m0.Signature())
}

err = m0.Verify(rootKey, alwaysOK, ms)
c.Assert(err, gc.IsNil)
}
Loading

0 comments on commit 155185a

Please sign in to comment.