From 0c9338b7d6699ba7d518403aae696f2d8eacf90c Mon Sep 17 00:00:00 2001 From: Arthur Barr Date: Thu, 2 Aug 2018 17:20:31 +0100 Subject: [PATCH] Enable admin and app users to do REST messaging --- .../Installation1/servers/mqweb/mqwebuser.xml | 8 +++ test/docker/devconfig_test.go | 29 +++++++- test/docker/devconfig_test_util.go | 72 ++++++++++++++++++- 3 files changed, 104 insertions(+), 5 deletions(-) diff --git a/incubating/mqadvanced-server-dev/web/installations/Installation1/servers/mqweb/mqwebuser.xml b/incubating/mqadvanced-server-dev/web/installations/Installation1/servers/mqweb/mqwebuser.xml index f0e5ada..d5d2303 100644 --- a/incubating/mqadvanced-server-dev/web/installations/Installation1/servers/mqweb/mqwebuser.xml +++ b/incubating/mqadvanced-server-dev/web/installations/Installation1/servers/mqweb/mqwebuser.xml @@ -16,13 +16,21 @@ + + + + + + + + diff --git a/test/docker/devconfig_test.go b/test/docker/devconfig_test.go index da172d3..46a52d2 100644 --- a/test/docker/devconfig_test.go +++ b/test/docker/devconfig_test.go @@ -37,10 +37,11 @@ func TestDevGoldenPath(t *testing.T) { if err != nil { t.Fatal(err) } + qm := "qm1" containerConfig := container.Config{ Env: []string{ "LICENSE=accept", - "MQ_QMGR_NAME=qm1", + "MQ_QMGR_NAME=" + qm, }, } id := runContainerWithPorts(t, cli, &containerConfig, []int{9443}) @@ -51,6 +52,13 @@ func TestDevGoldenPath(t *testing.T) { // Run the JMS tests, with no password specified runJMSTests(t, cli, id, false, "app", "") }) + t.Run("REST admin", func(t *testing.T) { + testRESTAdmin(t, cli, id, insecureTLSConfig) + }) + t.Run("REST messaging as admin", func(t *testing.T) { + testRESTMessaging(t, cli, id, insecureTLSConfig, qm, "admin", devAdminPassword) + }) + // Can't run the messaging tests as "app" with the defaults, because you can't have an empty password // Stop the container cleanly stopContainer(t, cli, id) } @@ -64,10 +72,11 @@ func TestDevSecure(t *testing.T) { t.Fatal(err) } const tlsPassPhrase string = "passw0rd" + qm := "qm1" containerConfig := container.Config{ Env: []string{ "LICENSE=accept", - "MQ_QMGR_NAME=qm1", + "MQ_QMGR_NAME=", qm, "MQ_APP_PASSWORD=" + devAppPassword, "MQ_TLS_KEYSTORE=/var/tls/server.p12", "MQ_TLS_PASSPHRASE=" + tlsPassPhrase, @@ -100,7 +109,21 @@ func TestDevSecure(t *testing.T) { waitForReady(t, cli, ctr.ID) cert := filepath.Join(tlsDir(t, true), "server.crt") waitForWebReady(t, cli, ctr.ID, createTLSConfig(t, cert, tlsPassPhrase)) - runJMSTests(t, cli, ctr.ID, true, "app", devAppPassword) + + t.Run("JMS", func(t *testing.T) { + // Run the JMS tests, with no password specified + runJMSTests(t, cli, ctr.ID, true, "app", devAppPassword) + }) + t.Run("REST admin", func(t *testing.T) { + testRESTAdmin(t, cli, ctr.ID, insecureTLSConfig) + }) + t.Run("REST messaging as admin", func(t *testing.T) { + testRESTMessaging(t, cli, ctr.ID, insecureTLSConfig, qm, "admin", devAdminPassword) + }) + t.Run("REST messaging as app", func(t *testing.T) { + testRESTMessaging(t, cli, ctr.ID, insecureTLSConfig, qm, "app", devAppPassword) + }) + // Stop the container cleanly stopContainer(t, cli, ctr.ID) } diff --git a/test/docker/devconfig_test_util.go b/test/docker/devconfig_test_util.go index c89e458..9e08127 100644 --- a/test/docker/devconfig_test_util.go +++ b/test/docker/devconfig_test_util.go @@ -18,12 +18,14 @@ limitations under the License. package main import ( + "bytes" "context" "crypto/tls" "crypto/x509" "fmt" "io/ioutil" "net/http" + "net/http/httputil" "path/filepath" "strings" "testing" @@ -140,14 +142,13 @@ func createTLSConfig(t *testing.T, certFile, password string) *tls.Config { } } -func testREST(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.Config) { +func testRESTAdmin(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.Config) { httpClient := http.Client{ Timeout: time.Duration(30 * time.Second), Transport: &http.Transport{ TLSClientConfig: tlsConfig, }, } - url := fmt.Sprintf("https://localhost:%s/ibmmq/rest/v1/admin/installation", getPort(t, cli, ID, 9443)) req, err := http.NewRequest("GET", url, nil) req.SetBasicAuth("admin", devAdminPassword) @@ -159,3 +160,70 @@ func testREST(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.Config t.Errorf("Expected HTTP status code %v from 'GET installation'; got %v", http.StatusOK, resp.StatusCode) } } + +// curl -i -k https://localhost:1234/ibmmq/rest/v1/messaging/qmgr/qm1/queue/DEV.QUEUE.1/message -X POST -u app -H “ibm-mq-rest-csrf-token: N/A” -H “Content-Type: text/plain;charset=utf-8" -d “Hello World” + +func logHTTPRequest(t *testing.T, req *http.Request) { + d, err := httputil.DumpRequestOut(req, true) + if err != nil { + t.Error(err) + } + t.Logf("HTTP request: %v", string(d)) +} + +func logHTTPResponse(t *testing.T, resp *http.Response) { + d, err := httputil.DumpResponse(resp, true) + if err != nil { + t.Error(err) + } + t.Logf("HTTP response: %v", string(d)) +} + +func testRESTMessaging(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.Config, qmName string, user string, password string) { + httpClient := http.Client{ + Timeout: time.Duration(30 * time.Second), + Transport: &http.Transport{ + TLSClientConfig: tlsConfig, + }, + } + q := "DEV.QUEUE.1" + url := fmt.Sprintf("https://localhost:%s/ibmmq/rest/v1/messaging/qmgr/%s/queue/%s/message", getPort(t, cli, ID, 9443), qmName, q) + putMessage := []byte("Hello") + req, err := http.NewRequest("POST", url, bytes.NewBuffer(putMessage)) + req.SetBasicAuth(user, password) + req.Header.Add("ibm-mq-rest-csrf-token", "n/a") + req.Header.Add("Content-Type", "text/plain;charset=utf-8") + logHTTPRequest(t, req) + resp, err := httpClient.Do(req) + if err != nil { + t.Fatal(err) + } + logHTTPResponse(t, resp) + if resp.StatusCode != http.StatusCreated { + t.Errorf("Expected HTTP status code %v from 'POST to queue'; got %v", http.StatusOK, resp.StatusCode) + t.Logf("HTTP response: %+v", resp) + t.Fail() + } + + req, err = http.NewRequest("DELETE", url, nil) + req.Header.Add("ibm-mq-rest-csrf-token", "n/a") + req.SetBasicAuth(user, password) + logHTTPRequest(t, req) + resp, err = httpClient.Do(req) + if err != nil { + t.Fatal(err) + } + logHTTPResponse(t, resp) + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + t.Errorf("Expected HTTP status code %v from 'DELETE from queue'; got %v", http.StatusOK, resp.StatusCode) + t.Logf("HTTP response: %+v", resp) + t.Fail() + } + gotMessage, err := ioutil.ReadAll(resp.Body) + //gotMessage := string(b) + if string(gotMessage) != string(putMessage) { + t.Errorf("Expected payload to be \"%s\"; got \"%s\"", putMessage, gotMessage) + } +}