Enable only app user to do REST messaging
This commit is contained in:
@@ -21,7 +21,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/ibm-messaging/mq-container/internal/command"
|
"github.com/ibm-messaging/mq-container/internal/command"
|
||||||
)
|
)
|
||||||
@@ -33,7 +35,22 @@ func startWebServer() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Println("Starting web server")
|
log.Println("Starting web server")
|
||||||
out, rc, err := command.RunAsMQM("strmqweb")
|
cmd := exec.Command("strmqweb")
|
||||||
|
// Set a default app password for the web server, if one isn't already set
|
||||||
|
_, set := os.LookupEnv("MQ_APP_PASSWORD")
|
||||||
|
log.Println(cmd.Env)
|
||||||
|
if !set {
|
||||||
|
// Take all current environment variables, and add the app password
|
||||||
|
cmd.Env = append(os.Environ(), "MQ_APP_PASSWORD=passw0rd")
|
||||||
|
}
|
||||||
|
log.Println(cmd.Env)
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
|
uid, gid, err := command.LookupMQM()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
||||||
|
out, rc, err := command.RunCmd(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error %v starting web server: %v", rc, string(out))
|
log.Printf("Error %v starting web server: %v", rc, string(out))
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -23,13 +23,15 @@
|
|||||||
</enterpriseApplication>
|
</enterpriseApplication>
|
||||||
<basicRegistry id="basic" realm="defaultRealm">
|
<basicRegistry id="basic" realm="defaultRealm">
|
||||||
<user name="admin" password="${env.MQ_ADMIN_PASSWORD}"/>
|
<user name="admin" password="${env.MQ_ADMIN_PASSWORD}"/>
|
||||||
|
<!-- The app user will always get a default password of "passw0rd",
|
||||||
|
even if you don't set the environment variable.
|
||||||
|
See `webserver.go` -->
|
||||||
<user name="app" password="${env.MQ_APP_PASSWORD}"/>
|
<user name="app" password="${env.MQ_APP_PASSWORD}"/>
|
||||||
<group name="MQWebUI">
|
<group name="MQWebUI">
|
||||||
<member name="admin"/>
|
<member name="admin"/>
|
||||||
</group>
|
</group>
|
||||||
<group name="MQWebMessaging">
|
<group name="MQWebMessaging">
|
||||||
<member name="app"/>
|
<member name="app"/>
|
||||||
<member name="admin"/>
|
|
||||||
</group>
|
</group>
|
||||||
</basicRegistry>
|
</basicRegistry>
|
||||||
<variable name="httpHost" value="*"/>
|
<variable name="httpHost" value="*"/>
|
||||||
|
|||||||
@@ -50,15 +50,14 @@ func TestDevGoldenPath(t *testing.T) {
|
|||||||
waitForWebReady(t, cli, id, insecureTLSConfig)
|
waitForWebReady(t, cli, id, insecureTLSConfig)
|
||||||
t.Run("JMS", func(t *testing.T) {
|
t.Run("JMS", func(t *testing.T) {
|
||||||
// Run the JMS tests, with no password specified
|
// Run the JMS tests, with no password specified
|
||||||
runJMSTests(t, cli, id, false, "app", "")
|
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS)
|
||||||
})
|
})
|
||||||
t.Run("REST admin", func(t *testing.T) {
|
t.Run("REST admin", func(t *testing.T) {
|
||||||
testRESTAdmin(t, cli, id, insecureTLSConfig)
|
testRESTAdmin(t, cli, id, insecureTLSConfig)
|
||||||
})
|
})
|
||||||
t.Run("REST messaging as admin", func(t *testing.T) {
|
t.Run("REST messaging", func(t *testing.T) {
|
||||||
testRESTMessaging(t, cli, id, insecureTLSConfig, qm, "admin", devAdminPassword)
|
testRESTMessaging(t, cli, id, insecureTLSConfig, qm, "app", defaultAppPasswordWeb)
|
||||||
})
|
})
|
||||||
// Can't run the messaging tests as "app" with the defaults, because you can't have an empty password
|
|
||||||
// Stop the container cleanly
|
// Stop the container cleanly
|
||||||
stopContainer(t, cli, id)
|
stopContainer(t, cli, id)
|
||||||
}
|
}
|
||||||
@@ -73,11 +72,12 @@ func TestDevSecure(t *testing.T) {
|
|||||||
}
|
}
|
||||||
const tlsPassPhrase string = "passw0rd"
|
const tlsPassPhrase string = "passw0rd"
|
||||||
qm := "qm1"
|
qm := "qm1"
|
||||||
|
appPassword := "differentPassw0rd"
|
||||||
containerConfig := container.Config{
|
containerConfig := container.Config{
|
||||||
Env: []string{
|
Env: []string{
|
||||||
"LICENSE=accept",
|
"LICENSE=accept",
|
||||||
"MQ_QMGR_NAME=", qm,
|
"MQ_QMGR_NAME=" + qm,
|
||||||
"MQ_APP_PASSWORD=" + devAppPassword,
|
"MQ_APP_PASSWORD=" + appPassword,
|
||||||
"MQ_TLS_KEYSTORE=/var/tls/server.p12",
|
"MQ_TLS_KEYSTORE=/var/tls/server.p12",
|
||||||
"MQ_TLS_PASSPHRASE=" + tlsPassPhrase,
|
"MQ_TLS_PASSPHRASE=" + tlsPassPhrase,
|
||||||
"DEBUG=1",
|
"DEBUG=1",
|
||||||
@@ -111,17 +111,13 @@ func TestDevSecure(t *testing.T) {
|
|||||||
waitForWebReady(t, cli, ctr.ID, createTLSConfig(t, cert, tlsPassPhrase))
|
waitForWebReady(t, cli, ctr.ID, createTLSConfig(t, cert, tlsPassPhrase))
|
||||||
|
|
||||||
t.Run("JMS", func(t *testing.T) {
|
t.Run("JMS", func(t *testing.T) {
|
||||||
// Run the JMS tests, with no password specified
|
runJMSTests(t, cli, ctr.ID, true, "app", appPassword)
|
||||||
runJMSTests(t, cli, ctr.ID, true, "app", devAppPassword)
|
|
||||||
})
|
})
|
||||||
t.Run("REST admin", func(t *testing.T) {
|
t.Run("REST admin", func(t *testing.T) {
|
||||||
testRESTAdmin(t, cli, ctr.ID, insecureTLSConfig)
|
testRESTAdmin(t, cli, ctr.ID, insecureTLSConfig)
|
||||||
})
|
})
|
||||||
t.Run("REST messaging as admin", func(t *testing.T) {
|
t.Run("REST messaging", func(t *testing.T) {
|
||||||
testRESTMessaging(t, cli, ctr.ID, insecureTLSConfig, qm, "admin", devAdminPassword)
|
testRESTMessaging(t, cli, ctr.ID, insecureTLSConfig, qm, "app", appPassword)
|
||||||
})
|
|
||||||
t.Run("REST messaging as app", func(t *testing.T) {
|
|
||||||
testRESTMessaging(t, cli, ctr.ID, insecureTLSConfig, qm, "app", devAppPassword)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Stop the container cleanly
|
// Stop the container cleanly
|
||||||
@@ -152,7 +148,7 @@ func TestDevWebDisabled(t *testing.T) {
|
|||||||
})
|
})
|
||||||
t.Run("JMS", func(t *testing.T) {
|
t.Run("JMS", func(t *testing.T) {
|
||||||
// Run the JMS tests, with no password specified
|
// Run the JMS tests, with no password specified
|
||||||
runJMSTests(t, cli, id, false, "app", "")
|
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS)
|
||||||
})
|
})
|
||||||
// Stop the container cleanly
|
// Stop the container cleanly
|
||||||
stopContainer(t, cli, id)
|
stopContainer(t, cli, id)
|
||||||
|
|||||||
@@ -36,8 +36,9 @@ import (
|
|||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
const devAdminPassword string = "passw0rd"
|
const defaultAdminPassword string = "passw0rd"
|
||||||
const devAppPassword string = "passw0rd"
|
const defaultAppPasswordOS string = ""
|
||||||
|
const defaultAppPasswordWeb string = "passw0rd"
|
||||||
|
|
||||||
// Disable TLS verification (server uses a self-signed certificate by default,
|
// Disable TLS verification (server uses a self-signed certificate by default,
|
||||||
// so verification isn't useful anyway)
|
// so verification isn't useful anyway)
|
||||||
@@ -60,7 +61,7 @@ func waitForWebReady(t *testing.T, cli *client.Client, ID string, tlsConfig *tls
|
|||||||
select {
|
select {
|
||||||
case <-time.After(1 * time.Second):
|
case <-time.After(1 * time.Second):
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
req.SetBasicAuth("admin", devAdminPassword)
|
req.SetBasicAuth("admin", defaultAdminPassword)
|
||||||
resp, err := httpClient.Do(req.WithContext(ctx))
|
resp, err := httpClient.Do(req.WithContext(ctx))
|
||||||
if err == nil && resp.StatusCode == http.StatusOK {
|
if err == nil && resp.StatusCode == http.StatusOK {
|
||||||
t.Log("MQ web server is ready")
|
t.Log("MQ web server is ready")
|
||||||
@@ -151,7 +152,7 @@ func testRESTAdmin(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.C
|
|||||||
}
|
}
|
||||||
url := fmt.Sprintf("https://localhost:%s/ibmmq/rest/v1/admin/installation", getPort(t, cli, ID, 9443))
|
url := fmt.Sprintf("https://localhost:%s/ibmmq/rest/v1/admin/installation", getPort(t, cli, ID, 9443))
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
req.SetBasicAuth("admin", devAdminPassword)
|
req.SetBasicAuth("admin", defaultAdminPassword)
|
||||||
resp, err := httpClient.Do(req)
|
resp, err := httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ class JMSTests {
|
|||||||
factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
|
factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
|
||||||
factory.setChannel(channel);
|
factory.setChannel(channel);
|
||||||
factory.setConnectionNameList(String.format("%s(1414)", addr));
|
factory.setConnectionNameList(String.format("%s(1414)", addr));
|
||||||
|
// If a password is set, make sure it gets sent to the queue manager for authentication
|
||||||
|
if (password != null) {
|
||||||
|
factory.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);
|
||||||
|
}
|
||||||
// factory.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT);
|
// factory.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT);
|
||||||
if (TRUSTSTORE == null) {
|
if (TRUSTSTORE == null) {
|
||||||
LOGGER.info("Not using TLS");
|
LOGGER.info("Not using TLS");
|
||||||
|
|||||||
Reference in New Issue
Block a user