SMQ-3108 - Add support for public and private metadata for users and clients (#3155)

Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
This commit is contained in:
Felix Gateru
2026-01-22 10:55:25 +03:00
committed by GitHub
parent 9293de7636
commit 5b913dd46b
40 changed files with 1045 additions and 533 deletions
+5
View File
@@ -95,6 +95,11 @@ func ToClient(data map[string]any) (clients.Client, error) {
c.Metadata = meta
}
pmeta, ok := data["public_metadata"].(map[string]any)
if ok {
c.PublicMetadata = pmeta
}
uby, ok := data["updated_by"].(string)
if ok {
c.UpdatedBy = uby
+14 -13
View File
@@ -27,19 +27,20 @@ const (
// Client represents supermq client.
type Client struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Tags []string `json:"tags,omitempty"`
DomainID string `json:"domain_id,omitempty"`
ParentGroup string `json:"parent_group_id,omitempty"`
Credentials ClientCredentials `json:"credentials"`
Metadata map[string]any `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
UpdatedBy string `json:"updated_by,omitempty"`
Status string `json:"status,omitempty"`
Permissions []string `json:"permissions,omitempty"`
Roles []roles.MemberRoleActions `json:"roles,omitempty"`
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Tags []string `json:"tags,omitempty"`
DomainID string `json:"domain_id,omitempty"`
ParentGroup string `json:"parent_group_id,omitempty"`
Credentials ClientCredentials `json:"credentials"`
Metadata map[string]any `json:"metadata,omitempty"`
PublicMetadata map[string]any `json:"public_metadata,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
UpdatedBy string `json:"updated_by,omitempty"`
Status string `json:"status,omitempty"`
Permissions []string `json:"permissions,omitempty"`
Roles []roles.MemberRoleActions `json:"roles,omitempty"`
}
type ClientCredentials struct {
+43 -39
View File
@@ -51,11 +51,12 @@ func TestCreateClient(t *testing.T) {
client := generateTestClient(t, false)
createClientReq := sdk.Client{
Name: client.Name,
Tags: client.Tags,
Credentials: client.Credentials,
Metadata: client.Metadata,
Status: client.Status,
Name: client.Name,
Tags: client.Tags,
Credentials: client.Credentials,
Metadata: client.Metadata,
PublicMetadata: client.PublicMetadata,
Status: client.Status,
}
conf := sdk.Config{
@@ -126,11 +127,12 @@ func TestCreateClient(t *testing.T) {
domainID: domainID,
token: validToken,
createClientReq: sdk.Client{
Name: strings.Repeat("a", 1025),
Tags: client.Tags,
Credentials: client.Credentials,
Metadata: client.Metadata,
Status: client.Status,
Name: strings.Repeat("a", 1025),
Tags: client.Tags,
Credentials: client.Credentials,
PublicMetadata: client.PublicMetadata,
Metadata: client.Metadata,
Status: client.Status,
},
svcReq: clients.Client{},
svcRes: []clients.Client{},
@@ -143,12 +145,13 @@ func TestCreateClient(t *testing.T) {
domainID: domainID,
token: validToken,
createClientReq: sdk.Client{
ID: "123456789",
Name: client.Name,
Tags: client.Tags,
Credentials: client.Credentials,
Metadata: client.Metadata,
Status: client.Status,
ID: "123456789",
Name: client.Name,
Tags: client.Tags,
Credentials: client.Credentials,
PublicMetadata: client.PublicMetadata,
Metadata: client.Metadata,
Status: client.Status,
},
svcReq: clients.Client{},
svcRes: []clients.Client{},
@@ -162,7 +165,7 @@ func TestCreateClient(t *testing.T) {
token: validToken,
createClientReq: sdk.Client{
Name: valid,
Metadata: map[string]any{
PublicMetadata: map[string]any{
valid: make(chan int),
},
},
@@ -182,7 +185,7 @@ func TestCreateClient(t *testing.T) {
Name: client.Name,
Tags: client.Tags,
Credentials: clients.Credentials(client.Credentials),
Metadata: clients.Metadata{
PublicMetadata: clients.Metadata{
"test": make(chan int),
},
}},
@@ -276,7 +279,7 @@ func TestCreateClients(t *testing.T) {
desc: "create new clients with a request that can't be marshalled",
domainID: domainID,
token: validToken,
createClientsRequest: []sdk.Client{{Name: "test", Metadata: map[string]any{"test": make(chan int)}}},
createClientsRequest: []sdk.Client{{Name: "test", PublicMetadata: map[string]any{"test": make(chan int)}}},
svcReq: convertClients(sdkClients...),
svcRes: []clients.Client{},
svcErr: nil,
@@ -293,7 +296,7 @@ func TestCreateClients(t *testing.T) {
Name: sdkClients[0].Name,
Tags: sdkClients[0].Tags,
Credentials: clients.Credentials(sdkClients[0].Credentials),
Metadata: clients.Metadata{
PublicMetadata: clients.Metadata{
"test": make(chan int),
},
}},
@@ -559,7 +562,7 @@ func TestListClients(t *testing.T) {
Name: sdkClients[0].Name,
Tags: sdkClients[0].Tags,
Credentials: clients.Credentials(sdkClients[0].Credentials),
Metadata: clients.Metadata{
PublicMetadata: clients.Metadata{
"test": make(chan int),
},
}},
@@ -695,7 +698,7 @@ func TestViewClient(t *testing.T) {
Name: sdkClient.Name,
Tags: sdkClient.Tags,
Credentials: clients.Credentials(sdkClient.Credentials),
Metadata: clients.Metadata{
PublicMetadata: clients.Metadata{
"test": make(chan int),
},
},
@@ -742,13 +745,13 @@ func TestUpdateClient(t *testing.T) {
sdkClient := generateTestClient(t, false)
updatedClient := sdkClient
updatedClient.Name = "newName"
updatedClient.Metadata = map[string]any{
updatedClient.PublicMetadata = map[string]any{
"newKey": "newValue",
}
updateClientReq := sdk.Client{
ID: sdkClient.ID,
Name: updatedClient.Name,
Metadata: updatedClient.Metadata,
ID: sdkClient.ID,
Name: updatedClient.Name,
PublicMetadata: updatedClient.PublicMetadata,
}
conf := sdk.Config{
@@ -844,7 +847,7 @@ func TestUpdateClient(t *testing.T) {
updateClientReq: sdk.Client{
ID: valid,
Metadata: map[string]any{
PublicMetadata: map[string]any{
"test": make(chan int),
},
},
@@ -864,7 +867,7 @@ func TestUpdateClient(t *testing.T) {
Name: updatedClient.Name,
Tags: updatedClient.Tags,
Credentials: clients.Credentials(updatedClient.Credentials),
Metadata: clients.Metadata{
PublicMetadata: clients.Metadata{
"test": make(chan int),
},
},
@@ -996,7 +999,7 @@ func TestUpdateClientTags(t *testing.T) {
token: validToken,
updateClientReq: sdk.Client{
ID: valid,
Metadata: map[string]any{
PublicMetadata: map[string]any{
"test": make(chan int),
},
},
@@ -1016,7 +1019,7 @@ func TestUpdateClientTags(t *testing.T) {
Name: updatedClient.Name,
Tags: updatedClient.Tags,
Credentials: clients.Credentials(updatedClient.Credentials),
Metadata: clients.Metadata{
PublicMetadata: clients.Metadata{
"test": make(chan int),
},
},
@@ -1148,7 +1151,7 @@ func TestUpdateClientSecret(t *testing.T) {
Name: updatedClient.Name,
Tags: updatedClient.Tags,
Credentials: clients.Credentials(updatedClient.Credentials),
Metadata: clients.Metadata{
PublicMetadata: clients.Metadata{
"test": make(chan int),
},
},
@@ -1251,7 +1254,7 @@ func TestEnableClient(t *testing.T) {
Name: enabledClient.Name,
Tags: enabledClient.Tags,
Credentials: clients.Credentials(enabledClient.Credentials),
Metadata: clients.Metadata{
PublicMetadata: clients.Metadata{
"test": make(chan int),
},
},
@@ -1354,7 +1357,7 @@ func TestDisableClient(t *testing.T) {
Name: disabledClient.Name,
Tags: disabledClient.Tags,
Credentials: clients.Credentials(disabledClient.Credentials),
Metadata: clients.Metadata{
PublicMetadata: clients.Metadata{
"test": make(chan int),
},
},
@@ -3268,11 +3271,12 @@ func generateTestClient(t *testing.T, withRoles bool) sdk.Client {
Identity: "client@example.com",
Secret: generateUUID(t),
},
Tags: []string{"tag1", "tag2"},
Metadata: validMetadata,
Status: clients.EnabledStatus.String(),
CreatedAt: createdAt,
UpdatedAt: updatedAt,
Roles: rl,
Tags: []string{"tag1", "tag2"},
Metadata: validMetadata,
PublicMetadata: validMetadata,
Status: clients.EnabledStatus.String(),
CreatedAt: createdAt,
UpdatedAt: updatedAt,
Roles: rl,
}
}
+21 -18
View File
@@ -172,6 +172,7 @@ func convertUser(c sdk.User) users.User {
Email: c.Email,
Credentials: users.Credentials(c.Credentials),
Metadata: users.Metadata(c.Metadata),
PublicMetadata: users.Metadata(c.PublicMetadata),
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
Status: status,
@@ -189,18 +190,19 @@ func convertClient(c sdk.Client) clients.Client {
return clients.Client{}
}
return clients.Client{
ID: c.ID,
Name: c.Name,
Tags: c.Tags,
Domain: c.DomainID,
ParentGroup: c.ParentGroup,
Credentials: clients.Credentials(c.Credentials),
Metadata: clients.Metadata(c.Metadata),
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
UpdatedBy: c.UpdatedBy,
Status: status,
Roles: c.Roles,
ID: c.ID,
Name: c.Name,
Tags: c.Tags,
Domain: c.DomainID,
ParentGroup: c.ParentGroup,
Credentials: clients.Credentials(c.Credentials),
Metadata: clients.Metadata(c.Metadata),
PublicMetadata: clients.Metadata(c.PublicMetadata),
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
UpdatedBy: c.UpdatedBy,
Status: status,
Roles: c.Roles,
}
}
@@ -265,12 +267,13 @@ func generateTestUser(t *testing.T) sdk.User {
Username: "username",
Secret: secret,
},
Tags: []string{"tag1", "tag2"},
Metadata: validMetadata,
CreatedAt: createdAt,
UpdatedAt: createdAt,
Status: users.EnabledStatus.String(),
Role: users.UserRole.String(),
Tags: []string{"tag1", "tag2"},
Metadata: validMetadata,
PublicMetadata: validMetadata,
CreatedAt: createdAt,
UpdatedAt: createdAt,
Status: users.EnabledStatus.String(),
Role: users.UserRole.String(),
}
}
+1
View File
@@ -36,6 +36,7 @@ type User struct {
Credentials Credentials `json:"credentials"`
Tags []string `json:"tags,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
PublicMetadata Metadata `json:"public_metadata,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
Status string `json:"status,omitempty"`
+45 -40
View File
@@ -56,13 +56,14 @@ func TestCreateUser(t *testing.T) {
defer ts.Close()
createSdkUserReq := sdk.User{
FirstName: user.FirstName,
LastName: user.LastName,
Email: user.Email,
Tags: user.Tags,
Credentials: user.Credentials,
Metadata: user.Metadata,
Status: user.Status,
FirstName: user.FirstName,
LastName: user.LastName,
Email: user.Email,
Tags: user.Tags,
Credentials: user.Credentials,
Metadata: user.Metadata,
PublicMetadata: user.PublicMetadata,
Status: user.Status,
}
conf := sdk.Config{
@@ -142,10 +143,11 @@ func TestCreateUser(t *testing.T) {
desc: "register user with first name too long",
token: validToken,
createSdkUserReq: sdk.User{
FirstName: strings.Repeat("a", 1025),
Credentials: createSdkUserReq.Credentials,
Metadata: createSdkUserReq.Metadata,
Tags: createSdkUserReq.Tags,
FirstName: strings.Repeat("a", 1025),
Credentials: createSdkUserReq.Credentials,
PublicMetadata: createSdkUserReq.PublicMetadata,
Metadata: createSdkUserReq.Metadata,
Tags: createSdkUserReq.Tags,
},
svcReq: users.User{},
svcRes: users.User{},
@@ -164,8 +166,9 @@ func TestCreateUser(t *testing.T) {
Username: "",
Secret: createSdkUserReq.Credentials.Secret,
},
Metadata: createSdkUserReq.Metadata,
Tags: createSdkUserReq.Tags,
PublicMetadata: createSdkUserReq.PublicMetadata,
Metadata: createSdkUserReq.Metadata,
Tags: createSdkUserReq.Tags,
},
svcReq: users.User{},
svcRes: users.User{},
@@ -184,8 +187,9 @@ func TestCreateUser(t *testing.T) {
Username: createSdkUserReq.Credentials.Username,
Secret: "",
},
Metadata: createSdkUserReq.Metadata,
Tags: createSdkUserReq.Tags,
PublicMetadata: createSdkUserReq.PublicMetadata,
Metadata: createSdkUserReq.Metadata,
Tags: createSdkUserReq.Tags,
},
svcReq: users.User{},
svcRes: users.User{},
@@ -204,8 +208,9 @@ func TestCreateUser(t *testing.T) {
Username: createSdkUserReq.Credentials.Username,
Secret: "weak",
},
Metadata: createSdkUserReq.Metadata,
Tags: createSdkUserReq.Tags,
PublicMetadata: createSdkUserReq.PublicMetadata,
Metadata: createSdkUserReq.Metadata,
Tags: createSdkUserReq.Tags,
},
svcReq: users.User{},
svcRes: users.User{},
@@ -224,7 +229,7 @@ func TestCreateUser(t *testing.T) {
FirstName: createSdkUserReq.FirstName,
LastName: createSdkUserReq.LastName,
Email: createSdkUserReq.Email,
Metadata: map[string]any{
PublicMetadata: map[string]any{
"test": make(chan int),
},
},
@@ -248,7 +253,7 @@ func TestCreateUser(t *testing.T) {
Username: createSdkUserReq.Credentials.Username,
Secret: createSdkUserReq.Credentials.Secret,
},
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -290,9 +295,9 @@ func TestListUsers(t *testing.T) {
Username: fmt.Sprintf("Username_%d", i),
Secret: fmt.Sprintf("password_%d", i),
},
Metadata: sdk.Metadata{"name": fmt.Sprintf("user_%d", i)},
Status: users.EnabledStatus.String(),
Role: users.UserRole.String(),
PublicMetadata: sdk.Metadata{"name": fmt.Sprintf("user_%d", i)},
Status: users.EnabledStatus.String(),
Role: users.UserRole.String(),
}
if i == 50 {
cl.Status = users.DisabledStatus.String()
@@ -546,7 +551,7 @@ func TestListUsers(t *testing.T) {
{
ID: id,
FirstName: "user_99",
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -600,9 +605,9 @@ func TestSearchUsers(t *testing.T) {
Username: fmt.Sprintf("Username_%d", i),
Secret: fmt.Sprintf("password_%d", i),
},
Metadata: sdk.Metadata{"name": fmt.Sprintf("user_%d", i)},
Status: users.EnabledStatus.String(),
Role: users.UserRole.String(),
PublicMetadata: sdk.Metadata{"name": fmt.Sprintf("user_%d", i)},
Status: users.EnabledStatus.String(),
Role: users.UserRole.String(),
}
if i == 50 {
cl.Status = users.DisabledStatus.String()
@@ -782,7 +787,7 @@ func TestViewUser(t *testing.T) {
ID: id,
FirstName: user.FirstName,
LastName: user.LastName,
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -861,7 +866,7 @@ func TestUserProfile(t *testing.T) {
svcRes: users.User{
ID: id,
FirstName: user.FirstName,
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -1001,7 +1006,7 @@ func TestUpdateUser(t *testing.T) {
token: validToken,
updateUserReq: sdk.User{
ID: generateUUID(t),
Metadata: map[string]any{
PublicMetadata: map[string]any{
"test": make(chan int),
},
},
@@ -1025,7 +1030,7 @@ func TestUpdateUser(t *testing.T) {
svcRes: users.User{
ID: id,
FirstName: updatedName,
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -1162,7 +1167,7 @@ func TestUpdateUserTags(t *testing.T) {
token: validToken,
updateUserReq: sdk.User{
ID: generateUUID(t),
Metadata: map[string]any{
PublicMetadata: map[string]any{
"test": make(chan int),
},
},
@@ -1186,7 +1191,7 @@ func TestUpdateUserTags(t *testing.T) {
svcRes: users.User{
ID: id,
Tags: updatedTags,
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -1334,7 +1339,7 @@ func TestUpdateUserEmail(t *testing.T) {
svcRes: users.User{
ID: id,
FirstName: updatedEmail,
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -1630,7 +1635,7 @@ func TestUpdatePassword(t *testing.T) {
svcRes: users.User{
ID: id,
FirstName: user.FirstName,
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -1764,7 +1769,7 @@ func TestUpdateUserRole(t *testing.T) {
token: validToken,
updateUserReq: sdk.User{
ID: generateUUID(t),
Metadata: map[string]any{
PublicMetadata: map[string]any{
"test": make(chan int),
},
},
@@ -1788,7 +1793,7 @@ func TestUpdateUserRole(t *testing.T) {
svcRes: users.User{
ID: id,
Role: users.AdminRole,
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -1952,7 +1957,7 @@ func TestUpdateUsername(t *testing.T) {
Credentials: users.Credentials{
Username: updatedUsername,
},
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -2092,7 +2097,7 @@ func TestUpdateProfilePicture(t *testing.T) {
token: validToken,
updateUserReq: sdk.User{
ID: generateUUID(t),
Metadata: map[string]any{
PublicMetadata: map[string]any{
"test": make(chan int),
},
},
@@ -2115,7 +2120,7 @@ func TestUpdateProfilePicture(t *testing.T) {
},
svcRes: users.User{
ID: id,
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},
@@ -2293,7 +2298,7 @@ func TestDisableUser(t *testing.T) {
svcRes: users.User{
ID: id,
Status: users.DisabledStatus,
Metadata: users.Metadata{
PublicMetadata: users.Metadata{
"key": make(chan int),
},
},