Implemented ACL Init on server.

Implemented reading of ACL from JSON and YAML files into user list in memory.
This commit is contained in:
Kelvin Clement Mwinuka
2023-12-07 16:53:23 +08:00
parent 5ef457cec5
commit 1382ef494b
5 changed files with 96 additions and 3 deletions

3
.gitignore vendored
View File

@@ -1,7 +1,6 @@
.idea
bin
openssl
config*.json
config*.y*ml
docker-compose.y*ml
volumes
/config/

View File

@@ -7,6 +7,7 @@ RUN mkdir -p /etc/ssl/certs/memstore
COPY ./bin/linux/x86_64/plugins /usr/local/lib/memstore
COPY ./bin/linux/x86_64/server /opt/memstore/bin
COPY ./openssl/server /etc/ssl/certs/memstore
COPY ./config /etc/config/memstore
WORKDIR /opt/memstore/bin
@@ -24,4 +25,5 @@ CMD "./server" \
"--http=${HTTP}" \
"--tls=${TLS}" \
"--inMemory=${INMEMORY}" \
"--bootstrapCluster=${BOOTSTRAP_CLUSTER}" \
"--bootstrapCluster=${BOOTSTRAP_CLUSTER}" \
"--aclConfig=${ACL_CONFIG}" \

85
src/acl.go Normal file
View File

@@ -0,0 +1,85 @@
package main
import (
"encoding/json"
"fmt"
"gopkg.in/yaml.v3"
"log"
"os"
"path"
)
type Password struct {
PasswordType string `json:"PasswordType" yaml:"PasswordType"` // plaintext, SHA256
PasswordValue string `json:"PasswordValue" yaml:"PasswordValue"`
}
type UserPassword struct {
Enabled bool `json:"Enabled" yaml:"Enabled"`
Passwords []Password `json:"Passwords" yaml:"Passwords"`
}
type User struct {
Username string `json:"Username" yaml:"Username"`
Enabled bool `json:"Enabled" yaml:"Enabled"`
Authentication UserPassword `json:"Authentication" yaml:"Authentication"`
IncludedCategories []string `json:"IncludedCategories" yaml:"IncludedCategories"`
ExcludedCategories []string `json:"ExcludedCategories" yaml:"ExcludedCategories"`
IncludedCommands []string `json:"IncludedCommands" yaml:"IncludedCommands"`
ExcludedCommands []string `json:"ExcludedCommands" yaml:"ExcludedCommands"`
IncludedKeys []string `json:"IncludedKeys" yaml:"IncludedKeys"`
ExcludedKeys []string `json:"ExcludedKeys" yaml:"ExcludedKeys"`
IncludedReadKeys []string `json:"IncludedReadKeys" yaml:"IncludedReadKeys"`
IncludedWriteKeys []string `json:"IncludedWriteKeys" yaml:"IncludedWriteKeys"`
IncludedPubSubChannels []string `json:"IncludedPubSubChannels" yaml:"IncludedPubSubChannels"`
ExcludedPubSubChannels []string `json:"ExcludedPubSubChannels" yaml:"ExcludedPubSubChannels"`
}
type ACL struct {
Users []User
}
func NewACL(aclConfig string) *ACL {
users := []User{}
// 1. Initialise default ACL user
// 2. Read and parse the ACL config file and set the
if aclConfig != "" {
// Override acl configurations from file
if f, err := os.Open(aclConfig); err != nil {
panic(err)
} else {
defer func() {
if err := f.Close(); err != nil {
fmt.Println("acl config file close error: ", err)
}
}()
ext := path.Ext(f.Name())
if ext == ".json" {
if err := json.NewDecoder(f).Decode(&users); err != nil {
log.Fatal("could not load JSON ACL config: ", err)
}
}
if ext == ".yaml" || ext == ".yml" {
if err := yaml.NewDecoder(f).Decode(&users); err != nil {
log.Fatal("could not load YAML ACL config: ", err)
}
}
}
}
// 3. Validate the ACL Config that has been loaded from the file
return &ACL{
Users: users,
}
}

View File

@@ -51,6 +51,8 @@ type Server struct {
numOfNodes int
cancelCh *chan (os.Signal)
ACL *ACL
}
func (server *Server) KeyLock(ctx context.Context, key string) (bool, error) {
@@ -410,6 +412,8 @@ func main() {
broadcastQueue: new(memberlist.TransmitLimitedQueue),
numOfNodes: 0,
ACL: NewACL(config.AclConfig),
cancelCh: &cancelCh,
}

View File

@@ -24,6 +24,7 @@ type Config struct {
InMemory bool `json:"inMemory" yaml:"inMemory"`
DataDir string `json:"dataDir" yaml:"dataDir"`
BootstrapCluster bool `json:"BootstrapCluster" yaml:"bootstrapCluster"`
AclConfig string `json:"AclConfig" yaml:"AclConfig"`
}
func GetConfig() Config {
@@ -41,6 +42,7 @@ func GetConfig() Config {
inMemory := flag.Bool("inMemory", false, "Whether to use memory or persisten storage for raft logs and snapshots.")
dataDir := flag.String("dataDir", "/var/lib/memstore", "Directory to store raft snapshots and logs.")
bootstrapCluster := flag.Bool("bootstrapCluster", false, "Whether this instance should bootstrap a new cluster.")
aclConfig := flag.String("aclConfig", "", "ACL config file path.")
config := flag.String(
"config",
@@ -65,6 +67,7 @@ func GetConfig() Config {
InMemory: *inMemory,
DataDir: *dataDir,
BootstrapCluster: *bootstrapCluster,
AclConfig: *aclConfig,
}
if len(*config) > 0 {