Something went wrong. Try again.
An event companion and onboarding experience for the ATmosphere (alpha) atmo.quest
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475package auth
import ( "errors" "net/http"
"github.com/bluesky-social/indigo/atproto/auth/oauth" "github.com/bluesky-social/indigo/atproto/syntax")
// ErrNoSession is returned by ResumeSession when no auth cookie is present.// Other features should check for this with errors.Is and redirect to /signin.var ErrNoSession = errors.New("auth: no session")
// IdentityInfo holds the resolved viewer identity.// Use ResolveIdentity in handlers that support both ATProto and local users.type IdentityInfo struct { DID string // ATProto DID (did:plc:...) or local ID (local_xxx) IsLocal bool // true when the user is a local-only account IsAuth bool // true when the user is authenticated (either type)}
// ResolveIdentity checks the ATProto session cookie first, then the local// cookie. Returns the identity without writing any redirect headers.// Use this in handlers that can serve both ATProto and local users.func (h *Handlers) ResolveIdentity(r *http.Request) IdentityInfo { didStr, sid := h.Sessions.Get(r) if didStr != "" && sid != "" { return IdentityInfo{DID: didStr, IsLocal: false, IsAuth: true} } localID := h.Sessions.GetLocal(r) if localID != "" { return IdentityInfo{DID: localID, IsLocal: true, IsAuth: true} } return IdentityInfo{}}
// ResumeSession reads the session cookie and asks indigo to resume the OAuth// session for the resulting (DID, SessionID). Returns ErrNoSession when no// cookie is present so callers can distinguish "logged out" from "bad token".//// Use this from any authenticated handler. Example://// did, sess, err := h.Auth.ResumeSession(r)// if err != nil { http.Redirect(w, r, "/signin", http.StatusFound); return }func (h *Handlers) ResumeSession(r *http.Request) (syntax.DID, *oauth.ClientSession, error) { didStr, sid := h.Sessions.Get(r) if didStr == "" || sid == "" { return "", nil, ErrNoSession } did, err := syntax.ParseDID(didStr) if err != nil { return "", nil, err } sess, err := h.OAuth.ResumeSession(r.Context(), did, sid) if err != nil { return did, nil, err } return did, sess, nil}
// RequireSession is a small helper that redirects to /signin?next=<path> if// no session is present, otherwise returns the resumed indigo session.//// did, sess, ok := h.Auth.RequireSession(w, r)// if !ok { return }func (h *Handlers) RequireSession(w http.ResponseWriter, r *http.Request) (syntax.DID, *oauth.ClientSession, bool) { did, sess, err := h.ResumeSession(r) if err != nil { http.Redirect(w, r, "/signin?next="+r.URL.Path, http.StatusFound) return "", nil, false } return did, sess, true}