Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
2.2 kB · 79 lines
Go
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980package accessctl
import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "net/http" "strconv" "strings" "time")
// ViewerCookieName carries a signed statement that the bearer is did,// so routes that browsers hit without an Authorization header (playback,// thumbnails, chat and livestream websockets) can apply the viewer gate.// It is minted on every authenticated XRPC response from an allowed viewer// and never on its own is proof of anything beyond "this DID was allowed// when the cookie was minted"; the gate re-checks the DID against the live// snapshot on every request.const ViewerCookieName = "sp_access"
const viewerCookieTTL = 7 * 24 * time.Hour
func (c *Controller) sign(did string, exp int64) []byte { mac := hmac.New(sha256.New, c.cookieKey) mac.Write([]byte(did)) mac.Write([]byte{0}) mac.Write([]byte(strconv.FormatInt(exp, 10))) return mac.Sum(nil)}
// ViewerCookie implements access.Manager.func (c *Controller) ViewerCookie(did string) *http.Cookie { exp := time.Now().Add(viewerCookieTTL).Unix() enc := base64.RawURLEncoding value := enc.EncodeToString([]byte(did)) + "." + strconv.FormatInt(exp, 10) + "." + enc.EncodeToString(c.sign(did, exp)) return &http.Cookie{ Name: ViewerCookieName, Value: value, Path: "/", MaxAge: int(viewerCookieTTL / time.Second), HttpOnly: true, Secure: c.cli.HasHTTPS() || c.cli.BehindHTTPSProxy, SameSite: http.SameSiteLaxMode, }}
// ViewerFromCookie implements access.Manager.func (c *Controller) ViewerFromCookie(r *http.Request) (string, bool) { ck, err := r.Cookie(ViewerCookieName) if err != nil { return "", false } return c.verify(ck.Value, time.Now())}
func (c *Controller) verify(value string, now time.Time) (string, bool) { parts := strings.Split(value, ".") if len(parts) != 3 { return "", false } enc := base64.RawURLEncoding didBs, err := enc.DecodeString(parts[0]) if err != nil { return "", false } exp, err := strconv.ParseInt(parts[1], 10, 64) if err != nil || now.Unix() > exp { return "", false } sig, err := enc.DecodeString(parts[2]) if err != nil { return "", false } if !hmac.Equal(sig, c.sign(string(didBs), exp)) { return "", false } return string(didBs), true}