diff --git a/server/const.go b/server/const.go index 7230981e..97d29725 100644 --- a/server/const.go +++ b/server/const.go @@ -8,7 +8,7 @@ import ( const ( // VERSION is the current version for the server. - VERSION = "0.8.1" + VERSION = "0.8.2" // DEFAULT_PORT is the deault port for client connections. DEFAULT_PORT = 4222 diff --git a/server/monitor.go b/server/monitor.go index 1368a636..8f785701 100644 --- a/server/monitor.go +++ b/server/monitor.go @@ -36,25 +36,26 @@ type Connz struct { // ConnInfo has detailed information on a per connection basis. type ConnInfo struct { - Cid uint64 `json:"cid"` - IP string `json:"ip"` - Port int `json:"port"` - Start time.Time `json:"start"` - LastActivity time.Time `json:"last_activity"` - Uptime string `json:"uptime"` - Idle string `json:"idle"` - Pending int `json:"pending_bytes"` - InMsgs int64 `json:"in_msgs"` - OutMsgs int64 `json:"out_msgs"` - InBytes int64 `json:"in_bytes"` - OutBytes int64 `json:"out_bytes"` - NumSubs uint32 `json:"subscriptions"` - Name string `json:"name,omitempty"` - Lang string `json:"lang,omitempty"` - Version string `json:"version,omitempty"` - TLSVersion string `json:"tls_version,omitempty"` - TLSCipher string `json:"tls_cipher_suite,omitempty"` - Subs []string `json:"subscriptions_list,omitempty"` + Cid uint64 `json:"cid"` + IP string `json:"ip"` + Port int `json:"port"` + Start time.Time `json:"start"` + LastActivity time.Time `json:"last_activity"` + Uptime string `json:"uptime"` + Idle string `json:"idle"` + Pending int `json:"pending_bytes"` + InMsgs int64 `json:"in_msgs"` + OutMsgs int64 `json:"out_msgs"` + InBytes int64 `json:"in_bytes"` + OutBytes int64 `json:"out_bytes"` + NumSubs uint32 `json:"subscriptions"` + Name string `json:"name,omitempty"` + Lang string `json:"lang,omitempty"` + Version string `json:"version,omitempty"` + TLSVersion string `json:"tls_version,omitempty"` + TLSCipher string `json:"tls_cipher_suite,omitempty"` + AuthorizedUser string `json:"authorized_user,omitempty"` + Subs []string `json:"subscriptions_list,omitempty"` } // DefaultConnListSize is the default size of the connection list. @@ -76,6 +77,7 @@ func (s *Server) HandleConnz(w http.ResponseWriter, r *http.Request) { c := &Connz{} c.Now = time.Now() + auth, _ := strconv.Atoi(r.URL.Query().Get("auth")) subs, _ := strconv.Atoi(r.URL.Query().Get("subs")) c.Offset, _ = strconv.Atoi(r.URL.Query().Get("offset")) c.Limit, _ = strconv.Atoi(r.URL.Query().Get("limit")) @@ -216,6 +218,7 @@ func (s *Server) HandleConnz(w http.ResponseWriter, r *http.Request) { ci.IP = addr.IP.String() } + // Fill in subscription data if requested. if subs == 1 { sublist := make([]*subscription, 0, len(client.subs)) for _, sub := range client.subs { @@ -224,6 +227,11 @@ func (s *Server) HandleConnz(w http.ResponseWriter, r *http.Request) { ci.Subs = castToSliceString(sublist) } + // Fill in user if auth requested. + if auth == 1 { + ci.AuthorizedUser = client.opts.Username + } + client.mu.Unlock() i++ } diff --git a/test/configs/multi_user.conf b/test/configs/multi_user.conf index ebfb5964..0bf83298 100644 --- a/test/configs/multi_user.conf +++ b/test/configs/multi_user.conf @@ -1,6 +1,7 @@ # Copyright 2016 Apcera Inc. All rights reserved. listen: 127.0.0.1:4233 +http: 127.0.0.1:8233 authorization { users = [ diff --git a/test/monitor_test.go b/test/monitor_test.go index 0d3c4b12..d68c6224 100644 --- a/test/monitor_test.go +++ b/test/monitor_test.go @@ -377,6 +377,54 @@ func TestConnzWithSubs(t *testing.T) { } } +func TestConnzWithAuth(t *testing.T) { + srv, opts := RunServerWithConfig("./configs/multi_user.conf") + defer srv.Shutdown() + + endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port) + curl := fmt.Sprintf("nats://%s:%s@%s/", opts.Users[0].Username, opts.Users[0].Password, endpoint) + nc, err := nats.Connect(curl) + if err != nil { + t.Fatalf("Got an error on Connect: %+v\n", err) + } + defer nc.Close() + + ch := make(chan struct{}) + nc.Subscribe("foo", func(m *nats.Msg) { ch <- struct{}{} }) + nc.Publish("foo", []byte("Hello")) + + // Wait for message + <-ch + + url := fmt.Sprintf("http://localhost:%d/", opts.HTTPPort) + + resp, err := http.Get(url + "connz?auth=1") + if err != nil { + t.Fatalf("Expected no error: Got %v\n", err) + } + if resp.StatusCode != 200 { + t.Fatalf("Expected a 200 response, got %d\n", resp.StatusCode) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Fatalf("Got an error reading the body: %v\n", err) + } + + c := server.Connz{} + if err := json.Unmarshal(body, &c); err != nil { + t.Fatalf("Got an error unmarshalling the body: %v\n", err) + } + + // Test that we have authorized_user and its Alice. + ci := c.Conns[0] + if ci.AuthorizedUser != opts.Users[0].Username { + t.Fatalf("Expected authorized_user to be %q, got %q\n", + opts.Users[0].Username, ci.AuthorizedUser) + } + +} + func TestConnzWithOffsetAndLimit(t *testing.T) { s := runMonitorServer() defer s.Shutdown()