~bigbes/sr-ht-dolt

ref: 0f6d50a68d88bf7c94e65770e6fc50750bc73519 sr-ht-dolt/authn/ctx.go -rw-r--r-- 2.9 KiB
0f6d50a6 — Eugene Blikh authn: gofmt the test files 5 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Package authn resolves the SourceHut caller for a dolt.sr.ht request across
// the three authentication flows the service accepts:
//
//   - the unified-login cookie (web UI), via OptionalCookieMiddleware;
//   - a meta.sr.ht personal access token (dolt clone/push --user + Basic auth),
//     via ResolveBasic;
//   - a dolt Ed25519 keypair (dolt login / Bearer EdDSA JWT), via ResolveDoltJWT.
//
// It reuses core-go's token/cookie primitives (auth.DecodeBearerToken,
// auth.LookupUser, auth.LookupTokenRevocation, crypto.DecryptWithoutExpiration)
// and dolt's creds.PubKeyToKIDStr for key-id derivation, and produces
// *auth.AuthContext values that AsCoreCaller maps onto the pure core.Caller
// domain type for the access-control matrix in package core.
//
// Production wiring: the cookie middleware and the resolvers read the meta.sr.ht
// user database and config from the request context, so the caller must install
// config.Middleware and database.Middleware upstream (see cmd/doltsrht). The
// meta-lookup and token-revocation calls are funnelled through the package-level
// MetaBackend so tests can stub them without a database or network.
package authn

import (
	"context"

	"sourcecraft.dev/bigbes/sr-ht-core/auth"

	"sourcecraft.dev/bigbes/sr-ht-dolt/core"
)

// AuthMethodDoltKey labels an AuthContext resolved from a dolt Ed25519 keypair
// JWT. core-go has no such method; we never call auth.AuthContext.Access (which
// would panic on an unknown method) — access is decided by core.Allowed — so a
// private label is safe and keeps dolt-key auth distinguishable from OAuth2.
const AuthMethodDoltKey = "DOLT_KEY"

type contextKey struct{ name string }

var callerCtxKey = &contextKey{"authn.caller"}

// WithCaller returns a copy of ctx carrying the resolved caller. A nil ac is
// stored as-is and reads back as anonymous via CallerFromContext.
func WithCaller(ctx context.Context, ac *auth.AuthContext) context.Context {
	return context.WithValue(ctx, callerCtxKey, ac)
}

// CallerFromContext returns the caller stored by WithCaller, or nil for an
// anonymous request. Unlike core-go's auth.ForContext it never panics on a
// missing value: an unauthenticated request is a normal, expected state for
// dolt.sr.ht (public browsing and public clones).
func CallerFromContext(ctx context.Context) *auth.AuthContext {
	ac, _ := ctx.Value(callerCtxKey).(*auth.AuthContext)
	return ac
}

// AsCoreCaller maps a resolved *auth.AuthContext onto the pure core.Caller
// domain type consumed by core.Allowed. A nil ac (anonymous) maps to a nil
// caller. Suspended is derived from the meta UserType, which independently
// gates every write operation.
func AsCoreCaller(ac *auth.AuthContext) *core.Caller {
	if ac == nil {
		return nil
	}
	return &core.Caller{
		UserID:    ac.UserID,
		Username:  ac.Username,
		UserType:  core.UserType(ac.UserType),
		Suspended: ac.UserType == auth.USER_TYPE_SUSPENDED,
	}
}