func TestJwtUnknownUser(t *testing.T) { // Setup jwt c := &JwtAuthConfig{} c.Admin.PrivateKey = "Key" c.User.PrivateKey = "UserKey" j := NewJwtAuth(c) tests.Assert(t, j != nil) // Setup middleware framework n := negroni.New(j) tests.Assert(t, n != nil) // Create a simple middleware to check if it was called called := false mw := func(rw http.ResponseWriter, r *http.Request) { called = true } n.UseHandlerFunc(mw) // Create test server ts := httptest.NewServer(n) // Create token with invalid user token := jwt.New(jwt.SigningMethodHS256) token.Claims["iat"] = time.Now().Unix() token.Claims["exp"] = time.Now().Add(time.Second * 5).Unix() token.Claims["iss"] = "someotheruser" tokenString, err := token.SignedString([]byte("Key")) tests.Assert(t, err == nil) // Setup header req, err := http.NewRequest("GET", ts.URL, nil) tests.Assert(t, err == nil) // Miss 'bearer' string req.Header.Set("Authorization", "bearer "+tokenString) r, err := http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusUnauthorized) tests.Assert(t, called == false) s, err := utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "Unknown user")) }
func TestJwtGarbageToken(t *testing.T) { // Setup jwt c := &JwtAuthConfig{} c.Admin.PrivateKey = "Key" c.User.PrivateKey = "UserKey" j := NewJwtAuth(c) tests.Assert(t, j != nil) // Setup middleware framework n := negroni.New(j) tests.Assert(t, n != nil) // Create a simple middleware to check if it was called called := false mw := func(rw http.ResponseWriter, r *http.Request) { called = true } n.UseHandlerFunc(mw) // Create test server ts := httptest.NewServer(n) // Setup header req, err := http.NewRequest("GET", ts.URL, nil) tests.Assert(t, err == nil) // Miss 'bearer' string req.Header.Set("Authorization", "123456770309238402938402398409234") // Call r, err := http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) tests.Assert(t, called == false) s, err := utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "Authorization header format must be Bearer")) // Setup header req, err = http.NewRequest("GET", ts.URL, nil) tests.Assert(t, err == nil) req.Header.Set("Authorization", "bearer") // Call r, err = http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) tests.Assert(t, called == false) s, err = utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "Authorization header format must be Bearer")) // Setup header req, err = http.NewRequest("GET", ts.URL, nil) tests.Assert(t, err == nil) req.Header.Set("Authorization", "bearer 123456770309238402938402398409234") // Call r, err = http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusUnauthorized) tests.Assert(t, called == false) s, err = utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "token contains an invalid number of segments")) }
func TestJwtInvalidToken(t *testing.T) { // Setup jwt c := &JwtAuthConfig{} c.Admin.PrivateKey = "Key" c.User.PrivateKey = "UserKey" j := NewJwtAuth(c) tests.Assert(t, j != nil) // Setup middleware framework n := negroni.New(j) tests.Assert(t, n != nil) // Create a simple middleware to check if it was called called := false mw := func(rw http.ResponseWriter, r *http.Request) { called = true } n.UseHandlerFunc(mw) // Create test server ts := httptest.NewServer(n) // Create token with missing 'iss' claim token := jwt.New(jwt.SigningMethodHS256) token.Claims["iat"] = time.Now().Unix() token.Claims["exp"] = time.Now().Add(time.Second * 5).Unix() tokenString, err := token.SignedString([]byte("Key")) tests.Assert(t, err == nil) // Setup header req, err := http.NewRequest("GET", ts.URL, nil) tests.Assert(t, err == nil) // Miss 'bearer' string req.Header.Set("Authorization", "bearer "+tokenString) r, err := http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusUnauthorized) tests.Assert(t, called == false) s, err := utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "Token missing iss claim")) // Create an expired token token = jwt.New(jwt.SigningMethodHS256) token.Claims["iat"] = time.Now().Unix() token.Claims["exp"] = time.Now().Add(time.Millisecond).Unix() token.Claims["iss"] = "admin" tokenString, err = token.SignedString([]byte("Key")) tests.Assert(t, err == nil) // Wait a bit time.Sleep(time.Second) // Setup header req, err = http.NewRequest("GET", ts.URL, nil) tests.Assert(t, err == nil) // Send request req.Header.Set("Authorization", "bearer "+tokenString) r, err = http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusUnauthorized) tests.Assert(t, called == false) s, err = utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "token is expired")) // Create missing 'qsh' claim token = jwt.New(jwt.SigningMethodHS256) token.Claims["iat"] = time.Now().Unix() token.Claims["exp"] = time.Now().Add(time.Second * 10).Unix() token.Claims["iss"] = "admin" tokenString, err = token.SignedString([]byte("Key")) tests.Assert(t, err == nil) // Setup header req, err = http.NewRequest("GET", ts.URL, nil) tests.Assert(t, err == nil) // Send request req.Header.Set("Authorization", "bearer "+tokenString) r, err = http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusUnauthorized) tests.Assert(t, called == false) s, err = utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "Invalid qsh claim in token")) // Create an invalid 'qsh' claim token = jwt.New(jwt.SigningMethodHS256) token.Claims["iat"] = time.Now().Unix() token.Claims["exp"] = time.Now().Add(time.Second * 10).Unix() token.Claims["iss"] = "admin" token.Claims["qsh"] = "12343345678945678a" tokenString, err = token.SignedString([]byte("Key")) tests.Assert(t, err == nil) // Setup header req, err = http.NewRequest("GET", ts.URL, nil) tests.Assert(t, err == nil) // Send request req.Header.Set("Authorization", "bearer "+tokenString) r, err = http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusUnauthorized) tests.Assert(t, called == false) s, err = utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "Invalid qsh claim in token")) }
func TestNodePeerDetachFailure(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Create a cluster. We do not want // any drives in the node so we can delete easily err := setupSampleDbWithTopology(app, 1, // clusters 4, // nodes_per_cluster 0, // devices_per_node, 50*GB, // disksize) ) tests.Assert(t, err == nil) // Setup the mock peer probe to fail peer_called := false peer_calls := 0 app.xo.MockPeerDetach = func(exec_host, newnode string) error { peer_calls++ peer_called = true return errors.New("Mock") } // Get a node id var nodeid string err = app.db.View(func(tx *bolt.Tx) error { clusterlist, err := ClusterList(tx) if err != nil { return err } cluster, err := NewClusterEntryFromId(tx, clusterlist[0]) if err != nil { return err } nodeid = cluster.Info.Nodes[0] return nil }) tests.Assert(t, err == nil) tests.Assert(t, nodeid != "") // Delete node req, err := http.NewRequest("DELETE", ts.URL+"/nodes/"+nodeid, nil) tests.Assert(t, err == nil) r, err := http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusAccepted) location, err := r.Location() tests.Assert(t, err == nil) // Since we forced the MockPeerDetach above to fail, the request should fail for { r, err = http.Get(location.String()) tests.Assert(t, err == nil) if r.Header.Get("X-Pending") == "true" { tests.Assert(t, r.StatusCode == http.StatusOK) time.Sleep(time.Millisecond * 10) } else { tests.Assert(t, r.StatusCode == http.StatusInternalServerError) s, err := utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.TrimSpace(s) == "Mock") tests.Assert(t, peer_called == true) tests.Assert(t, peer_calls == 1) break } } // Check that the node is still in the db err = app.db.View(func(tx *bolt.Tx) error { clusters, err := ClusterList(tx) if err != nil { return err } cluster, err := NewClusterEntryFromId(tx, clusters[0]) if err != nil { return err } tests.Assert(t, utils.SortedStringHas(cluster.Info.Nodes, nodeid)) _, err = NewNodeEntryFromId(tx, nodeid) return err }) tests.Assert(t, err == nil) }
func TestNodePeerProbeFailure(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Create a cluster. We at least one // other node in the same cluster to execute a probe err := setupSampleDbWithTopology(app, 1, // clusters 4, // nodes_per_cluster 4, // devices_per_node, 50*GB, // disksize) ) tests.Assert(t, err == nil) // Setup the mock peer probe to fail peerprobe_called := false peerprobe_calls := 0 app.xo.MockPeerProbe = func(exec_host, newnode string) error { peerprobe_calls++ peerprobe_called = true return errors.New("Mock") } // Get cluter id var clusterlist []string err = app.db.View(func(tx *bolt.Tx) error { var err error clusterlist, err = ClusterList(tx) return err }) tests.Assert(t, err == nil) tests.Assert(t, len(clusterlist) == 1) clusterid := clusterlist[0] // Create a node storage_name := "host.hostname.com" manage_name := "host.hostname.com" request := []byte(`{ "cluster" : "` + clusterid + `", "hostnames" : { "storage" : [ "` + storage_name + `" ], "manage" : [ "` + manage_name + `" ] }, "zone" : 1 }`) // Create node r, err := http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusAccepted) location, err := r.Location() tests.Assert(t, err == nil) // Since we forced the MockPeerProbe above to fail, the request should fail for { r, err = http.Get(location.String()) tests.Assert(t, err == nil) if r.Header.Get("X-Pending") == "true" { tests.Assert(t, r.StatusCode == http.StatusOK) time.Sleep(time.Millisecond * 10) } else { tests.Assert(t, r.StatusCode == http.StatusInternalServerError) s, err := utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.TrimSpace(s) == "Mock") tests.Assert(t, peerprobe_called == true) tests.Assert(t, peerprobe_calls == 1) break } } // Check that the node has not been added to the db var nodelist []string var cluster *ClusterEntry err = app.db.View(func(tx *bolt.Tx) error { var err error cluster, err = NewClusterEntryFromId(tx, clusterid) if err != nil { return err } // Check that the node has not registered b := tx.Bucket([]byte(BOLTDB_BUCKET_NODE)) tests.Assert(t, b != nil) val := b.Get([]byte("STORAGE" + storage_name)) tests.Assert(t, val == nil) val = b.Get([]byte("MANAGE" + manage_name)) tests.Assert(t, val == nil) // Set nodelist nodelist = EntryKeys(tx, BOLTDB_BUCKET_NODE) return nil }) tests.Assert(t, err == nil) tests.Assert(t, len(nodelist) == 4) tests.Assert(t, len(cluster.Info.Nodes) == 4) }
func TestNodeAddBadRequests(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // ClusterCreate JSON Request request := []byte(`{ bad json }`) // Post bad JSON r, err := http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == 422) // Make a request without hostnames request = []byte(`{ "cluster" : "123", "hostname" : {} }`) // Post bad JSON r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) // Make a request with only manage hostname request = []byte(`{ "cluster" : "123", "hostnames" : { "manage" : [ "manage.hostname.com" ] }, "zone" : 10 }`) // Post bad JSON r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest, *r) // Make a request with only storage hostname request = []byte(`{ "cluster" : "123", "hostnames" : { "storage" : [ "storage.hostname.com" ] }, "zone" : 10 }`) // Post bad JSON r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) // Make a request where the hostnames are empty strings request = []byte(`{ "cluster" : "123", "hostnames" : { "storage" : [ "" ], "manage" : [ "" ] }, "zone" : 10 }`) // Check that it returns that the cluster id is not found r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) s, err := utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "empty string")) // Make a request where the zone is missing request = []byte(`{ "cluster" : "123", "hostnames" : { "storage" : [ "storage.hostname.com" ], "manage" : [ "manage.hostname.com" ] } }`) // Check that it returns that the cluster id is not found r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) s, err = utils.GetStringFromResponse(r) tests.Assert(t, err == nil) tests.Assert(t, strings.Contains(s, "Zone cannot be zero")) // Make a request where the cluster id does not exist request = []byte(`{ "cluster" : "123", "hostnames" : { "storage" : [ "storage.hostname.com" ], "manage" : [ "manage.hostname.com" ] }, "zone" : 10 }`) // Check that it returns that the cluster id is not found r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusNotFound, r.StatusCode) }