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) return p.handleDelUser(ctx, cmd, server)
case "whoami": case "whoami":
return p.handleWhoAmI(ctx, cmd, server) return p.handleWhoAmI(ctx, cmd, server)
case "genpass":
return p.handleGenPass(ctx, cmd, server)
case "list": case "list":
return p.handleList(ctx, cmd, server) return p.handleList(ctx, cmd, server)
case "load": 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") 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) { func (p Plugin) handleList(ctx context.Context, cmd []string, server utils.Server) ([]byte, error) {
return nil, errors.New("ACL LIST not implemented") return nil, errors.New("ACL LIST not implemented")
} }
@@ -117,75 +111,98 @@ func NewModule(acl *ACL) Plugin {
{ {
Command: "auth", Command: "auth",
Categories: []string{}, Categories: []string{},
Description: "Authenticates the connection", Description: "(AUTH [username] password) Authenticates the connection",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
{ {
Command: "acl", Command: "acl",
Categories: []string{}, Categories: []string{},
Description: "List all the categories and commands inside a category", Description: "Access-Control-List commands",
Sync: false, Sync: false,
SubCommands: []utils.SubCommand{ SubCommands: []utils.SubCommand{
{ {
Command: "cat", Command: "cat",
Categories: []string{}, 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, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
{ {
Command: "users", Command: "users",
Categories: []string{}, Categories: []string{},
Description: "List all ACL users", Description: "(ACL LIST) List all ACL users",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
{ {
Command: "setuser", Command: "setuser",
Categories: []string{}, Categories: []string{},
Description: "Configure a new or existing user", Description: "(ACL SETUSER) Configure a new or existing user",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
{ {
Command: "getuser", Command: "getuser",
Categories: []string{}, Categories: []string{},
Description: "List the ACL rules of a user", Description: "(ACL GETUSER) List the ACL rules of a user",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
{ {
Command: "deluser", Command: "deluser",
Categories: []string{}, Categories: []string{},
Description: "Deletes users and terminates their connections", Description: "(ACL DELUSER) Deletes users and terminates their connections",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
{ {
Command: "whoami", Command: "whoami",
Categories: []string{}, Categories: []string{},
Description: "Returns the authenticated user of the current connection", Description: "(ACL WHOAMI) Returns the authenticated user of the current connection",
Sync: true,
},
{
Command: "genpass",
Categories: []string{},
Description: "Generates a password that can be used to identify a user",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
{ {
Command: "list", Command: "list",
Categories: []string{}, 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, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
{ {
Command: "load", Command: "load",
Categories: []string{}, 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, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
{ {
Command: "save", Command: "save",
Categories: []string{}, 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, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
}, },
}, },
}, },

View File

@@ -160,18 +160,42 @@ func NewModule() Plugin {
Categories: []string{}, Categories: []string{},
Description: "(SET key value) Set the value of a key, considering the value's type.", Description: "(SET key value) Set the value of a key, considering the value's type.",
Sync: true, 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", Command: "setnx",
Categories: []string{}, Categories: []string{},
Description: "(SETNX key value) Set the key/value only if the key doesn't exist.", Description: "(SETNX key value) Set the key/value only if the key doesn't exist.",
Sync: true, 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", Command: "mset",
Categories: []string{}, Categories: []string{},
Description: "(MSET key value [key value ...]) Automatically etc or modify multiple key/value pairs.", Description: "(MSET key value [key value ...]) Automatically etc or modify multiple key/value pairs.",
Sync: true, 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", description: "Handle basic SET commands",

View File

@@ -99,14 +99,26 @@ func NewModule() Plugin {
{ {
Command: "get", Command: "get",
Categories: []string{}, Categories: []string{},
Description: "", Description: "(GET key) Get the value at the specified key.",
Sync: false, 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", Command: "mget",
Categories: []string{}, Categories: []string{},
Description: "", Description: "(MGET key1 [key2]) Get multiple values from the specified keys.",
Sync: true, 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", description: "Handle basic GET and MGET commands",

View File

@@ -511,78 +511,156 @@ func NewModule() Plugin {
Categories: []string{}, 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.", 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, 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", Command: "lpushx",
Categories: []string{}, Categories: []string{},
Description: "(LPUSHX key value) Prepends a value to the beginning of a list only if the list exists.", Description: "(LPUSHX key value) Prepends a value to the beginning of a list only if the list exists.",
Sync: true, 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", Command: "lpop",
Categories: []string{}, Categories: []string{},
Description: "(LPOP key) Removes and returns the first element of a list.", Description: "(LPOP key) Removes and returns the first element of a list.",
Sync: true, 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", Command: "llen",
Categories: []string{}, Categories: []string{},
Description: "(LLEN key) Return the length of a list.", Description: "(LLEN key) Return the length of a list.",
Sync: true, 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", Command: "lrange",
Categories: []string{}, Categories: []string{},
Description: "(LRANGE key start end) Return a range of elements between the given indices.", Description: "(LRANGE key start end) Return a range of elements between the given indices.",
Sync: true, 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", Command: "lindex",
Categories: []string{}, Categories: []string{},
Description: "(LINDEX key index) Gets list element by index.", Description: "(LINDEX key index) Gets list element by index.",
Sync: true, 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", Command: "lset",
Categories: []string{}, Categories: []string{},
Description: "(LSET key index value) Sets the value of an element in a list by its index.", Description: "(LSET key index value) Sets the value of an element in a list by its index.",
Sync: true, 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", Command: "ltrim",
Categories: []string{}, Categories: []string{},
Description: "(LTRIM key start end) Trims a list to the specified range.", Description: "(LTRIM key start end) Trims a list to the specified range.",
Sync: true, 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", Command: "lrem",
Categories: []string{}, Categories: []string{},
Description: "(LREM key count value) Remove elements from list.", Description: "(LREM key count value) Remove elements from list.",
Sync: true, 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", Command: "lmove",
Categories: []string{}, 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, 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", Command: "rpop",
Categories: []string{}, Categories: []string{},
Description: "(RPOP key) Removes and gets the last element in a list.", Description: "(RPOP key) Removes and gets the last element in a list.",
Sync: true, 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", Command: "rpush",
Categories: []string{}, Categories: []string{},
Description: "(RPUSH key value [value2]) Appends one or multiple elements to the end of a list.", Description: "(RPUSH key value [value2]) Appends one or multiple elements to the end of a list.",
Sync: true, 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", Command: "rpushx",
Categories: []string{}, Categories: []string{},
Description: "(RPUSHX key value) Appends an element to the end of a list, only if the list exists.", Description: "(RPUSHX key value) Appends an element to the end of a list, only if the list exists.",
Sync: true, 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", description: "Handle List commands",

View File

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

View File

@@ -97,23 +97,44 @@ func NewModule(pubsub *PubSub) Plugin {
{ {
Command: "publish", Command: "publish",
Categories: []string{}, Categories: []string{},
Description: "", Description: "(PUBLISH channel message) Publish a message to the specified channel.",
Sync: true, 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", Command: "subscribe",
Categories: []string{}, 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, 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", Command: "unsubscribe",
Categories: []string{}, Categories: []string{},
Description: "", Description: "(UNSUBSCRIBE channel) Unsubscribe from a channel.",
Sync: false, 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 return PubSubModule
} }

View File

@@ -207,24 +207,48 @@ func NewModule() Plugin {
Categories: []string{}, 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.", 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, 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", Command: "strlen",
Categories: []string{}, Categories: []string{},
Description: "(STRLEN key) Returns length of the key's value if it's a string.", Description: "(STRLEN key) Returns length of the key's value if it's a string.",
Sync: false, 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", Command: "substr",
Categories: []string{}, Categories: []string{},
Description: "(SUBSTR key start end) Returns a substring from the string value.", Description: "(SUBSTR key start end) Returns a substring from the string value.",
Sync: false, 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", Command: "getrange",
Categories: []string{}, Categories: []string{},
Description: "(GETRANGE key start end) Returns a substring from the string value.", Description: "(GETRANGE key start end) Returns a substring from the string value.",
Sync: false, 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", description: "Handle basic STRING commands",

View File

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