Newer
Older
var ErrAuthFailed = errors.New("authentication failed")
// User is an application user.
type User struct {
Name string
IsAdmin bool
CanWrite bool // Set for non-anonymous users
readOnly := " (ro)"
if u.CanWrite {
readOnly = ""
}
return "{" + u.Name + readOnly + "}"
// Valid checks whether the given token represents a valid user session. If that is the case, the user
// is returned. Otherwise, an error is returned.
Valid(ctx context.Context, token string) (*User, error)
}
// Require wraps hdlr so that it requires authentication to use. Requests handled by hdlr will have the user
// name attached to their context. Use the User function to retrieve it.
//
// If authentication fails, for example because the users' session is no longer valid or doesn't exist, the
// request will be handled by the authFailed handler. It will receive the original request and response writer.
// This is triggered by provider returning an error wrapping ErrAuthFailed from its `Valid` method.
func Require(next http.Handler, authFailed http.Handler, provider Provider) http.Handler {
anonAuth := func(w http.ResponseWriter, r *http.Request) {
// No session: allow GET and friends, deny POST by requesting authentication
if r.Method == "POST" || strings.HasPrefix(r.URL.Path, "/user/") {
level.Error(log.Get(r)).
Log("msg", "denying POST access for unknown user")
level.Info(log.Get(r)).
Log("msg", "no session, using anon auth")
user := &User{
Name: "anon",
}
ctx := context.WithValue(r.Context(), key, *user)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err != nil || user == nil {
if user == nil && err == nil {
// The auth provider did something weird: no error, but no user either
err = errors.New("no user")
}
// Some error that isn't because the session is expired or doesn't exist (DB?)
Log("error", err, "msg", "can't authenticate user")
http.Error(w, err.Error(), http.StatusInternalServerError)
Log("user", *user, "msg", "user authenticated")
ctx := context.WithValue(r.Context(), key, *user)
// Get returns the user from r's context. If there is no user in r's context, returns an empty user.
func Get(r *http.Request) User {
val := r.Context().Value(contextKey("user"))
if val == nil {