Skip to content

Commit

Permalink
[ADD] cli: keygen command
Browse files Browse the repository at this point in the history
The command connects to a running instance. By default "localhost:8080".
The spec is: MASTERKEY CHANNEL ACCESS [ -t=ttl] [ -h=host ]

Note: If we start adding more commands, ideally the cli should move to a
separate project.

Closes: #430
  • Loading branch information
Florimond committed Oct 8, 2024
1 parent 49b0856 commit 910b5de
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 5 deletions.
13 changes: 8 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
)
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down Expand Up @@ -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=
Expand Down Expand Up @@ -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=
Expand All @@ -242,13 +248,17 @@ 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=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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=
Expand All @@ -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=
Expand Down
89 changes: 89 additions & 0 deletions internal/command/keygen/keygen.go
Original file line number Diff line number Diff line change
@@ -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<http://www.gnu.org/licenses/>.
************************************************************************************/

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=<ttl>] [ -h=<host> ]"
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 <ip:port> 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)
}
}
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
}
Expand Down

0 comments on commit 910b5de

Please sign in to comment.