github.com/rita33cool1/iot-system-gateway@v0.0.0-20200911033302-e65bde238cc5/docker-engine/integration/plugin/authz/main_test.go (about)

     1  // +build !windows
     2  
     3  package authz // import "github.com/docker/docker/integration/plugin/authz"
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"net/http/httptest"
    11  	"os"
    12  	"strings"
    13  	"testing"
    14  
    15  	"github.com/docker/docker/internal/test/daemon"
    16  	"github.com/docker/docker/internal/test/environment"
    17  	"github.com/docker/docker/pkg/authorization"
    18  	"github.com/docker/docker/pkg/plugins"
    19  	"github.com/gotestyourself/gotestyourself/skip"
    20  )
    21  
    22  var (
    23  	testEnv *environment.Execution
    24  	d       *daemon.Daemon
    25  	server  *httptest.Server
    26  )
    27  
    28  func TestMain(m *testing.M) {
    29  	var err error
    30  	testEnv, err = environment.New()
    31  	if err != nil {
    32  		fmt.Println(err)
    33  		os.Exit(1)
    34  	}
    35  	err = environment.EnsureFrozenImagesLinux(testEnv)
    36  	if err != nil {
    37  		fmt.Println(err)
    38  		os.Exit(1)
    39  	}
    40  
    41  	testEnv.Print()
    42  	setupSuite()
    43  	exitCode := m.Run()
    44  	teardownSuite()
    45  
    46  	os.Exit(exitCode)
    47  }
    48  
    49  func setupTest(t *testing.T) func() {
    50  	skip.IfCondition(t, testEnv.IsRemoteDaemon(), "cannot run daemon when remote daemon")
    51  	environment.ProtectAll(t, testEnv)
    52  
    53  	d = daemon.New(t, daemon.WithExperimental)
    54  
    55  	return func() {
    56  		if d != nil {
    57  			d.Stop(t)
    58  		}
    59  		testEnv.Clean(t)
    60  	}
    61  }
    62  
    63  func setupSuite() {
    64  	mux := http.NewServeMux()
    65  	server = httptest.NewServer(mux)
    66  
    67  	mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
    68  		b, err := json.Marshal(plugins.Manifest{Implements: []string{authorization.AuthZApiImplements}})
    69  		if err != nil {
    70  			panic("could not marshal json for /Plugin.Activate: " + err.Error())
    71  		}
    72  		w.Write(b)
    73  	})
    74  
    75  	mux.HandleFunc("/AuthZPlugin.AuthZReq", func(w http.ResponseWriter, r *http.Request) {
    76  		defer r.Body.Close()
    77  		body, err := ioutil.ReadAll(r.Body)
    78  		if err != nil {
    79  			panic("could not read body for /AuthZPlugin.AuthZReq: " + err.Error())
    80  		}
    81  		authReq := authorization.Request{}
    82  		err = json.Unmarshal(body, &authReq)
    83  		if err != nil {
    84  			panic("could not unmarshal json for /AuthZPlugin.AuthZReq: " + err.Error())
    85  		}
    86  
    87  		assertBody(authReq.RequestURI, authReq.RequestHeaders, authReq.RequestBody)
    88  		assertAuthHeaders(authReq.RequestHeaders)
    89  
    90  		// Count only server version api
    91  		if strings.HasSuffix(authReq.RequestURI, serverVersionAPI) {
    92  			ctrl.versionReqCount++
    93  		}
    94  
    95  		ctrl.requestsURIs = append(ctrl.requestsURIs, authReq.RequestURI)
    96  
    97  		reqRes := ctrl.reqRes
    98  		if isAllowed(authReq.RequestURI) {
    99  			reqRes = authorization.Response{Allow: true}
   100  		}
   101  		if reqRes.Err != "" {
   102  			w.WriteHeader(http.StatusInternalServerError)
   103  		}
   104  		b, err := json.Marshal(reqRes)
   105  		if err != nil {
   106  			panic("could not marshal json for /AuthZPlugin.AuthZReq: " + err.Error())
   107  		}
   108  
   109  		ctrl.reqUser = authReq.User
   110  		w.Write(b)
   111  	})
   112  
   113  	mux.HandleFunc("/AuthZPlugin.AuthZRes", func(w http.ResponseWriter, r *http.Request) {
   114  		defer r.Body.Close()
   115  		body, err := ioutil.ReadAll(r.Body)
   116  		if err != nil {
   117  			panic("could not read body for /AuthZPlugin.AuthZRes: " + err.Error())
   118  		}
   119  		authReq := authorization.Request{}
   120  		err = json.Unmarshal(body, &authReq)
   121  		if err != nil {
   122  			panic("could not unmarshal json for /AuthZPlugin.AuthZRes: " + err.Error())
   123  		}
   124  
   125  		assertBody(authReq.RequestURI, authReq.ResponseHeaders, authReq.ResponseBody)
   126  		assertAuthHeaders(authReq.ResponseHeaders)
   127  
   128  		// Count only server version api
   129  		if strings.HasSuffix(authReq.RequestURI, serverVersionAPI) {
   130  			ctrl.versionResCount++
   131  		}
   132  		resRes := ctrl.resRes
   133  		if isAllowed(authReq.RequestURI) {
   134  			resRes = authorization.Response{Allow: true}
   135  		}
   136  		if resRes.Err != "" {
   137  			w.WriteHeader(http.StatusInternalServerError)
   138  		}
   139  		b, err := json.Marshal(resRes)
   140  		if err != nil {
   141  			panic("could not marshal json for /AuthZPlugin.AuthZRes: " + err.Error())
   142  		}
   143  		ctrl.resUser = authReq.User
   144  		w.Write(b)
   145  	})
   146  }
   147  
   148  func teardownSuite() {
   149  	if server == nil {
   150  		return
   151  	}
   152  
   153  	server.Close()
   154  }
   155  
   156  // assertAuthHeaders validates authentication headers are removed
   157  func assertAuthHeaders(headers map[string]string) error {
   158  	for k := range headers {
   159  		if strings.Contains(strings.ToLower(k), "auth") || strings.Contains(strings.ToLower(k), "x-registry") {
   160  			panic(fmt.Sprintf("Found authentication headers in request '%v'", headers))
   161  		}
   162  	}
   163  	return nil
   164  }
   165  
   166  // assertBody asserts that body is removed for non text/json requests
   167  func assertBody(requestURI string, headers map[string]string, body []byte) {
   168  	if strings.Contains(strings.ToLower(requestURI), "auth") && len(body) > 0 {
   169  		panic("Body included for authentication endpoint " + string(body))
   170  	}
   171  
   172  	for k, v := range headers {
   173  		if strings.EqualFold(k, "Content-Type") && strings.HasPrefix(v, "text/") || v == "application/json" {
   174  			return
   175  		}
   176  	}
   177  	if len(body) > 0 {
   178  		panic(fmt.Sprintf("Body included while it should not (Headers: '%v')", headers))
   179  	}
   180  }