// UserFromRequest extracts user information from request and return the respective user in state, if valid // It requires the state to be locked func UserFromRequest(st *state.State, req *http.Request) (*auth.UserState, error) { // extract macaroons data from request header := req.Header.Get("Authorization") if header == "" { return nil, auth.ErrInvalidAuth } authorizationData := strings.SplitN(header, " ", 2) if len(authorizationData) != 2 || authorizationData[0] != "Macaroon" { return nil, fmt.Errorf("authorization header misses Macaroon prefix") } var macaroon string var discharges []string for _, field := range strings.Split(authorizationData[1], ",") { field := strings.TrimSpace(field) if strings.HasPrefix(field, `root="`) { macaroon = strings.TrimSuffix(field[6:], `"`) } if strings.HasPrefix(field, `discharge="`) { discharges = append(discharges, strings.TrimSuffix(field[11:], `"`)) } } if macaroon == "" || len(discharges) == 0 { return nil, fmt.Errorf("invalid authorization header") } user, err := auth.CheckMacaroon(st, macaroon, discharges) return user, err }
func (as *authSuite) TestCheckMacaroonNoAuthData(c *C) { as.state.Lock() user, err := auth.CheckMacaroon(as.state, "macaroon", []string{"discharge"}) as.state.Unlock() c.Check(err, Equals, auth.ErrInvalidAuth) c.Check(user, IsNil) }
func (as *authSuite) TestCheckMacaroonInvalidAuth(c *C) { as.state.Lock() user, err := auth.CheckMacaroon(as.state, "other-macaroon", []string{"discharge"}) as.state.Unlock() c.Check(err, Equals, auth.ErrInvalidAuth) c.Check(user, IsNil) as.state.Lock() _, err = auth.NewUser(as.state, "username", "macaroon", []string{"discharge"}) as.state.Unlock() c.Check(err, IsNil) as.state.Lock() user, err = auth.CheckMacaroon(as.state, "other-macaroon", []string{"discharge"}) as.state.Unlock() c.Check(err, Equals, auth.ErrInvalidAuth) c.Check(user, IsNil) }
func (as *authSuite) TestCheckMacaroonValidUser(c *C) { as.state.Lock() expectedUser, err := auth.NewUser(as.state, "username", "macaroon", []string{"discharge"}) as.state.Unlock() c.Check(err, IsNil) as.state.Lock() user, err := auth.CheckMacaroon(as.state, "macaroon", []string{"discharge"}) as.state.Unlock() c.Check(err, IsNil) c.Check(user, DeepEquals, expectedUser) }