Added KeyExtractionFunc for all commands and sub commands to extract keys for ACL authorization.

Deleted genpass command.
This commit is contained in:
Kelvin Clement Mwinuka
2023-12-13 22:09:14 +08:00
parent 5f39a64a8d
commit 42c145ef3c
8 changed files with 218 additions and 32 deletions

View File

@@ -51,8 +51,6 @@ func (p Plugin) HandleCommand(ctx context.Context, cmd []string, server utils.Se
return p.handleDelUser(ctx, cmd, server)
case "whoami":
return p.handleWhoAmI(ctx, cmd, server)
case "genpass":
return p.handleGenPass(ctx, cmd, server)
case "list":
return p.handleList(ctx, cmd, server)
case "load":
@@ -92,10 +90,6 @@ func (p Plugin) handleWhoAmI(ctx context.Context, cmd []string, server utils.Ser
return nil, errors.New("ACL WHOAMI not implemented")
}
func (p Plugin) handleGenPass(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("ACL GENPASS not implemented")
}
func (p Plugin) handleList(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("ACL LIST not implemented")
}
@@ -117,75 +111,98 @@ func NewModule(acl *ACL) Plugin {
{
Command: "auth",
Categories: []string{},
Description: "Authenticates the connection",
Description: "(AUTH [username] password) Authenticates the connection",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
{
Command: "acl",
Categories: []string{},
Description: "List all the categories and commands inside a category",
Description: "Access-Control-List commands",
Sync: false,
SubCommands: []utils.SubCommand{
{
Command: "cat",
Categories: []string{},
Description: "List all the categories and commands inside a category",
Description: "(ACL CAT) List all the categories and commands inside a category.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
{
Command: "users",
Categories: []string{},
Description: "List all ACL users",
Description: "(ACL LIST) List all ACL users",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
{
Command: "setuser",
Categories: []string{},
Description: "Configure a new or existing user",
Description: "(ACL SETUSER) Configure a new or existing user",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
{
Command: "getuser",
Categories: []string{},
Description: "List the ACL rules of a user",
Description: "(ACL GETUSER) List the ACL rules of a user",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
{
Command: "deluser",
Categories: []string{},
Description: "Deletes users and terminates their connections",
Description: "(ACL DELUSER) Deletes users and terminates their connections",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
{
Command: "whoami",
Categories: []string{},
Description: "Returns the authenticated user of the current connection",
Description: "(ACL WHOAMI) Returns the authenticated user of the current connection",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
{
Command: "genpass",
Categories: []string{},
Description: "Generates a password that can be used to identify a user",
Sync: true,
},
{
Command: "list",
Categories: []string{},
Description: "Dumps effective acl rules in acl config file format",
Description: "(ACL LIST) Dumps effective acl rules in acl config file format",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
{
Command: "load",
Categories: []string{},
Description: "Reloads the rules from the configured ACL config file",
Description: "(ACL LOAD) Reloads the rules from the configured ACL config file",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
{
Command: "save",
Categories: []string{},
Description: "Saves the effective ACL rules the configured ACL config file",
Description: "(ACL SAVE) Saves the effective ACL rules the configured ACL config file",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
},
},

View File

@@ -160,18 +160,42 @@ func NewModule() Plugin {
Categories: []string{},
Description: "(SET key value) Set the value of a key, considering the value's type.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 3 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "setnx",
Categories: []string{},
Description: "(SETNX key value) Set the key/value only if the key doesn't exist.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 3 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "mset",
Categories: []string{},
Description: "(MSET key value [key value ...]) Automatically etc or modify multiple key/value pairs.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd[1:])%2 != 0 {
return nil, errors.New("each key must be paired with a value")
}
var keys []string
for i, key := range cmd[1:] {
if i%2 == 0 {
keys = append(keys, key)
}
}
return keys, nil
},
},
},
description: "Handle basic SET commands",

View File

@@ -99,14 +99,26 @@ func NewModule() Plugin {
{
Command: "get",
Categories: []string{},
Description: "",
Description: "(GET key) Get the value at the specified key.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 2 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "mget",
Categories: []string{},
Description: "",
Description: "(MGET key1 [key2]) Get multiple values from the specified keys.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New("wrong number of arguments")
}
return cmd[1:], nil
},
},
},
description: "Handle basic GET and MGET commands",

View File

@@ -511,78 +511,156 @@ func NewModule() Plugin {
Categories: []string{},
Description: "(LPUSH key value1 [value2]) Prepends one or more values to the beginning of a list, creates the list if it does not exist.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "lpushx",
Categories: []string{},
Description: "(LPUSHX key value) Prepends a value to the beginning of a list only if the list exists.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 3 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "lpop",
Categories: []string{},
Description: "(LPOP key) Removes and returns the first element of a list.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 2 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "llen",
Categories: []string{},
Description: "(LLEN key) Return the length of a list.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 2 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "lrange",
Categories: []string{},
Description: "(LRANGE key start end) Return a range of elements between the given indices.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "lindex",
Categories: []string{},
Description: "(LINDEX key index) Gets list element by index.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 3 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "lset",
Categories: []string{},
Description: "(LSET key index value) Sets the value of an element in a list by its index.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "ltrim",
Categories: []string{},
Description: "(LTRIM key start end) Trims a list to the specified range.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "lrem",
Categories: []string{},
Description: "(LREM key count value) Remove elements from list.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "lmove",
Categories: []string{},
Description: "(LMOVE source destination <LEFT | RIGHT> <LEFT | RIGHT> Move element from one list to the other specifying left/right for both lists.",
Description: "(LMOVE source destination <LEFT | RIGHT> <LEFT | RIGHT>) Move element from one list to the other specifying left/right for both lists.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 5 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1], cmd[2]}, nil
},
},
{
Command: "rpop",
Categories: []string{},
Description: "(RPOP key) Removes and gets the last element in a list.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 2 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "rpush",
Categories: []string{},
Description: "(RPUSH key value [value2]) Appends one or multiple elements to the end of a list.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "rpushx",
Categories: []string{},
Description: "(RPUSHX key value) Appends an element to the end of a list, only if the list exists.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 3 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
},
description: "Handle List commands",

View File

@@ -61,14 +61,20 @@ func NewModule() Plugin {
{
Command: "ping",
Categories: []string{},
Description: "",
Description: "(PING [value]) Ping the server. If a value is provided, the value will be echoed.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
{
Command: "ack",
Categories: []string{},
Description: "",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
},
},
description: "Handle PING command",

View File

@@ -97,23 +97,44 @@ func NewModule(pubsub *PubSub) Plugin {
{
Command: "publish",
Categories: []string{},
Description: "",
Description: "(PUBLISH channel message) Publish a message to the specified channel.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
// Treat the channel as a key
if len(cmd) != 3 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "subscribe",
Categories: []string{},
Description: "",
Description: "(SUBSCRIBE channel [consumer_group]) Subscribe to a channel with an option to join a consumer group on the channel.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
// Treat the channel as a key
if len(cmd) < 2 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "unsubscribe",
Categories: []string{},
Description: "",
Description: "(UNSUBSCRIBE channel) Unsubscribe from a channel.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
// Treat the channel as a key
if len(cmd) != 2 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
description: "Handle PUBSUB functionality",
},
description: "Handle PUBSUB feature",
}
return PubSubModule
}

View File

@@ -207,24 +207,48 @@ func NewModule() Plugin {
Categories: []string{},
Description: "(SETRANGE key offset value) Overwrites part of a string value with another by offset. Creates the key if it doesn't exist.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "strlen",
Categories: []string{},
Description: "(STRLEN key) Returns length of the key's value if it's a string.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 2 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "substr",
Categories: []string{},
Description: "(SUBSTR key start end) Returns a substring from the string value.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "getrange",
Categories: []string{},
Description: "(GETRANGE key start end) Returns a substring from the string value.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
},
description: "Handle basic STRING commands",

View File

@@ -35,11 +35,14 @@ type ApplyResponse struct {
Response []byte
}
type KeyExtractionFunc func(cmd []string) ([]string, error)
type SubCommand struct {
Command string
Categories []string
Description string
Sync bool // Specifies if sub-command should be synced across cluster
KeyExtractionFunc
}
type Command struct {
@@ -48,6 +51,7 @@ type Command struct {
Description string
SubCommands []SubCommand
Sync bool // Specifies if command should be synced across cluster
KeyExtractionFunc
}
type Plugin interface {