github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/pkg/authorization/authz_test.go (about) 1 package authorization 2 3 import ( 4 "encoding/json" 5 "io/ioutil" 6 "log" 7 "net" 8 "net/http" 9 "net/http/httptest" 10 "os" 11 "path" 12 "reflect" 13 "testing" 14 15 "github.com/docker/docker/pkg/plugins" 16 "github.com/docker/go-connections/tlsconfig" 17 "github.com/gorilla/mux" 18 ) 19 20 const pluginAddress = "authzplugin.sock" 21 22 func TestAuthZRequestPluginError(t *testing.T) { 23 server := authZPluginTestServer{t: t} 24 go server.start() 25 defer server.stop() 26 27 authZPlugin := createTestPlugin(t) 28 29 request := Request{ 30 User: "user", 31 RequestBody: []byte("sample body"), 32 RequestURI: "www.authz.com", 33 RequestMethod: "GET", 34 RequestHeaders: map[string]string{"header": "value"}, 35 } 36 server.replayResponse = Response{ 37 Err: "an error", 38 } 39 40 actualResponse, err := authZPlugin.AuthZRequest(&request) 41 if err != nil { 42 t.Fatalf("Failed to authorize request %v", err) 43 } 44 45 if !reflect.DeepEqual(server.replayResponse, *actualResponse) { 46 t.Fatalf("Response must be equal") 47 } 48 if !reflect.DeepEqual(request, server.recordedRequest) { 49 t.Fatalf("Requests must be equal") 50 } 51 } 52 53 func TestAuthZRequestPlugin(t *testing.T) { 54 server := authZPluginTestServer{t: t} 55 go server.start() 56 defer server.stop() 57 58 authZPlugin := createTestPlugin(t) 59 60 request := Request{ 61 User: "user", 62 RequestBody: []byte("sample body"), 63 RequestURI: "www.authz.com", 64 RequestMethod: "GET", 65 RequestHeaders: map[string]string{"header": "value"}, 66 } 67 server.replayResponse = Response{ 68 Allow: true, 69 Msg: "Sample message", 70 } 71 72 actualResponse, err := authZPlugin.AuthZRequest(&request) 73 if err != nil { 74 t.Fatalf("Failed to authorize request %v", err) 75 } 76 77 if !reflect.DeepEqual(server.replayResponse, *actualResponse) { 78 t.Fatalf("Response must be equal") 79 } 80 if !reflect.DeepEqual(request, server.recordedRequest) { 81 t.Fatalf("Requests must be equal") 82 } 83 } 84 85 func TestAuthZResponsePlugin(t *testing.T) { 86 server := authZPluginTestServer{t: t} 87 go server.start() 88 defer server.stop() 89 90 authZPlugin := createTestPlugin(t) 91 92 request := Request{ 93 User: "user", 94 RequestBody: []byte("sample body"), 95 } 96 server.replayResponse = Response{ 97 Allow: true, 98 Msg: "Sample message", 99 } 100 101 actualResponse, err := authZPlugin.AuthZResponse(&request) 102 if err != nil { 103 t.Fatalf("Failed to authorize request %v", err) 104 } 105 106 if !reflect.DeepEqual(server.replayResponse, *actualResponse) { 107 t.Fatalf("Response must be equal") 108 } 109 if !reflect.DeepEqual(request, server.recordedRequest) { 110 t.Fatalf("Requests must be equal") 111 } 112 } 113 114 func TestResponseModifier(t *testing.T) { 115 r := httptest.NewRecorder() 116 m := NewResponseModifier(r) 117 m.Header().Set("h1", "v1") 118 m.Write([]byte("body")) 119 m.WriteHeader(500) 120 121 m.Flush() 122 if r.Header().Get("h1") != "v1" { 123 t.Fatalf("Header value must exists %s", r.Header().Get("h1")) 124 } 125 if !reflect.DeepEqual(r.Body.Bytes(), []byte("body")) { 126 t.Fatalf("Body value must exists %s", r.Body.Bytes()) 127 } 128 if r.Code != 500 { 129 t.Fatalf("Status code must be correct %d", r.Code) 130 } 131 } 132 133 func TestResponseModifierOverride(t *testing.T) { 134 r := httptest.NewRecorder() 135 m := NewResponseModifier(r) 136 m.Header().Set("h1", "v1") 137 m.Write([]byte("body")) 138 m.WriteHeader(500) 139 140 overrideHeader := make(http.Header) 141 overrideHeader.Add("h1", "v2") 142 overrideHeaderBytes, err := json.Marshal(overrideHeader) 143 if err != nil { 144 t.Fatalf("override header failed %v", err) 145 } 146 147 m.OverrideHeader(overrideHeaderBytes) 148 m.OverrideBody([]byte("override body")) 149 m.OverrideStatusCode(404) 150 m.Flush() 151 if r.Header().Get("h1") != "v2" { 152 t.Fatalf("Header value must exists %s", r.Header().Get("h1")) 153 } 154 if !reflect.DeepEqual(r.Body.Bytes(), []byte("override body")) { 155 t.Fatalf("Body value must exists %s", r.Body.Bytes()) 156 } 157 if r.Code != 404 { 158 t.Fatalf("Status code must be correct %d", r.Code) 159 } 160 } 161 162 // createTestPlugin creates a new sample authorization plugin 163 func createTestPlugin(t *testing.T) *authorizationPlugin { 164 plugin := &plugins.Plugin{Name: "authz"} 165 pwd, err := os.Getwd() 166 if err != nil { 167 log.Fatal(err) 168 } 169 170 plugin.Client, err = plugins.NewClient("unix:///"+path.Join(pwd, pluginAddress), tlsconfig.Options{InsecureSkipVerify: true}) 171 if err != nil { 172 t.Fatalf("Failed to create client %v", err) 173 } 174 175 return &authorizationPlugin{name: "plugin", plugin: plugin} 176 } 177 178 // AuthZPluginTestServer is a simple server that implements the authZ plugin interface 179 type authZPluginTestServer struct { 180 listener net.Listener 181 t *testing.T 182 // request stores the request sent from the daemon to the plugin 183 recordedRequest Request 184 // response stores the response sent from the plugin to the daemon 185 replayResponse Response 186 } 187 188 // start starts the test server that implements the plugin 189 func (t *authZPluginTestServer) start() { 190 r := mux.NewRouter() 191 os.Remove(pluginAddress) 192 l, err := net.ListenUnix("unix", &net.UnixAddr{Name: pluginAddress, Net: "unix"}) 193 if err != nil { 194 t.t.Fatalf("Failed to listen %v", err) 195 } 196 t.listener = l 197 198 r.HandleFunc("/Plugin.Activate", t.activate) 199 r.HandleFunc("/"+AuthZApiRequest, t.auth) 200 r.HandleFunc("/"+AuthZApiResponse, t.auth) 201 t.listener, err = net.Listen("tcp", pluginAddress) 202 server := http.Server{Handler: r, Addr: pluginAddress} 203 server.Serve(l) 204 } 205 206 // stop stops the test server that implements the plugin 207 func (t *authZPluginTestServer) stop() { 208 os.Remove(pluginAddress) 209 if t.listener != nil { 210 t.listener.Close() 211 } 212 } 213 214 // auth is a used to record/replay the authentication api messages 215 func (t *authZPluginTestServer) auth(w http.ResponseWriter, r *http.Request) { 216 t.recordedRequest = Request{} 217 defer r.Body.Close() 218 body, err := ioutil.ReadAll(r.Body) 219 json.Unmarshal(body, &t.recordedRequest) 220 b, err := json.Marshal(t.replayResponse) 221 if err != nil { 222 log.Fatal(err) 223 } 224 w.Write(b) 225 } 226 227 func (t *authZPluginTestServer) activate(w http.ResponseWriter, r *http.Request) { 228 b, err := json.Marshal(plugins.Manifest{Implements: []string{AuthZApiImplements}}) 229 if err != nil { 230 log.Fatal(err) 231 } 232 w.Write(b) 233 }