Example #1
0
func (s *httpAuthChecker) writeError(w http.ResponseWriter, err error, req *http.Request) {
	err1, ok := errgo.Cause(err).(*auth.DischargeRequiredError)
	if !ok {
		logger.Infof("error when authorizing: %#v", err)
		// TODO permission denied error.
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	logger.Infof("got discharge-required error: %#v", err)
	if len(err1.Caveats) == 0 {
		panic("no caveats on discharge-required error!")
	}
	cookieName := "authz"
	expiry := 5 * time.Second
	if len(err1.Ops) == 1 && err1.Ops[0] == auth.LoginOp {
		cookieName = "authn"
		expiry = 24 * time.Hour
	}
	caveats := append(err1.Caveats, checkers.TimeBeforeCaveat(time.Now().Add(expiry)))
	m, err := s.store.NewMacaroon(err1.Ops, caveats)
	if err != nil {
		panic("cannot make new macaroon: " + err.Error())
	}
	// It's a discharge-required error. Write the expected httpbakery response.
	berr := httpbakery.NewDischargeRequiredErrorForRequest(m, "/", err, req)
	berr.(*httpbakery.Error).Info.CookieNameSuffix = cookieName
	// TODO we need some way of telling the client that the response shouldn't
	// be persisted.
	httprequest.ErrorMapper(httpbakery.ErrorToResponse).WriteError(w, berr)
}
Example #2
0
func (c *caveatSquasher) final() []string {
	if !c.expiry.IsZero() {
		c.conds = append(c.conds, checkers.TimeBeforeCaveat(c.expiry).Condition)
	}
	if len(c.conds) == 0 {
		return nil
	}
	// Make deterministic and eliminate duplicates.
	sort.Strings(c.conds)
	prev := c.conds[0]
	j := 1
	for _, cond := range c.conds[1:] {
		if cond != prev {
			c.conds[j] = cond
			prev = cond
			j++
		}
	}
	return c.conds
}