// CheckRequest checks that the given http request contains at least one // valid macaroon minted by the given service, using checker to check // any first party caveats. It returns an error with a // *bakery.VerificationError cause if the macaroon verification failed. // // The assert map holds any required attributes of "declared" attributes, // overriding any inferences made from the macaroons themselves. // It has a similar effect to adding a checkers.DeclaredCaveat // for each key and value, but the error message will be more // useful. // // It adds all the standard caveat checkers to the given checker. // // It returns any attributes declared in the successfully validated request. func CheckRequest(svc *bakery.Service, req *http.Request, assert map[string]string, checker checkers.Checker) (map[string]string, error) { mss := RequestMacaroons(req) if len(mss) == 0 { return nil, &bakery.VerificationError{ Reason: errgo.Newf("no macaroon cookies in request"), } } checker = checkers.New( checker, Checkers(req), checkers.TimeBefore, ) attrs, err := svc.CheckAny(mss, assert, checker) if err != nil { return nil, errgo.Mask(err, isVerificationError) } return attrs, nil }
// newDischargeRequiredError returns a discharge-required error holding // a newly minted macaroon referencing the original check error // checkErr. If authLocation is non-empty, the issued macaroon will // contain an "is-ok" third party caveat addressed to that location. // // If cookiePath is not nil, it will be called to find the cookie path // to put in the response. // // If req is non-nil, it will be used to pass to NewDischargeRequiredErrorForRequest, // otherwise the old protocol (triggered by NewDischargeRequiredError) will be used. func newDischargeRequiredError(svc *bakery.Service, authLocation string, cookiePath func() string, checkErr error, req *http.Request) error { var caveats []checkers.Caveat if authLocation != "" { caveats = []checkers.Caveat{{ Location: authLocation, Condition: "is-ok", }} } m, err := svc.NewMacaroon("", nil, caveats) if err != nil { panic(fmt.Errorf("cannot make new macaroon: %v", err)) } path := "" if cookiePath != nil { path = cookiePath() } if req != nil { return httpbakery.NewDischargeRequiredErrorForRequest(m, path, checkErr, req) } return httpbakery.NewDischargeRequiredError(m, path, checkErr) }
func addMacaroonTimeBeforeCaveat(svc *bakery.Service, m *macaroon.Macaroon, d time.Duration) error { return svc.AddCaveat(m, checkers.TimeBeforeCaveat(time.Now().Add(d))) }