1package auth
2
3import (
4 "net/http"
5
6 "github.com/git-bug/git-bug/entity"
7)
8
9// Middleware injects a fixed identity into every request context.
10// Used in local single-user mode where auth is implicit (identity comes from
11// git config at server startup rather than per-request login).
12func Middleware(fixedUserId entity.Id) func(http.Handler) http.Handler {
13 return func(next http.Handler) http.Handler {
14 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
15 ctx := CtxWithUser(r.Context(), fixedUserId)
16 next.ServeHTTP(w, r.WithContext(ctx))
17 })
18 }
19}
20
21// RequireAuth is middleware that rejects unauthenticated requests with 401.
22// Use this on subrouters that must never be accessible without a valid session
23// (e.g. the REST API in oauth mode when the server is publicly deployed).
24func RequireAuth(next http.Handler) http.Handler {
25 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
26 if _, ok := r.Context().Value(identityCtxKey).(entity.Id); !ok {
27 http.Error(w, "authentication required", http.StatusUnauthorized)
28 return
29 }
30 next.ServeHTTP(w, r)
31 })
32}
33
34// SessionMiddleware reads the session cookie on every request and, when a
35// valid session exists, injects the corresponding identity ID into the context.
36//
37// Requests without a valid session are served as unauthenticated rather than
38// rejected: GraphQL's userIdentity field returns null and mutations fail with
39// ErrNotAuthenticated. This allows the frontend to gracefully degrade rather
40// than receiving hard HTTP errors for every unauthenticated page load.
41func SessionMiddleware(store *SessionStore) func(http.Handler) http.Handler {
42 return func(next http.Handler) http.Handler {
43 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
44 if cookie, err := r.Cookie(SessionCookie); err == nil {
45 if id, ok := store.Get(cookie.Value); ok {
46 r = r.WithContext(CtxWithUser(r.Context(), id))
47 }
48 }
49 next.ServeHTTP(w, r)
50 })
51 }
52}