mirror of
https://github.com/EchoVault/SugarDB.git
synced 2025-10-20 22:49:36 +08:00
Implemented ACL Init on server.
Implemented reading of ACL from JSON and YAML files into user list in memory.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,7 +1,6 @@
|
|||||||
.idea
|
.idea
|
||||||
bin
|
bin
|
||||||
openssl
|
openssl
|
||||||
config*.json
|
|
||||||
config*.y*ml
|
|
||||||
docker-compose.y*ml
|
docker-compose.y*ml
|
||||||
volumes
|
volumes
|
||||||
|
/config/
|
||||||
|
@@ -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/plugins /usr/local/lib/memstore
|
||||||
COPY ./bin/linux/x86_64/server /opt/memstore/bin
|
COPY ./bin/linux/x86_64/server /opt/memstore/bin
|
||||||
COPY ./openssl/server /etc/ssl/certs/memstore
|
COPY ./openssl/server /etc/ssl/certs/memstore
|
||||||
|
COPY ./config /etc/config/memstore
|
||||||
|
|
||||||
WORKDIR /opt/memstore/bin
|
WORKDIR /opt/memstore/bin
|
||||||
|
|
||||||
@@ -25,3 +26,4 @@ CMD "./server" \
|
|||||||
"--tls=${TLS}" \
|
"--tls=${TLS}" \
|
||||||
"--inMemory=${INMEMORY}" \
|
"--inMemory=${INMEMORY}" \
|
||||||
"--bootstrapCluster=${BOOTSTRAP_CLUSTER}" \
|
"--bootstrapCluster=${BOOTSTRAP_CLUSTER}" \
|
||||||
|
"--aclConfig=${ACL_CONFIG}" \
|
85
src/acl.go
Normal file
85
src/acl.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
@@ -51,6 +51,8 @@ type Server struct {
|
|||||||
numOfNodes int
|
numOfNodes int
|
||||||
|
|
||||||
cancelCh *chan (os.Signal)
|
cancelCh *chan (os.Signal)
|
||||||
|
|
||||||
|
ACL *ACL
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) KeyLock(ctx context.Context, key string) (bool, error) {
|
func (server *Server) KeyLock(ctx context.Context, key string) (bool, error) {
|
||||||
@@ -410,6 +412,8 @@ func main() {
|
|||||||
broadcastQueue: new(memberlist.TransmitLimitedQueue),
|
broadcastQueue: new(memberlist.TransmitLimitedQueue),
|
||||||
numOfNodes: 0,
|
numOfNodes: 0,
|
||||||
|
|
||||||
|
ACL: NewACL(config.AclConfig),
|
||||||
|
|
||||||
cancelCh: &cancelCh,
|
cancelCh: &cancelCh,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ type Config struct {
|
|||||||
InMemory bool `json:"inMemory" yaml:"inMemory"`
|
InMemory bool `json:"inMemory" yaml:"inMemory"`
|
||||||
DataDir string `json:"dataDir" yaml:"dataDir"`
|
DataDir string `json:"dataDir" yaml:"dataDir"`
|
||||||
BootstrapCluster bool `json:"BootstrapCluster" yaml:"bootstrapCluster"`
|
BootstrapCluster bool `json:"BootstrapCluster" yaml:"bootstrapCluster"`
|
||||||
|
AclConfig string `json:"AclConfig" yaml:"AclConfig"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetConfig() Config {
|
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.")
|
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.")
|
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.")
|
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 := flag.String(
|
||||||
"config",
|
"config",
|
||||||
@@ -65,6 +67,7 @@ func GetConfig() Config {
|
|||||||
InMemory: *inMemory,
|
InMemory: *inMemory,
|
||||||
DataDir: *dataDir,
|
DataDir: *dataDir,
|
||||||
BootstrapCluster: *bootstrapCluster,
|
BootstrapCluster: *bootstrapCluster,
|
||||||
|
AclConfig: *aclConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*config) > 0 {
|
if len(*config) > 0 {
|
||||||
|
Reference in New Issue
Block a user