mirror of
https://github.com/cadmium-im/zirconium-go.git
synced 2024-12-27 11:21:51 +00:00
Implement dynamic plugins support (by RPC)
This commit is contained in:
parent
7e534680c7
commit
1584f9e58a
@ -1,16 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/ChronosX88/zirconium/internal"
|
||||
core "github.com/ChronosX88/zirconium/core"
|
||||
"github.com/google/logger"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/pelletier/go-toml"
|
||||
)
|
||||
|
||||
var connectionHandler = internal.NewConnectionHandler()
|
||||
var connectionHandler = core.NewConnectionHandler()
|
||||
var upgrader = websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
@ -18,7 +24,44 @@ var upgrader = websocket.Upgrader{
|
||||
}
|
||||
|
||||
func main() {
|
||||
internal.InitializeContext("localhost")
|
||||
|
||||
var cfg core.ServerConfig
|
||||
var configPath string
|
||||
var generateConfig bool
|
||||
flag.StringVar(&configPath, "config", "", "Path to config")
|
||||
flag.BoolVar(&generateConfig, "gen_config", false, "Generate the config")
|
||||
flag.Parse()
|
||||
if generateConfig == true {
|
||||
sampleConfig := &core.ServerConfig{}
|
||||
val, err := toml.Marshal(sampleConfig)
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to generate config: %s", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(val))
|
||||
os.Exit(0)
|
||||
}
|
||||
if configPath == "" {
|
||||
logger.Error("Path to config isn't specified!")
|
||||
os.Exit(1)
|
||||
}
|
||||
cfgData, err := ioutil.ReadFile(configPath)
|
||||
if err != nil {
|
||||
logger.Error("Failed to read config!")
|
||||
os.Exit(1)
|
||||
}
|
||||
err = toml.Unmarshal(cfgData, &cfg)
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to read config! (yaml error: %s)", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
err = validateConfig(&cfg)
|
||||
if err != nil {
|
||||
logger.Errorf("Config validation failed: %s", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
core.InitializeContext(cfg.ServerDomain, cfg.PluginsDirPath, cfg.EnabledPlugins)
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/", func(response http.ResponseWriter, request *http.Request) {
|
||||
response.Write([]byte("Zirconium server is up and running!"))
|
||||
@ -36,3 +79,12 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
connectionHandler.HandleNewConnection(ws)
|
||||
}
|
||||
|
||||
func validateConfig(config *core.ServerConfig) error {
|
||||
if config.ServerDomain == "" {
|
||||
return errors.New("server domain isn't specified")
|
||||
} else if config.PluginsDirPath == "" {
|
||||
return errors.New("plugin directory path isn't specified")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package internal
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
4
core/builtin_plugins.go
Normal file
4
core/builtin_plugins.go
Normal file
@ -0,0 +1,4 @@
|
||||
package core
|
||||
|
||||
// BuiltinPlugins is a list of builtin plugins
|
||||
var BuiltinPlugins = map[string]Module{}
|
12
core/config.go
Normal file
12
core/config.go
Normal file
@ -0,0 +1,12 @@
|
||||
package core
|
||||
|
||||
type ServerConfig struct {
|
||||
// A list of enabled plugins (or extensions) in server
|
||||
EnabledPlugins []string `toml:"enabledPlugins" comment:"A list of enabled plugins (or extensions) in server"`
|
||||
|
||||
// Server domain name (e.g. example.com)
|
||||
ServerDomain string `toml:"serverDomain" comment:"Server domain name (e.g. example.com)"`
|
||||
|
||||
// Path to directory with plugin executables
|
||||
PluginsDirPath string `toml:"pluginsDirPath" comment:"Path to directory with plugin executables"`
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package internal
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/ChronosX88/zirconium/internal/models"
|
||||
"github.com/ChronosX88/zirconium/core/models"
|
||||
"github.com/google/logger"
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/websocket"
|
41
core/globals.go
Normal file
41
core/globals.go
Normal file
@ -0,0 +1,41 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/google/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
moduleMgr *ModuleManager
|
||||
router *Router
|
||||
authManager *AuthManager
|
||||
serverDomain string
|
||||
pluginManager *PluginManager
|
||||
)
|
||||
|
||||
func InitializeContext(sDomain string, pluginsDirPath string, enabledPlugins []string) {
|
||||
var err error
|
||||
moduleMgr, err = NewModuleManager()
|
||||
if err != nil {
|
||||
logger.Fatalf("Unable to initialize module manager: %s", err.Error())
|
||||
}
|
||||
|
||||
router, err = NewRouter()
|
||||
if err != nil {
|
||||
logger.Fatalf("Unable to initialize router: %s", err.Error())
|
||||
}
|
||||
|
||||
authManager, err = NewAuthManager()
|
||||
if err != nil {
|
||||
logger.Fatalf("Unable to initialize authentication manager: %s", err.Error())
|
||||
}
|
||||
serverDomain = sDomain
|
||||
|
||||
for _, v := range BuiltinPlugins {
|
||||
go v.Initialize(moduleMgr) // Initialize builtin plugins
|
||||
}
|
||||
|
||||
pluginManager = NewPluginManager()
|
||||
for _, v := range enabledPlugins {
|
||||
pluginManager.StartPlugin(pluginsDirPath, v, moduleMgr)
|
||||
}
|
||||
}
|
17
core/module.go
Normal file
17
core/module.go
Normal file
@ -0,0 +1,17 @@
|
||||
package core
|
||||
|
||||
const (
|
||||
ModuleInterfaceName = "Module"
|
||||
)
|
||||
|
||||
type Module interface {
|
||||
Initialize(moduleAPI *ModuleManager)
|
||||
Name() string
|
||||
Version() string
|
||||
}
|
||||
|
||||
type ModuleRef struct {
|
||||
F func() Module
|
||||
}
|
||||
|
||||
type ModuleFunc func() Module
|
@ -1,11 +1,11 @@
|
||||
package internal
|
||||
package core
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ChronosX88/zirconium/internal/models"
|
||||
"github.com/ChronosX88/zirconium/core/models"
|
||||
)
|
||||
|
||||
type C2SMessageHandler struct {
|
||||
@ -14,15 +14,15 @@ type C2SMessageHandler struct {
|
||||
}
|
||||
|
||||
type ModuleManager struct {
|
||||
moduleMutex sync.Mutex
|
||||
c2sMessageHandlers map[string][]*C2SMessageHandler
|
||||
internalEventHandlers map[string][]func(sourceModuleName string, event map[string]interface{})
|
||||
moduleMutex sync.Mutex
|
||||
c2sMessageHandlers map[string][]*C2SMessageHandler
|
||||
coreEventHandlers map[string][]func(sourceModuleName string, event map[string]interface{})
|
||||
}
|
||||
|
||||
func NewModuleManager() (*ModuleManager, error) {
|
||||
var mm = &ModuleManager{
|
||||
c2sMessageHandlers: make(map[string][]*C2SMessageHandler),
|
||||
internalEventHandlers: make(map[string][]func(sourceModuleName string, event map[string]interface{})),
|
||||
c2sMessageHandlers: make(map[string][]*C2SMessageHandler),
|
||||
coreEventHandlers: make(map[string][]func(sourceModuleName string, event map[string]interface{})),
|
||||
}
|
||||
return mm, nil
|
||||
}
|
||||
@ -36,9 +36,9 @@ func (mm *ModuleManager) Hook(messageType string, anonymousAllowed bool, handler
|
||||
mm.moduleMutex.Unlock()
|
||||
}
|
||||
|
||||
func (mm *ModuleManager) HookInternalEvent(eventName string, handlerFunc func(sourceModuleName string, event map[string]interface{})) {
|
||||
func (mm *ModuleManager) HookcoreEvent(eventName string, handlerFunc func(sourceModuleName string, event map[string]interface{})) {
|
||||
mm.moduleMutex.Lock()
|
||||
mm.internalEventHandlers[eventName] = append(mm.internalEventHandlers[eventName], handlerFunc)
|
||||
mm.coreEventHandlers[eventName] = append(mm.coreEventHandlers[eventName], handlerFunc)
|
||||
mm.moduleMutex.Unlock()
|
||||
}
|
||||
|
||||
@ -59,17 +59,17 @@ func (mm *ModuleManager) Unhook(messageType string, handlerFunc func(origin *Ori
|
||||
}
|
||||
}
|
||||
|
||||
func (mm *ModuleManager) UnhookInternalEvent(eventName string, handlerFunc func(sourceModuleName string, event map[string]interface{})) {
|
||||
func (mm *ModuleManager) UnhookcoreEvent(eventName string, handlerFunc func(sourceModuleName string, event map[string]interface{})) {
|
||||
mm.moduleMutex.Lock()
|
||||
defer mm.moduleMutex.Unlock()
|
||||
var handlers = mm.internalEventHandlers[eventName]
|
||||
var handlers = mm.coreEventHandlers[eventName]
|
||||
if handlers != nil {
|
||||
for i, v := range handlers {
|
||||
if reflect.ValueOf(v).Pointer() == reflect.ValueOf(handlerFunc).Pointer() {
|
||||
handlers[i] = handlers[len(handlers)-1]
|
||||
handlers[len(handlers)-1] = nil
|
||||
handlers = handlers[:len(handlers)-1]
|
||||
mm.internalEventHandlers[eventName] = handlers
|
||||
mm.coreEventHandlers[eventName] = handlers
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -77,7 +77,7 @@ func (mm *ModuleManager) UnhookInternalEvent(eventName string, handlerFunc func(
|
||||
}
|
||||
|
||||
func (mm *ModuleManager) FireEvent(sourceModuleName string, eventName string, eventPayload map[string]interface{}) {
|
||||
router.RouteInternalEvent(sourceModuleName, eventName, eventPayload)
|
||||
router.RoutecoreEvent(sourceModuleName, eventName, eventPayload)
|
||||
}
|
||||
|
||||
func (mm *ModuleManager) GenerateToken(entityID, deviceID string, tokenExpireTimeDuration time.Duration) (string, error) {
|
38
core/module_rpc_receiver.go
Normal file
38
core/module_rpc_receiver.go
Normal file
@ -0,0 +1,38 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
type greeterServer struct {
|
||||
Broker *plugin.MuxBroker
|
||||
Module Module
|
||||
}
|
||||
|
||||
// Server implmentation of go-plugin.plugin.Plugin.Server
|
||||
func (p *ModuleRef) Server(b *plugin.MuxBroker) (interface{}, error) {
|
||||
if p.F == nil {
|
||||
return nil, errors.New("Greeter interface not implemeted")
|
||||
}
|
||||
return &greeterServer{Broker: b, Module: p.F()}, nil
|
||||
}
|
||||
|
||||
// Name calls the plugin implementation to get the name of the plugin
|
||||
func (p *greeterServer) Name(nothing interface{}, result *string) error {
|
||||
*result = p.Module.Name()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Version calls the plugin implementation to get the version of the plugin
|
||||
func (p *greeterServer) Version(nothing interface{}, result *string) error {
|
||||
*result = p.Module.Version()
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartTime calls the plugin implementation to initialize plugin
|
||||
func (p *greeterServer) Initialize(moduleAPI *ModuleManager, emptyResult interface{}) error {
|
||||
p.Module.Initialize(moduleAPI)
|
||||
return nil
|
||||
}
|
48
core/module_rpc_sender.go
Normal file
48
core/module_rpc_sender.go
Normal file
@ -0,0 +1,48 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/rpc"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
type moduleClient struct {
|
||||
Broker *plugin.MuxBroker
|
||||
Client *rpc.Client
|
||||
}
|
||||
|
||||
// Client implmentation of go-plugin.plugin.Plugin.Client
|
||||
func (p *ModuleRef) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
|
||||
return &moduleClient{Broker: b, Client: c}, nil
|
||||
}
|
||||
|
||||
// Name initiates an RPC call to the plugin name
|
||||
func (p *moduleClient) Name() string {
|
||||
var resp string
|
||||
err := p.Client.Call("Plugin.Name", new(interface{}), &resp)
|
||||
if err != nil {
|
||||
log.Fatal(err) // FIXME
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
// Version initiates an RPC call to the plugin version
|
||||
func (p *moduleClient) Version() string {
|
||||
var resp string
|
||||
err := p.Client.Call("Plugin.Version", new(interface{}), &resp)
|
||||
if err != nil {
|
||||
log.Fatal(err) // FIXME
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
// StartTime initiates an RPC call to the plugin for initializing
|
||||
func (p *moduleClient) Initialize(moduleAPI *ModuleManager) {
|
||||
err := p.Client.Call("Plugin.Initialize", map[string]interface{}{
|
||||
"moduleAPI": moduleAPI,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err) // FIXME
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package internal
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/ChronosX88/zirconium/internal/models"
|
||||
"github.com/ChronosX88/zirconium/core/models"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
56
core/plugin_manager.go
Normal file
56
core/plugin_manager.go
Normal file
@ -0,0 +1,56 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/logger"
|
||||
"github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
type PluginManager struct{}
|
||||
|
||||
func NewPluginManager() *PluginManager {
|
||||
return &PluginManager{}
|
||||
}
|
||||
|
||||
func (p *PluginManager) StartPlugin(pluginsDirPath, pluginFile string, moduleManager *ModuleManager) error {
|
||||
pluginsDirectory, _ := filepath.Abs(filepath.Dir(pluginsDirPath))
|
||||
pluginFile = filepath.Join(pluginsDirectory, pluginFile)
|
||||
|
||||
logger.Info("Starting plugin: %s", pluginFile)
|
||||
|
||||
client := plugin.NewClient(&plugin.ClientConfig{
|
||||
Cmd: exec.Command(pluginFile),
|
||||
Managed: true,
|
||||
SyncStdout: os.Stdout,
|
||||
SyncStderr: os.Stderr,
|
||||
|
||||
HandshakeConfig: HandshakeConfig,
|
||||
Plugins: GetPluginMap(nil),
|
||||
})
|
||||
|
||||
rpcclient, err := client.Client()
|
||||
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to get RPC Client: %s", err)
|
||||
client.Kill()
|
||||
return err
|
||||
}
|
||||
|
||||
// get the interface
|
||||
raw, err := rpcclient.Dispense(ModuleInterfaceName)
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to get interface: %s error: %s", ModuleInterfaceName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
moduleObj := raw.(Module)
|
||||
|
||||
go func() {
|
||||
moduleObj.Initialize(moduleManager)
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package internal
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/ChronosX88/zirconium/internal/models"
|
||||
"github.com/ChronosX88/zirconium/core/models"
|
||||
"github.com/google/logger"
|
||||
)
|
||||
|
||||
@ -64,8 +64,8 @@ func (r *Router) RouteMessage(origin *OriginC2S, message models.BaseMessage) {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Router) RouteInternalEvent(sourceModuleName string, eventName string, eventPayload map[string]interface{}) {
|
||||
handlers := r.moduleManager.internalEventHandlers[eventName]
|
||||
func (r *Router) RoutecoreEvent(sourceModuleName string, eventName string, eventPayload map[string]interface{}) {
|
||||
handlers := r.moduleManager.coreEventHandlers[eventName]
|
||||
if handlers != nil {
|
||||
for _, v := range handlers {
|
||||
go v(sourceModuleName, eventPayload)
|
99
core/utils.go
Normal file
99
core/utils.go
Normal file
@ -0,0 +1,99 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"log"
|
||||
"reflect"
|
||||
|
||||
"github.com/ChronosX88/zirconium/core/models"
|
||||
"github.com/google/logger"
|
||||
"github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
func GenRandomBytes(size int) (blk []byte, err error) {
|
||||
blk = make([]byte, size)
|
||||
_, err = rand.Read(blk)
|
||||
return
|
||||
}
|
||||
|
||||
func StructToMap(item interface{}) map[string]interface{} {
|
||||
res := map[string]interface{}{}
|
||||
if item == nil {
|
||||
return res
|
||||
}
|
||||
v := reflect.TypeOf(item)
|
||||
reflectValue := reflect.ValueOf(item)
|
||||
reflectValue = reflect.Indirect(reflectValue)
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
tag := v.Field(i).Tag.Get("json")
|
||||
field := reflectValue.Field(i).Interface()
|
||||
if tag != "" && tag != "-" {
|
||||
if v.Field(i).Type.Kind() == reflect.Struct {
|
||||
res[tag] = StructToMap(field)
|
||||
} else {
|
||||
res[tag] = field
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func PrepareMessageUnauthorized(msg models.BaseMessage) models.BaseMessage {
|
||||
protocolError := models.ProtocolError{
|
||||
ErrCode: "unauthorized",
|
||||
ErrText: "Unauthorized access",
|
||||
ErrPayload: make(map[string]interface{}),
|
||||
}
|
||||
errMsg := models.NewBaseMessage(msg.ID, msg.MessageType, serverDomain, msg.From, false, StructToMap(protocolError))
|
||||
return errMsg
|
||||
}
|
||||
|
||||
var HandshakeConfig = plugin.HandshakeConfig{
|
||||
ProtocolVersion: 1,
|
||||
MagicCookieKey: "TEST_TEST",
|
||||
MagicCookieValue: "qwerty",
|
||||
}
|
||||
|
||||
type PluginOpts struct {
|
||||
Module ModuleFunc
|
||||
RunAsPlugin bool
|
||||
}
|
||||
|
||||
// GetPluginMap returns the plugin map defined Hashicorp go-plugin.
|
||||
// The reserved parameter should only be used by the RPC receiver (the plugin).
|
||||
// Otherwise, reserved should be nil for the RPC sender (the mainapp).
|
||||
func GetPluginMap(reserved *PluginOpts) map[string]plugin.Plugin {
|
||||
var moduleObj ModuleRef
|
||||
|
||||
if reserved != nil {
|
||||
moduleObj.F = reserved.Module
|
||||
}
|
||||
|
||||
return map[string]plugin.Plugin{
|
||||
ModuleInterfaceName: &moduleObj,
|
||||
}
|
||||
}
|
||||
|
||||
func StartPlugin(opts *PluginOpts, quit chan bool) {
|
||||
if opts.RunAsPlugin {
|
||||
go func() {
|
||||
logger.Info("Starting plugin communication...")
|
||||
|
||||
plugin.Serve(&plugin.ServeConfig{
|
||||
HandshakeConfig: HandshakeConfig,
|
||||
Plugins: GetPluginMap(opts),
|
||||
})
|
||||
|
||||
logger.Info("Exiting plugin communication...")
|
||||
|
||||
quit <- true
|
||||
logger.Info("Exiting plugin...")
|
||||
}()
|
||||
} else {
|
||||
log.Println("Starting in standalone mode...")
|
||||
}
|
||||
}
|
2
go.mod
2
go.mod
@ -8,4 +8,6 @@ require (
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/hashicorp/go-plugin v1.0.1
|
||||
github.com/pelletier/go-toml v1.6.0
|
||||
)
|
||||
|
41
go.sum
41
go.sum
@ -1,5 +1,14 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/logger v1.0.1 h1:Jtq7/44yDwUXMaLTYgXFC31zpm6Oku7OI/k4//yVANQ=
|
||||
github.com/google/logger v1.0.1/go.mod h1:w7O8nrRr0xufejBlQMI83MXqRusvREoJdaAxV+CoAB4=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
@ -8,5 +17,37 @@ github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd h1:rNuUHR+CvK1IS89MMtcF0EpcVMZtjKfPRp4MEmt/aTs=
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
|
||||
github.com/hashicorp/go-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE=
|
||||
github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg=
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
|
||||
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.14.0 h1:ArxJuB1NWfPY6r9Gp9gqwplT0Ge7nqv9msgu03lHLmo=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -1,36 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/ChronosX88/zirconium/shared"
|
||||
"github.com/google/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
ModuleMgr *ModuleManager
|
||||
router *Router
|
||||
authManager *AuthManager
|
||||
serverDomain string
|
||||
)
|
||||
|
||||
func InitializeContext(sDomain string) {
|
||||
var err error
|
||||
ModuleMgr, err = NewModuleManager()
|
||||
if err != nil {
|
||||
logger.Fatalf("Unable to initialize module manager: %s", err.Error())
|
||||
}
|
||||
|
||||
router, err = NewRouter()
|
||||
if err != nil {
|
||||
logger.Fatalf("Unable to initialize router: %s", err.Error())
|
||||
}
|
||||
|
||||
authManager, err = NewAuthManager()
|
||||
if err != nil {
|
||||
logger.Fatalf("Unable to initialize authentication manager: %s", err.Error())
|
||||
}
|
||||
serverDomain = sDomain
|
||||
|
||||
for _, v := range shared.Plugins {
|
||||
go v.Initialize() // Initialize provided plugins
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"reflect"
|
||||
|
||||
"github.com/ChronosX88/zirconium/internal/models"
|
||||
)
|
||||
|
||||
func GenRandomBytes(size int) (blk []byte, err error) {
|
||||
blk = make([]byte, size)
|
||||
_, err = rand.Read(blk)
|
||||
return
|
||||
}
|
||||
|
||||
func StructToMap(item interface{}) map[string]interface{} {
|
||||
res := map[string]interface{}{}
|
||||
if item == nil {
|
||||
return res
|
||||
}
|
||||
v := reflect.TypeOf(item)
|
||||
reflectValue := reflect.ValueOf(item)
|
||||
reflectValue = reflect.Indirect(reflectValue)
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
tag := v.Field(i).Tag.Get("json")
|
||||
field := reflectValue.Field(i).Interface()
|
||||
if tag != "" && tag != "-" {
|
||||
if v.Field(i).Type.Kind() == reflect.Struct {
|
||||
res[tag] = StructToMap(field)
|
||||
} else {
|
||||
res[tag] = field
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func PrepareMessageUnauthorized(msg models.BaseMessage) models.BaseMessage {
|
||||
protocolError := models.ProtocolError{
|
||||
ErrCode: "unauthorized",
|
||||
ErrText: "Unauthorized access",
|
||||
ErrPayload: make(map[string]interface{}),
|
||||
}
|
||||
errMsg := models.NewBaseMessage(msg.ID, msg.MessageType, serverDomain, msg.From, false, StructToMap(protocolError))
|
||||
return errMsg
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package shared
|
||||
|
||||
type Module interface {
|
||||
Initialize()
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package shared
|
||||
|
||||
var Plugins = map[string]Module{
|
||||
// Add plugins here
|
||||
}
|
Loading…
Reference in New Issue
Block a user