diff --git a/go.mod b/go.mod
index 8b3a2b5b..f58c4fab 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
github.com/emitter-io/config v1.0.0
github.com/emitter-io/stats v1.0.3
github.com/golang/snappy v0.0.4
- github.com/gorilla/websocket v1.5.1
+ github.com/gorilla/websocket v1.5.3
github.com/jawher/mow.cli v1.2.0
github.com/kelindar/binary v1.0.18
github.com/kelindar/rate v1.0.0
@@ -25,11 +25,13 @@ require (
github.com/tidwall/pretty v1.2.1 // indirect
github.com/valyala/fasthttp v1.51.0
github.com/weaveworks/mesh v0.0.0-20191105120815-58dbcc3e8e63
- golang.org/x/crypto v0.18.0
- golang.org/x/net v0.20.0 // indirect
+ golang.org/x/crypto v0.25.0
+ golang.org/x/net v0.27.0 // indirect
gopkg.in/alexcesaro/statsd.v2 v2.0.0
)
+require github.com/eclipse/paho.mqtt.golang v1.5.0
+
require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@@ -60,8 +62,9 @@ require (
github.com/tidwall/tinyqueue v0.1.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
go.opencensus.io v0.24.0 // indirect
- golang.org/x/sys v0.16.0 // indirect
- golang.org/x/text v0.14.0 // indirect
+ golang.org/x/sync v0.7.0 // indirect
+ golang.org/x/sys v0.22.0 // indirect
+ golang.org/x/text v0.16.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index d761fab9..72b5a6ef 100644
--- a/go.sum
+++ b/go.sum
@@ -45,6 +45,8 @@ github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fp
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
+github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
github.com/emitter-io/address v1.0.1 h1:1bTyviCKDkB60rrFpHr6BY3AKjNWP3InY/WO6qPKkVU=
github.com/emitter-io/address v1.0.1/go.mod h1:kF9+NdGTAvzRKMd78zjj7MN01yDB9fPwZl2waJRlfYU=
github.com/emitter-io/config v1.0.0 h1:qpJMei4v3KL0Z5vsspVful/JIRr6v4zg8R28pG4Ry4M=
@@ -100,6 +102,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
+github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
+github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@@ -224,6 +228,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
+golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
+golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -242,6 +248,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
+golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
+golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -249,6 +257,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -259,10 +269,14 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
+golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
diff --git a/internal/command/keygen/keygen.go b/internal/command/keygen/keygen.go
new file mode 100644
index 00000000..886604cf
--- /dev/null
+++ b/internal/command/keygen/keygen.go
@@ -0,0 +1,89 @@
+/**********************************************************************************
+* Copyright (c) 2009-2019 Misakai Ltd.
+* This program is free software: you can redistribute it and/or modify it under the
+* terms of the GNU Affero General Public License as published by the Free Software
+* Foundation, either version 3 of the License, or(at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY
+* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+* PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License along
+* with this program. If not, see.
+************************************************************************************/
+
+package keygen
+
+import (
+ "encoding/json"
+ "fmt"
+
+ mqtt "github.com/eclipse/paho.mqtt.golang"
+ "github.com/emitter-io/emitter/internal/errors"
+ "github.com/emitter-io/emitter/internal/provider/logging"
+ "github.com/emitter-io/emitter/internal/service/keygen"
+ cli "github.com/jawher/mow.cli"
+)
+
+// Generate a new channel key.
+func NewKey(cmd *cli.Cmd) {
+ cmd.Spec = "MASTERKEY CHANNEL ACCESS [ -t=] [ -h= ]"
+ var (
+ masterkey = cmd.StringArg("MASTERKEY", "", "Specifies the master key for generating channel keys.")
+ channel = cmd.StringArg("CHANNEL", "", "Specifies the name channel for which to generate key.")
+ access = cmd.StringArg("ACCESS", "", "Specifies the access rights for the channel (rwslpex).")
+ ttl = cmd.IntOpt("t ttl", 0, "Specifies the time to live for the key in seconds. By default, the key will never expire.")
+ host = cmd.StringOpt("h host", "127.0.0.1:8080", "Specifies the broker host name and port. This must follow the format.")
+ )
+
+ cmd.Action = func() {
+ // Create a channel to receive the response.
+ respChan := make(chan []byte)
+
+ // Create a new MQTT client.
+ opts := mqtt.NewClientOptions().AddBroker(fmt.Sprintf("tcp://%s", *host))
+ opts.SetDefaultPublishHandler(func(client mqtt.Client, m mqtt.Message) {
+ respChan <- m.Payload()
+ })
+ client := mqtt.NewClient(opts)
+
+ // Connect to the MQTT broker.
+ if token := client.Connect(); token.Wait() && token.Error() != nil {
+ panic(fmt.Errorf("failed to connect: %v", token.Error()))
+ }
+
+ // Publish the request.
+ request := keygen.Request{
+ Key: *masterkey,
+ Channel: *channel,
+ Type: *access,
+ TTL: int32(*ttl),
+ }
+ payload, err := json.Marshal(request)
+ if err != nil {
+ logging.LogError("keygen", "marshaling the request", err)
+ return
+ }
+ if token := client.Publish("emitter/keygen/", 1, false, payload); token.Wait() && token.Error() != nil {
+ logging.LogError("keygen", "publishing the request", token.Error())
+ return
+ }
+
+ // Wait for the response and check whether it's an error.
+ response := <-respChan
+ var errResponse errors.Error
+ if err := json.Unmarshal(response, &errResponse); err == nil && errResponse.Error() != "" {
+ logging.LogError("keygen", "generating the key", fmt.Errorf("error: %s", errResponse.Error()))
+ return
+ }
+
+ // Parse the response and print the key.
+ keygen := keygen.Response{}
+ if err := json.Unmarshal(response, &keygen); err != nil {
+ logging.LogError("keygen", "parsing the response", err)
+ return
+ }
+ fmt.Println(keygen.Key)
+ client.Disconnect(250)
+ }
+}
diff --git a/main.go b/main.go
index c982ef8c..5fb78683 100644
--- a/main.go
+++ b/main.go
@@ -21,6 +21,7 @@ import (
"github.com/emitter-io/config/dynamo"
"github.com/emitter-io/config/vault"
"github.com/emitter-io/emitter/internal/broker"
+ "github.com/emitter-io/emitter/internal/command/keygen"
"github.com/emitter-io/emitter/internal/command/license"
"github.com/emitter-io/emitter/internal/command/load"
"github.com/emitter-io/emitter/internal/command/version"
@@ -44,6 +45,7 @@ func main() {
cmd.Command("new", "Generates a new license and secret key pair.", license.New)
// TODO: add more sub-commands for license
})
+ app.Command("keygen", "Generates a new key for a channel.", keygen.NewKey)
app.Run(os.Args)
}