mirror of
https://github.com/absmach/magistrala.git
synced 2026-08-07 07:14:46 +00:00
SMQ-3028 - Unify SMQ certs with Absmach Certs (#3146)
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
-113
@@ -1,113 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var cmdCerts = []cobra.Command{
|
||||
{
|
||||
Use: "get [<cert_serial> | client <client_id> ] <domain_id> <user_auth_token>",
|
||||
Short: "Get certificate",
|
||||
Long: `Gets a certificate for a given cert ID.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) < 3 {
|
||||
logUsageCmd(*cmd, cmd.Use)
|
||||
return
|
||||
}
|
||||
if args[0] == "client" {
|
||||
cert, err := sdk.ViewCertByClient(cmd.Context(), args[1], args[2], args[3])
|
||||
if err != nil {
|
||||
logErrorCmd(*cmd, err)
|
||||
return
|
||||
}
|
||||
logJSONCmd(*cmd, cert)
|
||||
return
|
||||
}
|
||||
cert, err := sdk.ViewCert(cmd.Context(), args[0], args[1], args[2])
|
||||
if err != nil {
|
||||
logErrorCmd(*cmd, err)
|
||||
return
|
||||
}
|
||||
logJSONCmd(*cmd, cert)
|
||||
},
|
||||
},
|
||||
{
|
||||
Use: "revoke-all <client_id> <domain_id> <user_auth_token>",
|
||||
Short: "Revoke certificate",
|
||||
Long: `Revokes a certificate for a given client ID.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 3 {
|
||||
logUsageCmd(*cmd, cmd.Use)
|
||||
return
|
||||
}
|
||||
rtime, err := sdk.RevokeAllCerts(cmd.Context(), args[0], args[1], args[2])
|
||||
if err != nil {
|
||||
logErrorCmd(*cmd, err)
|
||||
return
|
||||
}
|
||||
logRevokedTimeCmd(*cmd, rtime)
|
||||
},
|
||||
},
|
||||
{
|
||||
Use: "revoke <cert_serial> <domain_id> <user_auth_token>",
|
||||
Short: "Revoke certificate",
|
||||
Long: `Revokes a certificate for a given cert serial.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 3 {
|
||||
logUsageCmd(*cmd, cmd.Use)
|
||||
return
|
||||
}
|
||||
rtime, err := sdk.RevokeCert(cmd.Context(), args[0], args[1], args[2])
|
||||
if err != nil {
|
||||
logErrorCmd(*cmd, err)
|
||||
return
|
||||
}
|
||||
logRevokedTimeCmd(*cmd, rtime)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// NewCertsCmd returns certificate command.
|
||||
func NewCertsCmd() *cobra.Command {
|
||||
var ttl string
|
||||
|
||||
issueCmd := cobra.Command{
|
||||
Use: "issue <client_id> <domain_id> <user_auth_token> [--ttl=8760h]",
|
||||
Short: "Issue certificate",
|
||||
Long: `Issues new certificate for a client`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 3 {
|
||||
logUsageCmd(*cmd, cmd.Use)
|
||||
return
|
||||
}
|
||||
|
||||
clientID := args[0]
|
||||
|
||||
c, err := sdk.IssueCert(cmd.Context(), clientID, ttl, args[1], args[2])
|
||||
if err != nil {
|
||||
logErrorCmd(*cmd, err)
|
||||
return
|
||||
}
|
||||
logJSONCmd(*cmd, c)
|
||||
},
|
||||
}
|
||||
|
||||
issueCmd.Flags().StringVar(&ttl, "ttl", "8760h", "certificate time to live in duration")
|
||||
|
||||
cmd := cobra.Command{
|
||||
Use: "certs [issue | get | revoke ]",
|
||||
Short: "Certificates management",
|
||||
Long: `Certificates management: issue, get or revoke certificates for clients"`,
|
||||
}
|
||||
|
||||
cmdCerts = append(cmdCerts, issueCmd)
|
||||
|
||||
for i := range cmdCerts {
|
||||
cmd.AddCommand(&cmdCerts[i])
|
||||
}
|
||||
|
||||
return &cmd
|
||||
}
|
||||
@@ -1,341 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/supermq/cli"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
svcerr "github.com/absmach/supermq/pkg/errors/service"
|
||||
mgsdk "github.com/absmach/supermq/pkg/sdk"
|
||||
sdkmocks "github.com/absmach/supermq/pkg/sdk/mocks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
var cert = mgsdk.Cert{
|
||||
ClientID: client.ID,
|
||||
}
|
||||
|
||||
func TestGetCertCmd(t *testing.T) {
|
||||
sdkMock := new(sdkmocks.SDK)
|
||||
cli.SetSDK(sdkMock)
|
||||
certCmd := cli.NewCertsCmd()
|
||||
rootCmd := setFlags(certCmd)
|
||||
|
||||
var ct mgsdk.Cert
|
||||
var cts mgsdk.CertSerials
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
args []string
|
||||
sdkErr errors.SDKError
|
||||
errLogMessage string
|
||||
logType outputLog
|
||||
serials mgsdk.CertSerials
|
||||
cert mgsdk.Cert
|
||||
}{
|
||||
{
|
||||
desc: "get cert successfully",
|
||||
args: []string{
|
||||
"client",
|
||||
client.ID,
|
||||
domainID,
|
||||
validToken,
|
||||
},
|
||||
logType: entityLog,
|
||||
serials: mgsdk.CertSerials{
|
||||
PageRes: mgsdk.PageRes{
|
||||
Total: 1,
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
},
|
||||
Certs: []mgsdk.Cert{cert},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "get cert successfully by id",
|
||||
args: []string{
|
||||
client.ID,
|
||||
domainID,
|
||||
validToken,
|
||||
},
|
||||
logType: entityLog,
|
||||
cert: cert,
|
||||
},
|
||||
{
|
||||
desc: "get cert with invalid token",
|
||||
args: []string{
|
||||
"client",
|
||||
client.ID,
|
||||
domainID,
|
||||
invalidToken,
|
||||
},
|
||||
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized),
|
||||
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized)),
|
||||
logType: errLog,
|
||||
},
|
||||
{
|
||||
desc: "get cert by id with invalid token",
|
||||
args: []string{
|
||||
client.ID,
|
||||
domainID,
|
||||
invalidToken,
|
||||
},
|
||||
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized),
|
||||
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusUnauthorized)),
|
||||
logType: errLog,
|
||||
},
|
||||
{
|
||||
desc: "get cert with invalid args",
|
||||
args: []string{
|
||||
client.ID,
|
||||
},
|
||||
logType: usageLog,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
sdkCall := sdkMock.On("ViewCertByClient", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.serials, tc.sdkErr)
|
||||
sdkCall1 := sdkMock.On("ViewCert", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.cert, tc.sdkErr)
|
||||
out := executeCommand(t, rootCmd, append([]string{getCmd}, tc.args...)...)
|
||||
switch tc.logType {
|
||||
case entityLog:
|
||||
if tc.args[1] == "client" {
|
||||
err := json.Unmarshal([]byte(out), &cts)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, tc.serials, cts, fmt.Sprintf("%s unexpected response: expected: %v, got: %v", tc.desc, tc.serials, cts))
|
||||
} else {
|
||||
err := json.Unmarshal([]byte(out), &ct)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, tc.cert, ct, fmt.Sprintf("%s unexpected response: expected: %v, got: %v", tc.desc, tc.cert, ct))
|
||||
}
|
||||
|
||||
case errLog:
|
||||
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
|
||||
case usageLog:
|
||||
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
|
||||
}
|
||||
sdkCall.Unset()
|
||||
sdkCall1.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRevokeAllCertCmd(t *testing.T) {
|
||||
sdkMock := new(sdkmocks.SDK)
|
||||
cli.SetSDK(sdkMock)
|
||||
certCmd := cli.NewCertsCmd()
|
||||
rootCmd := setFlags(certCmd)
|
||||
|
||||
revokeTime := time.Now()
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
args []string
|
||||
sdkErr errors.SDKError
|
||||
logType outputLog
|
||||
errLogMessage string
|
||||
time time.Time
|
||||
response string
|
||||
}{
|
||||
{
|
||||
desc: "revoke cert successfully",
|
||||
args: []string{
|
||||
client.ID,
|
||||
domainID,
|
||||
token,
|
||||
},
|
||||
logType: revokeLog,
|
||||
response: fmt.Sprintf("\nrevoked: %s\n\n", revokeTime),
|
||||
time: revokeTime,
|
||||
},
|
||||
{
|
||||
desc: "revoke cert with invalid args",
|
||||
args: []string{
|
||||
client.ID,
|
||||
domainID,
|
||||
token,
|
||||
extraArg,
|
||||
},
|
||||
logType: usageLog,
|
||||
},
|
||||
{
|
||||
desc: "revoke cert with invalid token",
|
||||
args: []string{
|
||||
client.ID,
|
||||
domainID,
|
||||
invalidToken,
|
||||
},
|
||||
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
|
||||
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
|
||||
logType: errLog,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
sdkCall := sdkMock.On("RevokeAllCerts", mock.Anything, tc.args[0], tc.args[1], tc.args[2]).Return(tc.time, tc.sdkErr)
|
||||
out := executeCommand(t, rootCmd, append([]string{revokeAllCmd}, tc.args...)...)
|
||||
|
||||
switch tc.logType {
|
||||
case revokeLog:
|
||||
assert.Equal(t, tc.response, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.response, out))
|
||||
case errLog:
|
||||
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
|
||||
case usageLog:
|
||||
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
|
||||
}
|
||||
sdkCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRevokeCertCmd(t *testing.T) {
|
||||
sdkMock := new(sdkmocks.SDK)
|
||||
cli.SetSDK(sdkMock)
|
||||
certCmd := cli.NewCertsCmd()
|
||||
rootCmd := setFlags(certCmd)
|
||||
|
||||
revokeTime := time.Now()
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
args []string
|
||||
sdkErr errors.SDKError
|
||||
logType outputLog
|
||||
errLogMessage string
|
||||
time time.Time
|
||||
response string
|
||||
}{
|
||||
{
|
||||
desc: "revoke cert successfully",
|
||||
args: []string{
|
||||
cert.SerialNumber,
|
||||
domainID,
|
||||
token,
|
||||
},
|
||||
logType: revokeLog,
|
||||
response: fmt.Sprintf("\nrevoked: %s\n\n", revokeTime),
|
||||
time: revokeTime,
|
||||
},
|
||||
{
|
||||
desc: "revoke cert with invalid args",
|
||||
args: []string{
|
||||
cert.SerialNumber,
|
||||
domainID,
|
||||
token,
|
||||
extraArg,
|
||||
},
|
||||
logType: usageLog,
|
||||
},
|
||||
{
|
||||
desc: "revoke cert with invalid token",
|
||||
args: []string{
|
||||
cert.SerialNumber,
|
||||
domainID,
|
||||
invalidToken,
|
||||
},
|
||||
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
|
||||
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
|
||||
logType: errLog,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
sdkCall := sdkMock.On("RevokeCert", mock.Anything, tc.args[0], tc.args[1], tc.args[2]).Return(tc.time, tc.sdkErr)
|
||||
out := executeCommand(t, rootCmd, append([]string{revokeCmd}, tc.args...)...)
|
||||
|
||||
switch tc.logType {
|
||||
case revokeLog:
|
||||
assert.Equal(t, tc.response, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.response, out))
|
||||
case errLog:
|
||||
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
|
||||
case usageLog:
|
||||
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
|
||||
}
|
||||
sdkCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssueCertCmd(t *testing.T) {
|
||||
sdkMock := new(sdkmocks.SDK)
|
||||
cli.SetSDK(sdkMock)
|
||||
certCmd := cli.NewCertsCmd()
|
||||
rootCmd := setFlags(certCmd)
|
||||
|
||||
cert := mgsdk.Cert{
|
||||
SerialNumber: "serial",
|
||||
}
|
||||
|
||||
var cs mgsdk.Cert
|
||||
cases := []struct {
|
||||
desc string
|
||||
args []string
|
||||
logType outputLog
|
||||
errLogMessage string
|
||||
sdkErr errors.SDKError
|
||||
cert mgsdk.Cert
|
||||
}{
|
||||
{
|
||||
desc: "issue cert successfully",
|
||||
args: []string{
|
||||
client.ID,
|
||||
domainID,
|
||||
validToken,
|
||||
},
|
||||
cert: cert,
|
||||
logType: entityLog,
|
||||
},
|
||||
{
|
||||
desc: "issue cert with invalid args",
|
||||
args: []string{
|
||||
client.ID,
|
||||
domainID,
|
||||
validToken,
|
||||
extraArg,
|
||||
},
|
||||
logType: usageLog,
|
||||
},
|
||||
{
|
||||
desc: "issue cert with invalid token",
|
||||
args: []string{
|
||||
client.ID,
|
||||
domainID,
|
||||
invalidToken,
|
||||
},
|
||||
logType: errLog,
|
||||
sdkErr: errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden),
|
||||
errLogMessage: fmt.Sprintf("\nerror: %s\n\n", errors.NewSDKErrorWithStatus(svcerr.ErrAuthorization, http.StatusForbidden)),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
sdkCall := sdkMock.On("IssueCert", mock.Anything, mock.Anything, mock.Anything, tc.args[1], tc.args[2]).Return(tc.cert, tc.sdkErr)
|
||||
out := executeCommand(t, rootCmd, append([]string{issueCmd}, tc.args...)...)
|
||||
|
||||
switch tc.logType {
|
||||
case usageLog:
|
||||
assert.False(t, strings.Contains(out, rootCmd.Use), fmt.Sprintf("%s invalid usage: %s", tc.desc, out))
|
||||
case errLog:
|
||||
assert.Equal(t, tc.errLogMessage, out, fmt.Sprintf("%s unexpected error response: expected %s got errLogMessage:%s", tc.desc, tc.errLogMessage, out))
|
||||
case entityLog:
|
||||
err := json.Unmarshal([]byte(out), &cs)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, tc.cert, cs, fmt.Sprintf("%s unexpected response: expected: %v, got: %v", tc.desc, tc.cert, cs))
|
||||
}
|
||||
sdkCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -31,13 +31,6 @@ const (
|
||||
usersCmd = "users"
|
||||
)
|
||||
|
||||
// Certs commands
|
||||
const (
|
||||
revokeCmd = "revoke"
|
||||
revokeAllCmd = "revoke-all"
|
||||
issueCmd = "issue"
|
||||
)
|
||||
|
||||
// Messages commands
|
||||
const sendCmd = "send"
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ const (
|
||||
defDomainsURL string = defURL + ":9003"
|
||||
defChannelsURL string = defURL + ":9005"
|
||||
defGroupsURL string = defURL + ":9004"
|
||||
defCertsURL string = defURL + ":9019"
|
||||
defHTTPURL string = defURL + ":8008"
|
||||
defJournalURL string = defURL + ":9021"
|
||||
defTLSVerification bool = false
|
||||
@@ -111,7 +110,6 @@ func ParseConfig(sdkConf smqsdk.Config) (smqsdk.Config, error) {
|
||||
ChannelsURL: defChannelsURL,
|
||||
GroupsURL: defGroupsURL,
|
||||
HTTPAdapterURL: defHTTPURL,
|
||||
CertsURL: defCertsURL,
|
||||
JournalURL: defJournalURL,
|
||||
HostURL: defURL,
|
||||
TLSVerification: defTLSVerification,
|
||||
|
||||
@@ -6,7 +6,6 @@ package cli
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/hokaccha/go-prettyjson"
|
||||
@@ -77,14 +76,6 @@ func logOKCmd(cmd cobra.Command) {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "\n%s\n\n", color.BlueString("ok"))
|
||||
}
|
||||
|
||||
func logRevokedTimeCmd(cmd cobra.Command, t time.Time) {
|
||||
if RawOutput {
|
||||
fmt.Fprintln(cmd.OutOrStdout(), t)
|
||||
} else {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), color.BlueString("\nrevoked: %v\n\n"), t)
|
||||
}
|
||||
}
|
||||
|
||||
func convertMetadata(m string) (map[string]any, error) {
|
||||
var metadata map[string]any
|
||||
if m == "" {
|
||||
|
||||
Reference in New Issue
Block a user