Merge branch '14287-controller-structure'
[arvados.git] / sdk / go / auth / handlers.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package auth
6
7 import (
8         "context"
9         "net/http"
10 )
11
12 type contextKeyCredentials struct{}
13
14 // LoadToken wraps the next handler, adding credentials to the request
15 // context so subsequent handlers can access them efficiently via
16 // CredentialsFromRequest.
17 func LoadToken(next http.Handler) http.Handler {
18         return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
19                 if _, ok := r.Context().Value(contextKeyCredentials{}).(*Credentials); !ok {
20                         r = r.WithContext(context.WithValue(r.Context(), contextKeyCredentials{}, CredentialsFromRequest(r)))
21                 }
22                 next.ServeHTTP(w, r)
23         })
24 }
25
26 // RequireLiteralToken wraps the next handler, rejecting any request
27 // that doesn't supply the given token. If the given token is empty,
28 // RequireLiteralToken returns next (i.e., no auth checks are
29 // performed).
30 func RequireLiteralToken(token string, next http.Handler) http.Handler {
31         if token == "" {
32                 return next
33         }
34         return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
35                 c := CredentialsFromRequest(r)
36                 if len(c.Tokens) == 0 {
37                         http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
38                         return
39                 }
40                 for _, t := range c.Tokens {
41                         if t == token {
42                                 next.ServeHTTP(w, r)
43                                 return
44                         }
45                 }
46                 http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
47         })
48 }