...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package kivikd
16
17 import (
18 "net/http"
19
20 "github.com/go-kivik/kivik/v4/x/kivikd/auth"
21 "github.com/go-kivik/kivik/v4/x/kivikd/authdb"
22 )
23
24 type doneWriter struct {
25 http.ResponseWriter
26 done bool
27 }
28
29 func (w *doneWriter) WriteHeader(status int) {
30 w.done = true
31 w.ResponseWriter.WriteHeader(status)
32 }
33
34 func (w *doneWriter) Write(b []byte) (int, error) {
35 w.done = true
36 return w.ResponseWriter.Write(b)
37 }
38
39 func authHandler(next http.Handler) http.Handler {
40 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
41 dw := &doneWriter{ResponseWriter: w}
42 s := GetService(r)
43 session, err := s.validate(dw, r)
44 if err != nil {
45 reportError(w, err)
46 return
47 }
48 sessionPtr := mustGetSessionPtr(r.Context())
49 *sessionPtr = session
50 if dw.done {
51
52 return
53 }
54 next.ServeHTTP(w, r)
55 })
56 }
57
58
59
60 func (s *Service) validate(w http.ResponseWriter, r *http.Request) (*auth.Session, error) {
61 if s.authHandlers == nil {
62
63 return s.createSession("", &authdb.UserContext{Roles: []string{"_admin"}}), nil
64 }
65 for methodName, handler := range s.authHandlers {
66 uCtx, err := handler.Authenticate(w, r)
67 if err != nil {
68 return nil, err
69 }
70 if uCtx != nil {
71 return s.createSession(methodName, uCtx), nil
72 }
73 }
74
75 return s.createSession("", nil), nil
76 }
77
78 func (s *Service) createSession(method string, user *authdb.UserContext) *auth.Session {
79 return &auth.Session{
80 AuthMethod: method,
81 AuthDB: s.Conf().GetString("couch_httpd_auth.authentication_db"),
82 Handlers: s.authHandlerNames,
83 User: user,
84 }
85 }
86
View as plain text