Compare commits

..

7 Commits

Author SHA1 Message Date
cc27843bb3 add GetSoneInfo (not functional) 2025-08-20 10:12:44 +03:00
20fec82159 delete old scripts 2025-08-20 10:12:15 +03:00
055b299ecb some changes with scripts and add new 2025-08-20 10:12:02 +03:00
17bf207087 fix little bug with script ending 2025-08-20 10:11:36 +03:00
7ae8e12dc8 add new method 2025-08-20 10:11:14 +03:00
6e36db428a fmt 2025-08-20 10:11:02 +03:00
06103a3264 add lua engine skeleton 2025-08-20 10:10:52 +03:00
11 changed files with 309 additions and 9 deletions

View 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
View 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()

View File

@@ -0,0 +1 @@
package lua

View 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)
}

View 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
}

View File

@@ -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),
} }
} }

View File

@@ -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)

View File

@@ -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))