Browse code

pkg/authorization: make it goroutine-safe

It was racy on config reload

Signed-off-by: Alexander Morozov <lk4d4@docker.com>

Alexander Morozov authored on 2016/10/12 08:31:45
Showing 1 changed files
... ...
@@ -2,6 +2,7 @@ package authorization
2 2
 
3 3
 import (
4 4
 	"net/http"
5
+	"sync"
5 6
 
6 7
 	"github.com/Sirupsen/logrus"
7 8
 	"golang.org/x/net/context"
... ...
@@ -10,6 +11,7 @@ import (
10 10
 // Middleware uses a list of plugins to
11 11
 // handle authorization in the API requests.
12 12
 type Middleware struct {
13
+	mu      sync.Mutex
13 14
 	plugins []Plugin
14 15
 }
15 16
 
... ...
@@ -23,14 +25,19 @@ func NewMiddleware(names []string) *Middleware {
23 23
 
24 24
 // SetPlugins sets the plugin used for authorization
25 25
 func (m *Middleware) SetPlugins(names []string) {
26
+	m.mu.Lock()
26 27
 	m.plugins = newPlugins(names)
28
+	m.mu.Unlock()
27 29
 }
28 30
 
29 31
 // WrapHandler returns a new handler function wrapping the previous one in the request chain.
30 32
 func (m *Middleware) WrapHandler(handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error) func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
31 33
 	return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
32 34
 
33
-		if len(m.plugins) == 0 {
35
+		m.mu.Lock()
36
+		plugins := m.plugins
37
+		m.mu.Unlock()
38
+		if len(plugins) == 0 {
34 39
 			return handler(ctx, w, r, vars)
35 40
 		}
36 41
 
... ...
@@ -46,7 +53,7 @@ func (m *Middleware) WrapHandler(handler func(ctx context.Context, w http.Respon
46 46
 			userAuthNMethod = "TLS"
47 47
 		}
48 48
 
49
-		authCtx := NewCtx(m.plugins, user, userAuthNMethod, r.Method, r.RequestURI)
49
+		authCtx := NewCtx(plugins, user, userAuthNMethod, r.Method, r.RequestURI)
50 50
 
51 51
 		if err := authCtx.AuthZRequest(w, r); err != nil {
52 52
 			logrus.Errorf("AuthZRequest for %s %s returned error: %s", r.Method, r.RequestURI, err)