mirror of
https://github.com/akyaiy/GoSally-mvp.git
synced 2026-01-03 08:32:24 +00:00
Compare commits
7 Commits
c6da55ad65
...
cc27843bb3
| Author | SHA1 | Date | |
|---|---|---|---|
| cc27843bb3 | |||
| 20fec82159 | |||
| 055b299ecb | |||
| 17bf207087 | |||
| 7ae8e12dc8 | |||
| 6e36db428a | |||
| 06103a3264 |
77
com/Access/GetMasterAccess.lua
Normal file
77
com/Access/GetMasterAccess.lua
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
local session = require("internal.session")
|
||||||
|
local log = require("internal.log")
|
||||||
|
local jwt = require("internal.crypt.jwt")
|
||||||
|
local bc = require("internal.crypt.bcrypt")
|
||||||
|
local db = require("internal.database.sqlite").connect("db/root.db", {log = true})
|
||||||
|
local sha256 = require("internal.crypt.sha256")
|
||||||
|
|
||||||
|
log.info("Someone at "..session.request.address.." trying to get master access")
|
||||||
|
|
||||||
|
local function close_db()
|
||||||
|
if db then
|
||||||
|
db:close()
|
||||||
|
db = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local params = session.request.params.get()
|
||||||
|
|
||||||
|
local function check_missing(arr, p)
|
||||||
|
local is_missing = {}
|
||||||
|
local ok = true
|
||||||
|
for _, key in ipairs(arr) do
|
||||||
|
if p[key] == nil then
|
||||||
|
table.insert(is_missing, key)
|
||||||
|
ok = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ok, is_missing
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, mp = check_missing({"master_secret", "master_name", "my_key"}, params)
|
||||||
|
if not ok then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(-32602, "Missing params", mp)
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(params.master_secret) ~= "string" then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(-32050, "Access denied")
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(params.master_name) ~= "string" then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(-32050, "Access denied")
|
||||||
|
end
|
||||||
|
|
||||||
|
local master, err = db:query_row("SELECT * FROM master_units WHERE master_name = ?", {params.master_name})
|
||||||
|
|
||||||
|
if not master then
|
||||||
|
log.event("DB query failed:", err)
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(-32050, "Access denied")
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok = bc.compare(master.master_secret, params.master_secret)
|
||||||
|
if not ok then
|
||||||
|
log.warn("Login failed: wrong password")
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(-32050, "Access denied")
|
||||||
|
end
|
||||||
|
|
||||||
|
local token = jwt.encode({
|
||||||
|
secret = require("_config").token(),
|
||||||
|
payload = {
|
||||||
|
session_uuid = session.id,
|
||||||
|
master_id = master.id,
|
||||||
|
key = sha256.sum(params.my_key)
|
||||||
|
},
|
||||||
|
expires_in = 3600
|
||||||
|
})
|
||||||
|
|
||||||
|
close_db()
|
||||||
|
session.response.send({
|
||||||
|
token = token
|
||||||
|
})
|
||||||
|
|
||||||
|
-- G7HgOgl72o7t7u7r
|
||||||
69
com/Zones/GetZoneInfo.lua
Normal file
69
com/Zones/GetZoneInfo.lua
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
local session = require("internal.session")
|
||||||
|
local log = require("internal.log")
|
||||||
|
local jwt = require("internal.crypt.jwt")
|
||||||
|
local bc = require("internal.crypt.bcrypt")
|
||||||
|
local sha256 = require("internal.crypt.sha256")
|
||||||
|
local dbdriver = require("internal.database.sqlite")
|
||||||
|
|
||||||
|
local db_root = dbdriver.connect("db/root.db", {log = true})
|
||||||
|
local db_zone = nil
|
||||||
|
|
||||||
|
local function close_db()
|
||||||
|
if db_root then
|
||||||
|
db_root:close()
|
||||||
|
db_root = nil
|
||||||
|
end
|
||||||
|
if db_zone then
|
||||||
|
db_zone:close()
|
||||||
|
db_zone = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local token = session.request.headers.get("authorization")
|
||||||
|
|
||||||
|
if not token or type(token) ~= "string" then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(-32050, "Access denied")
|
||||||
|
end
|
||||||
|
|
||||||
|
local prefix = "Bearer "
|
||||||
|
if token:sub(1, #prefix) ~= prefix then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(-32052, "Invalid Authorization scheme")
|
||||||
|
end
|
||||||
|
|
||||||
|
local access_token = token:sub(#prefix + 1)
|
||||||
|
|
||||||
|
local err, data = jwt.decode(access_token, { secret = require("_config").token() })
|
||||||
|
|
||||||
|
if err or not data then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(-32053, "Cannod parse JWT", {err})
|
||||||
|
end
|
||||||
|
|
||||||
|
if data.master_id then
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local params = session.request.params.get()
|
||||||
|
|
||||||
|
local function check_missing(arr, p)
|
||||||
|
local is_missing = {}
|
||||||
|
local ok = true
|
||||||
|
for _, key in ipairs(arr) do
|
||||||
|
if p[key] == nil then
|
||||||
|
table.insert(is_missing, key)
|
||||||
|
ok = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ok, is_missing
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, mp = check_missing({"zone_name"}, params)
|
||||||
|
if not ok then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(-32602, "Missing params", mp)
|
||||||
|
end
|
||||||
|
|
||||||
|
close_db()
|
||||||
1
internal/engine/lua/handler.go
Normal file
1
internal/engine/lua/handler.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package lua
|
||||||
35
internal/engine/lua/pool.go
Normal file
35
internal/engine/lua/pool.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package lua
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
lua "github.com/yuin/gopher-lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LuaPool struct {
|
||||||
|
pool sync.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLuaPool() *LuaPool {
|
||||||
|
return &LuaPool{
|
||||||
|
pool: sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
L := lua.NewState()
|
||||||
|
|
||||||
|
return L
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lp *LuaPool) Get() *lua.LState {
|
||||||
|
return lp.pool.Get().(*lua.LState)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lp *LuaPool) Put(L *lua.LState) {
|
||||||
|
L.Close()
|
||||||
|
|
||||||
|
newL := lua.NewState()
|
||||||
|
|
||||||
|
lp.pool.Put(newL)
|
||||||
|
}
|
||||||
26
internal/engine/lua/types.go
Normal file
26
internal/engine/lua/types.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package lua
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
||||||
|
"github.com/akyaiy/GoSally-mvp/internal/engine/app"
|
||||||
|
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LuaEngineDeps struct {
|
||||||
|
HttpRequest *http.Request
|
||||||
|
JSONRPCRequest *rpc.RPCRequest
|
||||||
|
SessionUUID string
|
||||||
|
ScriptPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
type LuaEngineContract interface {
|
||||||
|
Handle(deps *LuaEngineDeps) *rpc.RPCResponse
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type LuaEngine struct {
|
||||||
|
x *app.AppX
|
||||||
|
cs *corestate.CoreState
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@ func NewResponse(result any, id *json.RawMessage) *RPCResponse {
|
|||||||
return &RPCResponse{
|
return &RPCResponse{
|
||||||
JSONRPC: JSONRPCVersion,
|
JSONRPC: JSONRPCVersion,
|
||||||
ID: id,
|
ID: id,
|
||||||
Result: result,
|
Result: result,
|
||||||
Data: GetData(result),
|
Data: GetData(result),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ func loadDBMod(llog *slog.Logger, sid string) func(*lua.LState) int {
|
|||||||
L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
|
L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
|
||||||
"exec": dbExec,
|
"exec": dbExec,
|
||||||
"query": dbQuery,
|
"query": dbQuery,
|
||||||
|
"query_row": dbQueryRow,
|
||||||
"close": dbClose,
|
"close": dbClose,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -213,6 +214,102 @@ func dbExec(L *lua.LState) int {
|
|||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func dbQueryRow(L *lua.LState) int {
|
||||||
|
ud := L.CheckUserData(1)
|
||||||
|
conn, ok := ud.Value.(*DBConnection)
|
||||||
|
if !ok {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString("invalid database connection"))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
query := L.CheckString(2)
|
||||||
|
|
||||||
|
var args []any
|
||||||
|
if L.GetTop() >= 3 {
|
||||||
|
params := L.CheckTable(3)
|
||||||
|
params.ForEach(func(k lua.LValue, v lua.LValue) {
|
||||||
|
args = append(args, ConvertLuaTypesToGolang(v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if conn.log {
|
||||||
|
conn.logger.Info("DB QueryRow",
|
||||||
|
slog.String("query", query),
|
||||||
|
slog.Any("params", args))
|
||||||
|
}
|
||||||
|
|
||||||
|
mtx := getDBMutex(conn.dbPath)
|
||||||
|
mtx.RLock()
|
||||||
|
defer mtx.RUnlock()
|
||||||
|
|
||||||
|
db, err := sql.Open("sqlite", conn.dbPath+"?_busy_timeout=5000&_journal_mode=WAL&_sync=NORMAL&_cache_size=-10000")
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(err.Error()))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
row := db.QueryRow(query, args...)
|
||||||
|
|
||||||
|
columns := []string{}
|
||||||
|
stmt, err := db.Prepare(query)
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(fmt.Sprintf("prepare failed: %v", err)))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
defer stmt.Close()
|
||||||
|
rows, err := stmt.Query(args...)
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(fmt.Sprintf("query failed: %v", err)))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
cols, err := rows.Columns()
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(fmt.Sprintf("get columns failed: %v", err)))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
for _, c := range cols {
|
||||||
|
columns = append(columns, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
colCount := len(columns)
|
||||||
|
values := make([]any, colCount)
|
||||||
|
valuePtrs := make([]any, colCount)
|
||||||
|
for i := range columns {
|
||||||
|
valuePtrs[i] = &values[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
err = row.Scan(valuePtrs...)
|
||||||
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(fmt.Sprintf("scan failed: %v", err)))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
rowTable := L.NewTable()
|
||||||
|
for i, col := range columns {
|
||||||
|
val := values[i]
|
||||||
|
if val == nil {
|
||||||
|
L.SetField(rowTable, col, lua.LNil)
|
||||||
|
} else {
|
||||||
|
L.SetField(rowTable, col, ConvertGolangTypesToLua(L, val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
L.Push(rowTable)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
func dbQuery(L *lua.LState) int {
|
func dbQuery(L *lua.LState) int {
|
||||||
ud := L.CheckUserData(1)
|
ud := L.CheckUserData(1)
|
||||||
conn, ok := ud.Value.(*DBConnection)
|
conn, ok := ud.Value.(*DBConnection)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func addInitiatorHeaders(sid string, req *http.Request, headers http.Header) {
|
|||||||
// I will be only glad.
|
// I will be only glad.
|
||||||
// TODO: make this huge function more harmonious by dividing responsibilities
|
// TODO: make this huge function more harmonious by dividing responsibilities
|
||||||
func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest, path string) *rpc.RPCResponse {
|
func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest, path string) *rpc.RPCResponse {
|
||||||
var __exit = 0
|
var __exit = -1
|
||||||
|
|
||||||
llog := h.x.SLog.With(slog.String("session-id", sid))
|
llog := h.x.SLog.With(slog.String("session-id", sid))
|
||||||
llog.Debug("handling LUA")
|
llog.Debug("handling LUA")
|
||||||
@@ -544,12 +544,7 @@ func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest,
|
|||||||
|
|
||||||
L.SetField(sha265mod, "sum", L.NewFunction(func(l *lua.LState) int {
|
L.SetField(sha265mod, "sum", L.NewFunction(func(l *lua.LState) int {
|
||||||
data := ConvertLuaTypesToGolang(L.Get(1))
|
data := ConvertLuaTypesToGolang(L.Get(1))
|
||||||
dataStr, ok := data.(string)
|
var dataStr = fmt.Sprint(data)
|
||||||
if !ok {
|
|
||||||
L.Push(lua.LNil)
|
|
||||||
L.Push(lua.LString("error: data must be a string"))
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
|
|
||||||
hash := sha256.Sum256([]byte(dataStr))
|
hash := sha256.Sum256([]byte(dataStr))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user