mirror of
https://github.com/akyaiy/GoSally-mvp.git
synced 2026-01-03 19:32:26 +00:00
Compare commits
30 Commits
auth-serve
...
df1ef57769
| Author | SHA1 | Date | |
|---|---|---|---|
| df1ef57769 | |||
| 4c840c40bb | |||
| 57f35e8f33 | |||
| f0c591f325 | |||
| 36ee320c45 | |||
| ee6fd205d5 | |||
| bed0471cc4 | |||
| e3812a18a6 | |||
| b7d939d5d7 | |||
| c737e80b8f | |||
| 5783a756c3 | |||
| ba47ee4219 | |||
| 5d49e0afc7 | |||
| 76fed578ff | |||
| 975c52b58e | |||
| 4e75d48f1d | |||
| 65af07fffa | |||
| 1252634420 | |||
| 4a58845211 | |||
| b0701632e6 | |||
| 9277aa9f1a | |||
| 19654e1eca | |||
| d4306a0d89 | |||
| 73095a69e0 | |||
| 0f82ce941b | |||
|
|
0ec8493ab4 | ||
|
|
24eef9eee0 | ||
|
|
a6c9e5102f | ||
| f3c4b9e9b1 | |||
|
|
81359c036c |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -10,4 +10,8 @@ com/_config.lua
|
|||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
Taskfile.yml
|
Taskfile.yml
|
||||||
config.yaml
|
config.yaml
|
||||||
|
|
||||||
|
# Garbage
|
||||||
|
com/_*
|
||||||
|
com/test.lua
|
||||||
18
Makefile
18
Makefile
@@ -29,15 +29,15 @@ build:
|
|||||||
@echo "Building..."
|
@echo "Building..."
|
||||||
@# @echo "CGO_CFLAGS is: '$(CGO_CFLAGS)'"
|
@# @echo "CGO_CFLAGS is: '$(CGO_CFLAGS)'"
|
||||||
@# @echo "CGO_LDFLAGS is: '$(CGO_LDFLAGS)'"
|
@# @echo "CGO_LDFLAGS is: '$(CGO_LDFLAGS)'"
|
||||||
@# CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)"
|
@# CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)"
|
||||||
@go build -trimpath -ldflags "-w -s $(LDFLAGS)" -o $(BIN_DIR)/$(APP_NAME) ./
|
@cd src && go build -trimpath -ldflags "-w -s $(LDFLAGS)" -o ../$(BIN_DIR)/$(APP_NAME) ./
|
||||||
@if ! command -v upx >/dev/null 2>&1; then \
|
# @if ! command -v upx >/dev/null 2>&1; then \
|
||||||
echo "upx not found, skipping compression."; \
|
# echo "upx not found, skipping compression."; \
|
||||||
elif upx -t $(BIN_DIR)/$(APP_NAME) >/dev/null 2>&1; then \
|
# elif upx -t $(BIN_DIR)/$(APP_NAME) >/dev/null 2>&1; then \
|
||||||
echo "$(BIN_DIR)/$(APP_NAME) already compressed, skipping."; \
|
# echo "$(BIN_DIR)/$(APP_NAME) already compressed, skipping."; \
|
||||||
else \
|
# else \
|
||||||
upx $(BIN_DIR)/$(APP_NAME) >/dev/null 2>&1 || true; \
|
# upx $(BIN_DIR)/$(APP_NAME) >/dev/null 2>&1 || true; \
|
||||||
fi
|
# fi
|
||||||
|
|
||||||
run: build
|
run: build
|
||||||
@echo "Running!"
|
@echo "Running!"
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
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
|
|
||||||
68
com/Unit/Create.lua
Normal file
68
com/Unit/Create.lua
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
-- File com/Unit/Create.lua
|
||||||
|
--
|
||||||
|
-- Created at 2025-05-10 18:23
|
||||||
|
--
|
||||||
|
-- Updated at -
|
||||||
|
-- Description:
|
||||||
|
--- Creates a record in the unit.db database without
|
||||||
|
--- requiring additional permissions. Requires username,
|
||||||
|
--- password (hashing occurs at the server level), and email fields.
|
||||||
|
|
||||||
|
local log = require("internal.log")
|
||||||
|
local db = require("internal.database.sqlite").connect("db/unit.db", {log = true})
|
||||||
|
local session = require("internal.session")
|
||||||
|
local crypt = require("internal.crypt.bcrypt")
|
||||||
|
local sha256 = require("internal.crypt.sha256")
|
||||||
|
|
||||||
|
local common = require("com/Unit/_common")
|
||||||
|
local errors = require("com/Unit/_errors")
|
||||||
|
|
||||||
|
-- Preparing for first db query
|
||||||
|
local function close_db()
|
||||||
|
if db then
|
||||||
|
log.debug("Closing DB connection")
|
||||||
|
db:close()
|
||||||
|
db = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local params = session.request.params.get()
|
||||||
|
|
||||||
|
local ok, mp = common.CheckMissingElement({"username", "password", "email"}, params)
|
||||||
|
if not ok then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.MISSING_PARAMS.code, errors.MISSING_PARAMS.message, mp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local hashPass = crypt.generate(params.password, crypt.DefaultCost)
|
||||||
|
local unitID = string.sub(sha256.hash(session.__seed), 1, 16)
|
||||||
|
|
||||||
|
local ctx, err = db:exec(
|
||||||
|
"INSERT INTO units (user_id, username, email, password) VALUES (?, ?, ?, ?)",
|
||||||
|
{
|
||||||
|
unitID,
|
||||||
|
params.username,
|
||||||
|
params.email,
|
||||||
|
hashPass,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if err ~= nil then
|
||||||
|
log.error("Insert failed: "..tostring(err))
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.DB_INSERT_FAILED.code, errors.DB_INSERT_FAILED.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local _, err = ctx:wait()
|
||||||
|
if err ~= nil then
|
||||||
|
close_db()
|
||||||
|
if tostring(err):match("UNIQUE constraint failed") then
|
||||||
|
session.response.send_error(errors.UNIT_EXISTS.code, errors.UNIT_EXISTS.message)
|
||||||
|
else
|
||||||
|
log.error("Insert confirmation failed: "..tostring(err))
|
||||||
|
session.response.send_error()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
close_db()
|
||||||
|
session.response.send({unit_id = unitID})
|
||||||
77
com/Unit/Delete.lua
Normal file
77
com/Unit/Delete.lua
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
-- File com/Unit/Delete.lua
|
||||||
|
--
|
||||||
|
-- Created at 2025-05-10 19:18
|
||||||
|
--
|
||||||
|
-- Updated at -
|
||||||
|
|
||||||
|
local log = require("internal.log")
|
||||||
|
local db = require("internal.database.sqlite").connect("db/unit.db", {log = true})
|
||||||
|
local session = require("internal.session")
|
||||||
|
|
||||||
|
local common = require("com/Unit/_common")
|
||||||
|
local errors = require("com/Unit/_errors")
|
||||||
|
|
||||||
|
-- Preparing for first db query
|
||||||
|
local function close_db()
|
||||||
|
if db then
|
||||||
|
log.debug("Closing DB connection")
|
||||||
|
db:close()
|
||||||
|
db = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local params = session.request.params.get()
|
||||||
|
|
||||||
|
local ok, mp = common.CheckMissingElement({"user_id"}, params)
|
||||||
|
if not ok then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.MISSING_PARAMS.code, errors.MISSING_PARAMS.message, mp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local existing, err = db:query([[
|
||||||
|
SELECT 1
|
||||||
|
FROM units
|
||||||
|
WHERE user_id = ?
|
||||||
|
AND entry_status != 'deleted'
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
LIMIT 1
|
||||||
|
]], {
|
||||||
|
params.user_id
|
||||||
|
})
|
||||||
|
|
||||||
|
if err ~= nil then
|
||||||
|
log.error("Email check failed: "..tostring(err))
|
||||||
|
close_db()
|
||||||
|
session.response.send_error()
|
||||||
|
end
|
||||||
|
|
||||||
|
if existing and #existing == 0 then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.UNIT_NOT_FOUND.code, errors.UNIT_NOT_FOUND.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local ctx, err = db:exec(
|
||||||
|
[[
|
||||||
|
UPDATE units
|
||||||
|
SET entry_status = 'deleted',
|
||||||
|
deleted_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE user_id = ? AND deleted_at is NULL
|
||||||
|
]],
|
||||||
|
{ params.user_id }
|
||||||
|
)
|
||||||
|
|
||||||
|
if err ~= nil then
|
||||||
|
log.error("Soft delete failed: " .. tostring(err))
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.DB_DELETE_FAILED.code, errors.DB_DELETE_FAILED.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local res, err = ctx:wait()
|
||||||
|
if err ~= nil then
|
||||||
|
log.error("Soft delete confirmation failed: " .. tostring(err))
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.DB_DELETE_FAILED.code, errors.DB_DELETE_FAILED.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
close_db()
|
||||||
|
session.response.send()
|
||||||
55
com/Unit/Get.lua
Normal file
55
com/Unit/Get.lua
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
-- File com/Unit/Get.lua
|
||||||
|
--
|
||||||
|
-- Created at 2025-09-25 20:04
|
||||||
|
--
|
||||||
|
-- Updated at -
|
||||||
|
|
||||||
|
local log = require("internal.log")
|
||||||
|
local db = require("internal.database.sqlite").connect("db/unit.db", {log = true})
|
||||||
|
local session = require("internal.session")
|
||||||
|
|
||||||
|
local common = require("com/Unit/_common")
|
||||||
|
local errors = require("com/Unit/_errors")
|
||||||
|
|
||||||
|
-- Preparing for first db query
|
||||||
|
local function close_db()
|
||||||
|
if db then
|
||||||
|
log.debug("Closing DB connection")
|
||||||
|
db:close()
|
||||||
|
db = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local params = session.request.params.get()
|
||||||
|
|
||||||
|
local ok, mp = common.CheckMissingElement({"by", "value"}, params)
|
||||||
|
if not ok then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.MISSING_PARAMS.code, errors.MISSING_PARAMS.message, mp)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not (params.by == "email" or params.by == "username" or params.by == "user_id") then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.INVALID_BY_PARAM.code, errors.INVALID_BY_PARAM.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local unit, err = db:query_row(
|
||||||
|
"SELECT user_id, username, email, created_at, updated_at, deleted_at, entry_status FROM units WHERE "..params.by.." = ? AND deleted_at IS NULL LIMIT 1",
|
||||||
|
{
|
||||||
|
params.value
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if err then
|
||||||
|
close_db()
|
||||||
|
log.error("DB query error: " .. tostring(err))
|
||||||
|
session.response.send_error()
|
||||||
|
end
|
||||||
|
|
||||||
|
if not unit then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.UNIT_NOT_FOUND.code, errors.UNIT_NOT_FOUND.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
close_db()
|
||||||
|
session.response.send(unit)
|
||||||
102
com/Unit/Update.lua
Normal file
102
com/Unit/Update.lua
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
-- File com/Unit/Update.lua
|
||||||
|
--
|
||||||
|
-- Created at 2025-10-10
|
||||||
|
--
|
||||||
|
|
||||||
|
local log = require("internal.log")
|
||||||
|
local db = require("internal.database.sqlite").connect("db/unit.db", { log = true })
|
||||||
|
local session = require("internal.session")
|
||||||
|
|
||||||
|
local common = require("com/Unit/_common")
|
||||||
|
local errors = require("com/Unit/_errors")
|
||||||
|
|
||||||
|
local function close_db()
|
||||||
|
if db then
|
||||||
|
log.debug("Closing DB connection")
|
||||||
|
db:close()
|
||||||
|
db = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local params = session.request.params.get()
|
||||||
|
|
||||||
|
local ok, mp = common.CheckMissingElement({"user_id", "fields"}, params)
|
||||||
|
if not ok then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.MISSING_PARAMS.code, errors.MISSING_PARAMS.message, mp)
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(params.fields) ~= "table" or next(params.fields) == nil then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.INVALID_FIELD_TYPE.code, errors.INVALID_FIELD_TYPE.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local allowed = {
|
||||||
|
username = true,
|
||||||
|
email = true,
|
||||||
|
password = true,
|
||||||
|
entry_status = true
|
||||||
|
}
|
||||||
|
|
||||||
|
local exists = db:query_row(
|
||||||
|
"SELECT 1 FROM units WHERE user_id = ? AND deleted_at IS NULL LIMIT 1",
|
||||||
|
{ params.user_id }
|
||||||
|
)
|
||||||
|
|
||||||
|
if not exists then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.UNIT_NOT_FOUND.code, errors.UNIT_NOT_FOUND.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local set_clauses = {}
|
||||||
|
local values = {}
|
||||||
|
|
||||||
|
for k, v in pairs(params.fields) do
|
||||||
|
if allowed[k] then
|
||||||
|
if k == "password" then
|
||||||
|
local crypt = require("internal.crypt.bcrypt")
|
||||||
|
v = crypt.generate(v, crypt.DefaultCost)
|
||||||
|
end
|
||||||
|
table.insert(set_clauses, k .. " = ?")
|
||||||
|
table.insert(values, v)
|
||||||
|
else
|
||||||
|
log.warn("Ignoring unsupported field: " .. k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #set_clauses == 0 then
|
||||||
|
close_db()
|
||||||
|
session.response.send_error(errors.NO_VALID_FIELDS.code, errors.NO_VALID_FIELDS.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(set_clauses, "updated_at = CURRENT_TIMESTAMP")
|
||||||
|
|
||||||
|
local query = "UPDATE units SET " .. table.concat(set_clauses, ", ")
|
||||||
|
.. " WHERE user_id = ? AND deleted_at IS NULL"
|
||||||
|
|
||||||
|
table.insert(values, params.user_id)
|
||||||
|
|
||||||
|
local ctx, err = db:exec(query, values)
|
||||||
|
if not ctx then
|
||||||
|
close_db()
|
||||||
|
if tostring(err):match("UNIQUE constraint failed") then
|
||||||
|
session.response.send_error(errors.UNIQUE_CONSTRAINT.code, errors.UNIQUE_CONSTRAINT.message)
|
||||||
|
else
|
||||||
|
session.response.send_error()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local _, err = ctx:wait()
|
||||||
|
if err ~= nil then
|
||||||
|
close_db()
|
||||||
|
if tostring(err):match("UNIQUE constraint failed") then
|
||||||
|
session.response.send_error(errors.UNIQUE_CONSTRAINT.code, errors.UNIQUE_CONSTRAINT.message)
|
||||||
|
else
|
||||||
|
log.error("Insert confirmation failed: "..tostring(err))
|
||||||
|
session.response.send_error()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
close_db()
|
||||||
|
|
||||||
|
session.response.send()
|
||||||
23
com/Unit/_common.lua
Normal file
23
com/Unit/_common.lua
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
-- File com/Unit/_common.lua
|
||||||
|
--
|
||||||
|
-- Created at 2025-05-10 18:23
|
||||||
|
--
|
||||||
|
-- Updated at -
|
||||||
|
-- Description:
|
||||||
|
--- Common functions for Unit module
|
||||||
|
|
||||||
|
local common = {}
|
||||||
|
|
||||||
|
function common.CheckMissingElement(arr, cmp)
|
||||||
|
local is_missing = {}
|
||||||
|
local ok = true
|
||||||
|
for _, key in ipairs(arr) do
|
||||||
|
if cmp[key] == nil then
|
||||||
|
table.insert(is_missing, key)
|
||||||
|
ok = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ok, is_missing
|
||||||
|
end
|
||||||
|
|
||||||
|
return common
|
||||||
30
com/Unit/_errors.lua
Normal file
30
com/Unit/_errors.lua
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
-- File com/Unit/_errors.lua
|
||||||
|
--
|
||||||
|
-- Created at 2025-10-10
|
||||||
|
-- Description:
|
||||||
|
--- Centralized error definitions for Unit operations
|
||||||
|
--- to keep API responses consistent and clean.
|
||||||
|
|
||||||
|
local errors = {
|
||||||
|
-- Common validation
|
||||||
|
MISSING_PARAMS = { code = -32602, message = "Missing params" },
|
||||||
|
INVALID_FIELD_TYPE = { code = -32602, message = "'fields' must be a non-empty table" },
|
||||||
|
INVALID_BY_PARAM = { code = -32602, message = "Invalid 'by' param" },
|
||||||
|
NO_VALID_FIELDS = { code = -32604, message = "No valid fields to update" },
|
||||||
|
|
||||||
|
-- Existence / duplication
|
||||||
|
UNIT_NOT_FOUND = { code = -32102, message = "Unit is not exists" },
|
||||||
|
UNIT_EXISTS = { code = -32101, message = "Unit is already exists" },
|
||||||
|
|
||||||
|
-- Database & constraint
|
||||||
|
UNIQUE_CONSTRAINT = { code = -32602, message = "Unique constraint failed" },
|
||||||
|
DB_QUERY_FAILED = { code = -32001, message = "Database query failed" },
|
||||||
|
DB_EXEC_FAILED = { code = -32002, message = "Database execution failed" },
|
||||||
|
DB_INSERT_FAILED = { code = -32003, message = "Failed to create unit" },
|
||||||
|
DB_DELETE_FAILED = { code = -32004, message = "Failed to delete unit" },
|
||||||
|
|
||||||
|
-- Generic fallback
|
||||||
|
UNKNOWN = { code = -32099, message = "Unexpected internal error" },
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
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,119 +0,0 @@
|
|||||||
-- com/DeleteUnit.lua
|
|
||||||
|
|
||||||
---@diagnostic disable: redefined-local
|
|
||||||
local db = require("internal.database.sqlite").connect("db/user-database.db", {log = true})
|
|
||||||
local log = require("internal.log")
|
|
||||||
local session = require("internal.session")
|
|
||||||
local crypt = require("internal.crypt.bcrypt")
|
|
||||||
local jwt = require("internal.crypt.jwt")
|
|
||||||
local sha256 = require("internal.crypt.sha256")
|
|
||||||
|
|
||||||
local params = session.request.params.get()
|
|
||||||
local token = session.request.headers.get("authorization")
|
|
||||||
|
|
||||||
local function close_db()
|
|
||||||
if db then
|
|
||||||
db:close()
|
|
||||||
db = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function error_response(message, code, data)
|
|
||||||
session.response.error = {
|
|
||||||
code = code or nil,
|
|
||||||
message = message,
|
|
||||||
data = data or nil
|
|
||||||
}
|
|
||||||
close_db()
|
|
||||||
end
|
|
||||||
|
|
||||||
if not token or type(token) ~= "string" then
|
|
||||||
return error_response("Access denied")
|
|
||||||
end
|
|
||||||
|
|
||||||
local prefix = "Bearer "
|
|
||||||
if token:sub(1, #prefix) ~= prefix then
|
|
||||||
return error_response("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
|
|
||||||
session.response.error = {
|
|
||||||
message = err
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- if data.session_uuid ~= session.id then
|
|
||||||
-- return error_response("Access denied")
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- if data.key ~= sha256.sum(session.request.address .. session.id .. session.request.headers.get("user-agent", "noagent")) then
|
|
||||||
-- return error_response("Access denied")
|
|
||||||
-- end
|
|
||||||
|
|
||||||
if not params then
|
|
||||||
return error_response("no params provided")
|
|
||||||
end
|
|
||||||
|
|
||||||
if not (params.username and params.email and params.password) then
|
|
||||||
return error_response("no username/email/password provided")
|
|
||||||
end
|
|
||||||
|
|
||||||
local existing, err = db:query(
|
|
||||||
"SELECT password FROM users WHERE email = ? AND username = ? AND deleted = 0 LIMIT 1",
|
|
||||||
{
|
|
||||||
params.email,
|
|
||||||
params.username
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if err ~= nil then
|
|
||||||
log.error("Password fetch failed: " .. tostring(err))
|
|
||||||
return error_response("Database query failed: " .. tostring(err))
|
|
||||||
end
|
|
||||||
|
|
||||||
if not existing or #existing == 0 then
|
|
||||||
return error_response("Unit not found")
|
|
||||||
end
|
|
||||||
|
|
||||||
local hashed_password = existing[1].password
|
|
||||||
|
|
||||||
local ok = crypt.compare(hashed_password, params.password)
|
|
||||||
if not ok then
|
|
||||||
log.warn("Wrong password attempt for: " .. params.username)
|
|
||||||
return error_response("Invalid password")
|
|
||||||
end
|
|
||||||
|
|
||||||
local ctx, err = db:exec(
|
|
||||||
[[
|
|
||||||
UPDATE users
|
|
||||||
SET deleted = 1,
|
|
||||||
deleted_at = CURRENT_TIMESTAMP
|
|
||||||
WHERE email = ? AND username = ? AND deleted = 0
|
|
||||||
]],
|
|
||||||
{ params.email, params.username }
|
|
||||||
)
|
|
||||||
|
|
||||||
if err ~= nil then
|
|
||||||
log.error("Soft delete failed: " .. tostring(err))
|
|
||||||
return error_response("Soft delete failed: " .. tostring(err))
|
|
||||||
end
|
|
||||||
|
|
||||||
local res, err = ctx:wait()
|
|
||||||
if err ~= nil then
|
|
||||||
log.error("Soft delete confirmation failed: " .. tostring(err))
|
|
||||||
return error_response("Soft delete confirmation failed: " .. tostring(err))
|
|
||||||
end
|
|
||||||
|
|
||||||
session.response.result = {
|
|
||||||
rows_affected = res,
|
|
||||||
message = "Unit soft-deleted successfully"
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("user " .. params.username .. " soft-deleted successfully")
|
|
||||||
|
|
||||||
close_db()
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
-- com/GetAccess
|
|
||||||
|
|
||||||
---@diagnostic disable: redefined-local
|
|
||||||
local db = require("internal.database.sqlite").connect("db/user-database.db", {log = true})
|
|
||||||
local log = require("internal.log")
|
|
||||||
local session = require("internal.session")
|
|
||||||
local crypt = require("internal.crypt.bcrypt")
|
|
||||||
local jwt = require("internal.crypt.jwt")
|
|
||||||
local sha256 = require("internal.crypt.sha256")
|
|
||||||
|
|
||||||
local params = session.request.params.get()
|
|
||||||
local secret = require("_config").token()
|
|
||||||
|
|
||||||
local function close_db()
|
|
||||||
if db then
|
|
||||||
db:close()
|
|
||||||
db = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function error_response(message, code, data)
|
|
||||||
session.response.error = {
|
|
||||||
code = code or nil,
|
|
||||||
message = message,
|
|
||||||
data = data or nil
|
|
||||||
}
|
|
||||||
close_db()
|
|
||||||
end
|
|
||||||
|
|
||||||
if not params then
|
|
||||||
return error_response("No params provided")
|
|
||||||
end
|
|
||||||
|
|
||||||
if not (params.username and params.email and params.password) then
|
|
||||||
return error_response("Missing username, email or password")
|
|
||||||
end
|
|
||||||
|
|
||||||
local unit, err = db:query(
|
|
||||||
"SELECT id, username, email, password, created_at FROM users WHERE email = ? AND username = ? AND deleted = 0 LIMIT 1",
|
|
||||||
{
|
|
||||||
params.email,
|
|
||||||
params.username
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if err then
|
|
||||||
log.error("DB query error: " .. tostring(err))
|
|
||||||
return error_response("Database query failed")
|
|
||||||
end
|
|
||||||
|
|
||||||
if not unit or #unit == 0 then
|
|
||||||
return error_response("Unit not found")
|
|
||||||
end
|
|
||||||
|
|
||||||
unit = unit[1]
|
|
||||||
|
|
||||||
local ok = crypt.compare(unit.password, params.password)
|
|
||||||
if not ok then
|
|
||||||
log.warn("Login failed: wrong password for " .. params.username)
|
|
||||||
return error_response("Invalid password")
|
|
||||||
end
|
|
||||||
|
|
||||||
local token = jwt.encode({
|
|
||||||
secret = secret,
|
|
||||||
payload = { session_uuid = session.id,
|
|
||||||
admin_user = params.username,
|
|
||||||
key = sha256.sum(session.request.address .. session.id .. session.request.headers.get("user-agent", "noagent"))
|
|
||||||
},
|
|
||||||
expires_in = 3600
|
|
||||||
})
|
|
||||||
|
|
||||||
session.response.result = {
|
|
||||||
access_token = token
|
|
||||||
}
|
|
||||||
|
|
||||||
close_db()
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
-- com/PutNewUnit.lua
|
|
||||||
|
|
||||||
---@diagnostic disable: redefined-local
|
|
||||||
local db = require("internal.database.sqlite").connect("db/user-database.db", {log = true})
|
|
||||||
local log = require("internal.log")
|
|
||||||
local session = require("internal.session")
|
|
||||||
local crypt = require("internal.crypt.bcrypt")
|
|
||||||
local jwt = require("internal.crypt.jwt")
|
|
||||||
local sha256 = require("internal.crypt.sha256")
|
|
||||||
|
|
||||||
local params = session.request.params.get()
|
|
||||||
local token = session.request.headers.get("authorization")
|
|
||||||
|
|
||||||
local function close_db()
|
|
||||||
if db then
|
|
||||||
db:close()
|
|
||||||
db = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function error_response(message, code, data)
|
|
||||||
session.response.error = {
|
|
||||||
code = code or nil,
|
|
||||||
message = message,
|
|
||||||
data = data or nil
|
|
||||||
}
|
|
||||||
close_db()
|
|
||||||
end
|
|
||||||
|
|
||||||
if not token or type(token) ~= "string" then
|
|
||||||
return error_response("Access denied")
|
|
||||||
end
|
|
||||||
|
|
||||||
local prefix = "Bearer "
|
|
||||||
if token:sub(1, #prefix) ~= prefix then
|
|
||||||
return error_response("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
|
|
||||||
session.response.error = {
|
|
||||||
message = err
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if data.session_uuid ~= session.id then
|
|
||||||
return error_response("Access denied")
|
|
||||||
end
|
|
||||||
|
|
||||||
if data.key ~= sha256.sum(session.request.address .. session.id .. session.request.headers.get("user-agent", "noagent")) then
|
|
||||||
return error_response("Access denied")
|
|
||||||
end
|
|
||||||
|
|
||||||
if not params then
|
|
||||||
return error_response("no params provided")
|
|
||||||
end
|
|
||||||
|
|
||||||
if not (params.username and params.email and params.password) then
|
|
||||||
return error_response("no username/email/password provided")
|
|
||||||
end
|
|
||||||
|
|
||||||
local hashPass = crypt.generate(params.password, crypt.DefaultCost)
|
|
||||||
|
|
||||||
local existing, err = db:query("SELECT 1 FROM users WHERE deleted = 0 AND (email = ? OR username = ?) LIMIT 1", {
|
|
||||||
params.email,
|
|
||||||
params.username
|
|
||||||
})
|
|
||||||
|
|
||||||
if err ~= nil then
|
|
||||||
log.error("Email check failed: "..tostring(err))
|
|
||||||
return error_response("Database check failed: "..tostring(err))
|
|
||||||
end
|
|
||||||
|
|
||||||
if existing and #existing > 0 then
|
|
||||||
return error_response("Unit already exists")
|
|
||||||
end
|
|
||||||
|
|
||||||
local ctx, err = db:exec(
|
|
||||||
"INSERT INTO users (username, email, password, first_name, last_name, phone_number) VALUES (?, ?, ?, ?, ?, ?)",
|
|
||||||
{
|
|
||||||
params.username,
|
|
||||||
params.email,
|
|
||||||
hashPass,
|
|
||||||
params.first_name or "",
|
|
||||||
params.last_name or "",
|
|
||||||
params.phone_number or ""
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if err ~= nil then
|
|
||||||
log.error("Insert failed: "..tostring(err))
|
|
||||||
return error_response("Insert failed: "..tostring(err))
|
|
||||||
end
|
|
||||||
|
|
||||||
local res, err = ctx:wait()
|
|
||||||
if err ~= nil then
|
|
||||||
log.error("Insert confirmation failed: "..tostring(err))
|
|
||||||
return error_response("Insert confirmation failed: "..tostring(err))
|
|
||||||
end
|
|
||||||
|
|
||||||
session.response.result = {
|
|
||||||
rows_affected = res,
|
|
||||||
message = "Unit created successfully"
|
|
||||||
}
|
|
||||||
|
|
||||||
close_db()
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
---@diagnostic disable: redefined-local
|
|
||||||
local db = require("internal.database-sqlite").connect("db/test.db", {log = true})
|
|
||||||
local log = require("internal.log")
|
|
||||||
local session = require("internal.session")
|
|
||||||
|
|
||||||
if not (session.request.params.name and session.request.params.email) then
|
|
||||||
session.response.error = {
|
|
||||||
code = -32602,
|
|
||||||
message = "Name and email are required"
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local existing, err = db:query("SELECT 1 FROM users WHERE email = ? LIMIT 1", {
|
|
||||||
session.request.params.email
|
|
||||||
})
|
|
||||||
if err ~= nil then
|
|
||||||
session.response.error = {
|
|
||||||
code = -32603,
|
|
||||||
message = "Database check failed: "..tostring(err)
|
|
||||||
}
|
|
||||||
log.error("Email check failed: "..tostring(err))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if existing and #existing > 0 then
|
|
||||||
session.response.error = {
|
|
||||||
code = -32604,
|
|
||||||
message = "Email already exists"
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local ctx, err = db:exec(
|
|
||||||
"INSERT INTO users (name, email) VALUES (?, ?)",
|
|
||||||
{
|
|
||||||
session.request.params.name,
|
|
||||||
session.request.params.email
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if err ~= nil then
|
|
||||||
session.response.error = {
|
|
||||||
code = -32605,
|
|
||||||
message = "Insert failed: "..tostring(err)
|
|
||||||
}
|
|
||||||
log.error("Insert failed: "..tostring(err))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local res, err = ctx:wait()
|
|
||||||
if err ~= nil then
|
|
||||||
session.response.error = {
|
|
||||||
code = -32606,
|
|
||||||
message = "Insert confirmation failed: "..tostring(err)
|
|
||||||
}
|
|
||||||
log.error("Insert confirmation failed: "..tostring(err))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
session.response.result = {
|
|
||||||
success = true,
|
|
||||||
rows_affected = res,
|
|
||||||
message = "User created successfully"
|
|
||||||
}
|
|
||||||
|
|
||||||
db:close()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
local session = require("internal.session")
|
|
||||||
local net = require("internal.net")
|
|
||||||
|
|
||||||
local reqAddr
|
|
||||||
local logReq = true
|
|
||||||
|
|
||||||
if session.request.params and session.request.params.url then
|
|
||||||
reqAddr = session.request.params.url
|
|
||||||
else
|
|
||||||
session.response.error = {
|
|
||||||
code = -32602,
|
|
||||||
message = "no url provided"
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local resp = net.http.get_request(logReq, reqAddr)
|
|
||||||
if resp then
|
|
||||||
session.response.result.answer = {
|
|
||||||
status = resp.status,
|
|
||||||
body = resp.body
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
session.response.error = {
|
|
||||||
data = "error while requesting"
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
local session = require("internal.session")
|
|
||||||
local net = require("internal.net")
|
|
||||||
local log = require("internal.log")
|
|
||||||
|
|
||||||
local reqAddr
|
|
||||||
local logReq = true
|
|
||||||
local payload
|
|
||||||
|
|
||||||
log.debug(session.request.params)
|
|
||||||
|
|
||||||
if not (session.request.params and session.request.params.url) then
|
|
||||||
session.response.error = {
|
|
||||||
code = -32602,
|
|
||||||
message = "no url or payload provided"
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
reqAddr = session.request.params.url
|
|
||||||
payload = session.request.params.payload
|
|
||||||
|
|
||||||
local resp = net.http.post_request(logReq, reqAddr, "application/json", payload)
|
|
||||||
if resp then
|
|
||||||
session.response.result.answer = {
|
|
||||||
status = resp.status,
|
|
||||||
body = resp.body
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
session.response.error = {
|
|
||||||
data = "error while requesting"
|
|
||||||
}
|
|
||||||
@@ -7,9 +7,9 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/hooks"
|
"github.com/akyaiy/GoSally-mvp/src/hooks"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/colors"
|
"github.com/akyaiy/GoSally-mvp/src/internal/colors"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/corestate"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/akyaiy/GoSally-mvp/hooks"
|
"github.com/akyaiy/GoSally-mvp/src/hooks"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/config"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module github.com/akyaiy/GoSally-mvp
|
module github.com/akyaiy/GoSally-mvp/src
|
||||||
|
|
||||||
go 1.24.4
|
go 1.24.4
|
||||||
|
|
||||||
@@ -13,8 +13,6 @@ github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE=
|
|||||||
github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
@@ -18,13 +18,13 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/colors"
|
"github.com/akyaiy/GoSally-mvp/src/internal/colors"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/corestate"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/run_manager"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/run_manager"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/utils"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/utils"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/app"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/app"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/config"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/logs"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/logs"
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -11,17 +11,17 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/colors"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/corestate"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/src/internal/colors"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/run_manager"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/run_manager"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/update"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/update"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/utils"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/utils"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/app"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/app"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/config"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/logs"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/logs"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/gateway"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/gateway"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/session"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/session"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/sv1"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/sv1"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/cors"
|
"github.com/go-chi/cors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var NodeApp = app.New()
|
var NodeApp = app.New()
|
||||||
|
var AllowedCmdPattern = `^[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*$`
|
||||||
|
|
||||||
func Run(cmd *cobra.Command, args []string) {
|
func Run(cmd *cobra.Command, args []string) {
|
||||||
NodeApp.InitialHooks(
|
NodeApp.InitialHooks(
|
||||||
@@ -60,7 +61,7 @@ func RunHook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) error {
|
|||||||
serverv1 := sv1.InitV1Server(&sv1.HandlerV1InitStruct{
|
serverv1 := sv1.InitV1Server(&sv1.HandlerV1InitStruct{
|
||||||
X: x,
|
X: x,
|
||||||
CS: cs,
|
CS: cs,
|
||||||
AllowedCmd: regexp.MustCompile(`^[a-zA-Z0-9]+(>[a-zA-Z0-9]+)*$`),
|
AllowedCmd: regexp.MustCompile(AllowedCmdPattern),
|
||||||
Ver: "v1",
|
Ver: "v1",
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/utils"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/utils"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetNodeUUID outputs the correct uuid from the file at the path specified in the arguments.
|
// GetNodeUUID outputs the correct uuid from the file at the path specified in the arguments.
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/utils"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RunManagerContract interface {
|
type RunManagerContract interface {
|
||||||
@@ -13,10 +13,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/run_manager"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/run_manager"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/utils"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/utils"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/app"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/app"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/config"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewUUIDRaw(length int) ([]byte, error) {
|
func NewUUIDRaw(length int) ([]byte, error) {
|
||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/corestate"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AppContract interface {
|
type AppContract interface {
|
||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/colors"
|
"github.com/akyaiy/GoSally-mvp/src/internal/colors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Compositor) Print(v any) {
|
func (c *Compositor) Print(v any) {
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/config"
|
||||||
"gopkg.in/natefinch/lumberjack.v2"
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -3,9 +3,9 @@ package lua
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/corestate"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/app"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/app"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LuaEngineDeps struct {
|
type LuaEngineDeps struct {
|
||||||
@@ -4,10 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/corestate"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/app"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/app"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/rpc"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/session"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
// serversApiVer is a type alias for string, used to represent API version strings in the GeneralServer.
|
// serversApiVer is a type alias for string, used to represent API version strings in the GeneralServer.
|
||||||
@@ -3,9 +3,9 @@ package gateway
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/corestate"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/app"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/app"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/session"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GeneralServerInit structure only for initialization general server.
|
// GeneralServerInit structure only for initialization general server.
|
||||||
@@ -8,8 +8,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/utils"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/utils"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/rpc"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/corestate"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -37,7 +37,9 @@ func NewError(code int, message string, data any, id *json.RawMessage) *RPCRespo
|
|||||||
Error = map[string]any{
|
Error = map[string]any{
|
||||||
"code": code,
|
"code": code,
|
||||||
"message": message,
|
"message": message,
|
||||||
"data": data,
|
}
|
||||||
|
if data != nil {
|
||||||
|
Error["data"] = data
|
||||||
}
|
}
|
||||||
|
|
||||||
return &RPCResponse{
|
return &RPCResponse{
|
||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *HandlerV1) Handle(_ context.Context, sid string, r *http.Request, req *rpc.RPCRequest) *rpc.RPCResponse {
|
func (h *HandlerV1) Handle(_ context.Context, sid string, r *http.Request, req *rpc.RPCRequest) *rpc.RPCResponse {
|
||||||
@@ -17,8 +17,8 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/colors"
|
"github.com/akyaiy/GoSally-mvp/src/internal/colors"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/rpc"
|
||||||
lua "github.com/yuin/gopher-lua"
|
lua "github.com/yuin/gopher-lua"
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
)
|
)
|
||||||
@@ -186,11 +186,6 @@ func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest,
|
|||||||
L.SetField(scriptDataTable, "result", resTable)
|
L.SetField(scriptDataTable, "result", resTable)
|
||||||
L.SetField(outTable, "send", L.NewFunction(func(L *lua.LState) int {
|
L.SetField(outTable, "send", L.NewFunction(func(L *lua.LState) int {
|
||||||
res := L.Get(1)
|
res := L.Get(1)
|
||||||
if res == lua.LNil {
|
|
||||||
__exit = 0
|
|
||||||
L.RaiseError("__successfull")
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
resFTable := scriptDataTable.RawGetString("result")
|
resFTable := scriptDataTable.RawGetString("result")
|
||||||
if resPTable, ok := res.(*lua.LTable); ok {
|
if resPTable, ok := res.(*lua.LTable); ok {
|
||||||
@@ -542,7 +537,7 @@ func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest,
|
|||||||
llog.Debug("import module crypt.sha256", slog.String("script", path))
|
llog.Debug("import module crypt.sha256", slog.String("script", path))
|
||||||
sha265mod := L.NewTable()
|
sha265mod := L.NewTable()
|
||||||
|
|
||||||
L.SetField(sha265mod, "sum", L.NewFunction(func(l *lua.LState) int {
|
L.SetField(sha265mod, "hash", L.NewFunction(func(l *lua.LState) int {
|
||||||
data := ConvertLuaTypesToGolang(L.Get(1))
|
data := ConvertLuaTypesToGolang(L.Get(1))
|
||||||
var dataStr = fmt.Sprint(data)
|
var dataStr = fmt.Sprint(data)
|
||||||
|
|
||||||
@@ -6,15 +6,17 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
"github.com/akyaiy/GoSally-mvp/src/internal/server/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var RPCMethodSeparator = "."
|
||||||
|
|
||||||
func (h *HandlerV1) resolveMethodPath(method string) (string, error) {
|
func (h *HandlerV1) resolveMethodPath(method string) (string, error) {
|
||||||
if !h.allowedCmd.MatchString(method) {
|
if !h.allowedCmd.MatchString(method) {
|
||||||
return "", errors.New(rpc.ErrInvalidMethodFormatS)
|
return "", errors.New(rpc.ErrInvalidMethodFormatS)
|
||||||
}
|
}
|
||||||
|
|
||||||
parts := strings.Split(method, ">")
|
parts := strings.Split(method, RPCMethodSeparator)
|
||||||
relPath := filepath.Join(parts...) + ".lua"
|
relPath := filepath.Join(parts...) + ".lua"
|
||||||
fullPath := filepath.Join(*h.x.Config.Conf.Node.ComDir, relPath)
|
fullPath := filepath.Join(*h.x.Config.Conf.Node.ComDir, relPath)
|
||||||
|
|
||||||
@@ -5,8 +5,8 @@ package sv1
|
|||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/src/internal/core/corestate"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/app"
|
"github.com/akyaiy/GoSally-mvp/src/internal/engine/app"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandlerV1InitStruct structure is only for initialization
|
// HandlerV1InitStruct structure is only for initialization
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/akyaiy/GoSally-mvp/cmd"
|
"github.com/akyaiy/GoSally-mvp/src/cmd"
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
Reference in New Issue
Block a user