From a71fde67e4b20a629b0e854b7fc854e0ad907065 Mon Sep 17 00:00:00 2001 From: d3m0k1d Date: Sat, 4 Apr 2026 18:49:05 +0300 Subject: [PATCH] fix: user reg --- backend/cmd/main.go | 3 +- backend/docs/docs.go | 706 ++++++++++++++++++---- backend/docs/swagger.json | 706 ++++++++++++++++++---- backend/docs/swagger.yaml | 495 ++++++++++++--- backend/internal/handlers/auth.go | 31 + backend/internal/handlers/scripts.go | 30 +- backend/internal/repository/models.go | 8 + backend/internal/repository/repository.go | 28 + infra/agent/config.yml | 2 +- 9 files changed, 1647 insertions(+), 362 deletions(-) diff --git a/backend/cmd/main.go b/backend/cmd/main.go index 26e87a1..c4cb983 100644 --- a/backend/cmd/main.go +++ b/backend/cmd/main.go @@ -144,13 +144,14 @@ func main() { authGroup := v1.Group("/auth") { authGroup.POST("/login", auth.Login) + authGroup.POST("/register", auth.RegisterUser) } // Auth token management (requires auth) authTokenGroup := v1.Group("/auth") authTokenGroup.Use(auth.AuthMiddleware()) { - authTokenGroup.POST("/token", handlers.RequireAdmin(), auth.CreateToken) + authTokenGroup.POST("/token") authTokenGroup.GET("/validate", auth.ValidateToken) authTokenGroup.GET("/tokens", handlers.RequireAdmin(), auth.ListTokens) authTokenGroup.DELETE("/token", auth.DeleteMyToken) diff --git a/backend/docs/docs.go b/backend/docs/docs.go index d7c99de..5cbdbb6 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -36,7 +36,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/handlers.AgentInfo" + "$ref": "#/definitions/internal_handlers.AgentInfo" } } } @@ -68,7 +68,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.DeployAgentsRequest" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployAgentsRequest" } } ], @@ -76,7 +76,7 @@ const docTemplate = `{ "200": { "description": "Deployment results with tokens for each server", "schema": { - "$ref": "#/definitions/repository.DeployResponse" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResponse" } }, "400": { @@ -119,7 +119,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/handlers.RegisterRequest" + "$ref": "#/definitions/internal_handlers.RegisterRequest" } } ], @@ -127,7 +127,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handlers.RegisterResponse" + "$ref": "#/definitions/internal_handlers.RegisterResponse" } } } @@ -157,7 +157,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.RegistrationRequest" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.RegistrationRequest" } } ], @@ -191,7 +191,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.LoginRequest" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest" } } ], @@ -199,7 +199,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/repository.LoginResponse" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse" } }, "400": { @@ -232,6 +232,67 @@ const docTemplate = `{ } } }, + "/auth/register": { + "post": { + "description": "Registers a new user with login, password, name, last name. All permissions are set to false.", + "consumes": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Register user", + "parameters": [ + { + "description": "Registration data", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.UserRegister" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "409": { + "description": "Conflict", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, "/auth/token": { "post": { "description": "Creates a new user with permissions", @@ -249,7 +310,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.TokenCreate" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate" } } ], @@ -345,7 +406,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/repository.Tokens" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" } } }, @@ -431,7 +492,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/repository.Tokens" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" } }, "400": { @@ -486,7 +547,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.TokenUpdate" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdate" } } ], @@ -666,7 +727,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.TokenPasswordReset" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenPasswordReset" } } ], @@ -734,7 +795,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.TokenUpdatePermissions" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdatePermissions" } } ], @@ -794,7 +855,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/repository.Tokens" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" } } }, @@ -824,7 +885,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/repository.Tokens" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" } }, "401": { @@ -839,6 +900,40 @@ const docTemplate = `{ } } }, + "/jobs": { + "post": { + "description": "Sends a command to the specified agent, waits for execution, and returns the result", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "jobs" + ], + "summary": "Create and run a job on an agent", + "parameters": [ + { + "description": "Job request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/internal_handlers.AddJobIn" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/internal_handlers.AddJobOut" + } + } + } + } + }, "/logs": { "get": { "security": [ @@ -906,7 +1001,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/storage.LogEntry" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry" } } } @@ -936,7 +1031,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/handlers.InsertLogRequest" + "$ref": "#/definitions/internal_handlers.InsertLogRequest" } } ], @@ -1006,7 +1101,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/handlers.InsertLogsRequest" + "$ref": "#/definitions/internal_handlers.InsertLogsRequest" } } ], @@ -1106,7 +1201,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/storage.LogEntry" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry" } } } @@ -1140,96 +1235,188 @@ const docTemplate = `{ } } } + }, + "/scripts/interpreters": { + "get": { + "description": "Returns all script interpreters available in the system", + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "List interpreters", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter" + } + } + } + } + }, + "post": { + "description": "Registers a new script interpreter with name, label, and argv", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "Create interpreter", + "parameters": [ + { + "description": "Interpreter definition", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterCreate" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter" + } + } + } + } + }, + "/scripts/interpreters/:id": { + "get": { + "description": "Returns a script interpreter by ID", + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "Get interpreter", + "parameters": [ + { + "type": "integer", + "description": "Interpreter ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter" + } + } + } + }, + "put": { + "description": "Updates fields of a script interpreter", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "Update interpreter", + "parameters": [ + { + "type": "integer", + "description": "Interpreter ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Interpreter fields", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter" + } + } + } + }, + "delete": { + "description": "Removes a script interpreter by ID", + "tags": [ + "scripts" + ], + "summary": "Delete interpreter", + "parameters": [ + { + "type": "integer", + "description": "Interpreter ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/scripts/run": { + "post": { + "description": "Resolves interpreter argv[] and sends the full command to the agent", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "Run a script on an agent", + "parameters": [ + { + "description": "Script request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/internal_handlers.RunScriptIn" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/internal_handlers.RunScriptOut" + } + } + } + } } }, "definitions": { - "handlers.AgentInfo": { - "type": "object", - "properties": { - "connected_at": { - "type": "string" - }, - "label": { - "type": "string" - }, - "services": { - "type": "array", - "items": { - "type": "string" - } - }, - "token": { - "type": "string" - } - } - }, - "handlers.InsertLogRequest": { - "type": "object", - "required": [ - "agent", - "level", - "message", - "service" - ], - "properties": { - "agent": { - "type": "string" - }, - "level": { - "type": "string" - }, - "message": { - "type": "string" - }, - "service": { - "type": "string" - }, - "timestamp": { - "type": "string" - } - } - }, - "handlers.InsertLogsRequest": { - "type": "object", - "required": [ - "logs" - ], - "properties": { - "logs": { - "type": "array", - "items": { - "$ref": "#/definitions/handlers.InsertLogRequest" - } - } - } - }, - "handlers.RegisterRequest": { - "type": "object", - "required": [ - "csr", - "token" - ], - "properties": { - "csr": { - "type": "string" - }, - "token": { - "type": "string" - } - } - }, - "handlers.RegisterResponse": { - "type": "object", - "properties": { - "ca_cert": { - "type": "string" - }, - "client_cert": { - "type": "string" - } - } - }, - "repository.AgentDeployConfig": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AgentDeployConfig": { "description": "Configuration for deploying HellreigN agent to a single server", "type": "object", "required": [ @@ -1247,7 +1434,7 @@ const docTemplate = `{ "authMethod": { "allOf": [ { - "$ref": "#/definitions/repository.AuthMethod" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AuthMethod" } ], "example": "key" @@ -1255,7 +1442,7 @@ const docTemplate = `{ "deployType": { "allOf": [ { - "$ref": "#/definitions/repository.DeployType" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployType" } ], "example": "docker" @@ -1282,7 +1469,7 @@ const docTemplate = `{ } } }, - "repository.AuthMethod": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AuthMethod": { "description": "SSH authentication method: key or password", "type": "string", "enum": [ @@ -1294,7 +1481,7 @@ const docTemplate = `{ "AuthMethodPassword" ] }, - "repository.DeployAgentsRequest": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployAgentsRequest": { "description": "Request to deploy HellreigN agents to multiple servers", "type": "object", "required": [ @@ -1305,12 +1492,12 @@ const docTemplate = `{ "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/repository.AgentDeployConfig" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AgentDeployConfig" } } } }, - "repository.DeployResponse": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResponse": { "description": "Response containing deployment results and registration tokens", "type": "object", "properties": { @@ -1321,12 +1508,12 @@ const docTemplate = `{ "results": { "type": "array", "items": { - "$ref": "#/definitions/repository.DeployResult" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResult" } } } }, - "repository.DeployResult": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResult": { "description": "Result of deploying to a single server", "type": "object", "properties": { @@ -1352,7 +1539,7 @@ const docTemplate = `{ } } }, - "repository.DeployType": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployType": { "description": "Type of deployment: docker or binary", "type": "string", "enum": [ @@ -1364,7 +1551,7 @@ const docTemplate = `{ "DeployTypeBinary" ] }, - "repository.LoginRequest": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest": { "type": "object", "required": [ "login", @@ -1379,7 +1566,7 @@ const docTemplate = `{ } } }, - "repository.LoginResponse": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse": { "type": "object", "properties": { "is_active": { @@ -1408,7 +1595,7 @@ const docTemplate = `{ } } }, - "repository.RegistrationRequest": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.RegistrationRequest": { "type": "object", "required": [ "label" @@ -1419,7 +1606,72 @@ const docTemplate = `{ } } }, - "repository.TokenCreate": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter": { + "type": "object", + "properties": { + "argv": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterCreate": { + "type": "object", + "required": [ + "argv", + "label", + "name" + ], + "properties": { + "argv": { + "type": "array", + "items": { + "type": "string" + } + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterUpdate": { + "type": "object", + "properties": { + "argv": { + "type": "array", + "items": { + "type": "string" + } + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate": { "type": "object", "required": [ "last_name", @@ -1454,7 +1706,7 @@ const docTemplate = `{ } } }, - "repository.TokenPasswordReset": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenPasswordReset": { "type": "object", "required": [ "new_password" @@ -1465,7 +1717,7 @@ const docTemplate = `{ } } }, - "repository.TokenUpdate": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdate": { "type": "object", "properties": { "last_name": { @@ -1476,7 +1728,7 @@ const docTemplate = `{ } } }, - "repository.TokenUpdatePermissions": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdatePermissions": { "type": "object", "properties": { "is_active": { @@ -1493,7 +1745,7 @@ const docTemplate = `{ } } }, - "repository.Tokens": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens": { "type": "object", "properties": { "id": { @@ -1525,7 +1777,30 @@ const docTemplate = `{ } } }, - "storage.LogEntry": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.UserRegister": { + "type": "object", + "required": [ + "last_name", + "login", + "name", + "password" + ], + "properties": { + "last_name": { + "type": "string" + }, + "login": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry": { "type": "object", "properties": { "agent": { @@ -1544,6 +1819,187 @@ const docTemplate = `{ "type": "string" } } + }, + "internal_handlers.AddJobIn": { + "type": "object", + "required": [ + "agent_id", + "command" + ], + "properties": { + "agent_id": { + "type": "string" + }, + "command": { + "type": "string" + }, + "interpreter_id": { + "type": "integer" + }, + "stdin": { + "type": "string" + } + } + }, + "internal_handlers.AddJobOut": { + "type": "object", + "properties": { + "command": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "status": { + "type": "integer" + }, + "stderr": { + "type": "string" + }, + "stdin": { + "type": "string" + }, + "stdout": { + "type": "string" + } + } + }, + "internal_handlers.AgentInfo": { + "type": "object", + "properties": { + "connected_at": { + "type": "string" + }, + "label": { + "type": "string" + }, + "services": { + "type": "array", + "items": { + "type": "string" + } + }, + "token": { + "type": "string" + } + } + }, + "internal_handlers.InsertLogRequest": { + "type": "object", + "required": [ + "agent", + "level", + "message", + "service" + ], + "properties": { + "agent": { + "type": "string" + }, + "level": { + "type": "string" + }, + "message": { + "type": "string" + }, + "service": { + "type": "string" + }, + "timestamp": { + "type": "string" + } + } + }, + "internal_handlers.InsertLogsRequest": { + "type": "object", + "required": [ + "logs" + ], + "properties": { + "logs": { + "type": "array", + "items": { + "$ref": "#/definitions/internal_handlers.InsertLogRequest" + } + } + } + }, + "internal_handlers.RegisterRequest": { + "type": "object", + "required": [ + "csr", + "token" + ], + "properties": { + "csr": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "internal_handlers.RegisterResponse": { + "type": "object", + "properties": { + "ca_cert": { + "type": "string" + }, + "client_cert": { + "type": "string" + } + } + }, + "internal_handlers.RunScriptIn": { + "type": "object", + "required": [ + "agent_id", + "interpreter_id", + "script_text" + ], + "properties": { + "agent_id": { + "type": "string" + }, + "interpreter_id": { + "type": "integer" + }, + "script_text": { + "type": "string" + }, + "stdin": { + "type": "string" + } + } + }, + "internal_handlers.RunScriptOut": { + "type": "object", + "properties": { + "command": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "status": { + "type": "integer" + }, + "stderr": { + "type": "string" + }, + "stdin": { + "type": "string" + }, + "stdout": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 3c8cb04..34e524a 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -25,7 +25,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/handlers.AgentInfo" + "$ref": "#/definitions/internal_handlers.AgentInfo" } } } @@ -57,7 +57,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.DeployAgentsRequest" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployAgentsRequest" } } ], @@ -65,7 +65,7 @@ "200": { "description": "Deployment results with tokens for each server", "schema": { - "$ref": "#/definitions/repository.DeployResponse" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResponse" } }, "400": { @@ -108,7 +108,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/handlers.RegisterRequest" + "$ref": "#/definitions/internal_handlers.RegisterRequest" } } ], @@ -116,7 +116,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handlers.RegisterResponse" + "$ref": "#/definitions/internal_handlers.RegisterResponse" } } } @@ -146,7 +146,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.RegistrationRequest" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.RegistrationRequest" } } ], @@ -180,7 +180,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.LoginRequest" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest" } } ], @@ -188,7 +188,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/repository.LoginResponse" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse" } }, "400": { @@ -221,6 +221,67 @@ } } }, + "/auth/register": { + "post": { + "description": "Registers a new user with login, password, name, last name. All permissions are set to false.", + "consumes": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Register user", + "parameters": [ + { + "description": "Registration data", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.UserRegister" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "409": { + "description": "Conflict", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, "/auth/token": { "post": { "description": "Creates a new user with permissions", @@ -238,7 +299,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.TokenCreate" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate" } } ], @@ -334,7 +395,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/repository.Tokens" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" } } }, @@ -420,7 +481,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/repository.Tokens" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" } }, "400": { @@ -475,7 +536,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.TokenUpdate" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdate" } } ], @@ -655,7 +716,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.TokenPasswordReset" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenPasswordReset" } } ], @@ -723,7 +784,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/repository.TokenUpdatePermissions" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdatePermissions" } } ], @@ -783,7 +844,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/repository.Tokens" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" } } }, @@ -813,7 +874,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/repository.Tokens" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens" } }, "401": { @@ -828,6 +889,40 @@ } } }, + "/jobs": { + "post": { + "description": "Sends a command to the specified agent, waits for execution, and returns the result", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "jobs" + ], + "summary": "Create and run a job on an agent", + "parameters": [ + { + "description": "Job request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/internal_handlers.AddJobIn" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/internal_handlers.AddJobOut" + } + } + } + } + }, "/logs": { "get": { "security": [ @@ -895,7 +990,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/storage.LogEntry" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry" } } } @@ -925,7 +1020,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/handlers.InsertLogRequest" + "$ref": "#/definitions/internal_handlers.InsertLogRequest" } } ], @@ -995,7 +1090,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/handlers.InsertLogsRequest" + "$ref": "#/definitions/internal_handlers.InsertLogsRequest" } } ], @@ -1095,7 +1190,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/storage.LogEntry" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry" } } } @@ -1129,96 +1224,188 @@ } } } + }, + "/scripts/interpreters": { + "get": { + "description": "Returns all script interpreters available in the system", + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "List interpreters", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter" + } + } + } + } + }, + "post": { + "description": "Registers a new script interpreter with name, label, and argv", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "Create interpreter", + "parameters": [ + { + "description": "Interpreter definition", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterCreate" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter" + } + } + } + } + }, + "/scripts/interpreters/:id": { + "get": { + "description": "Returns a script interpreter by ID", + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "Get interpreter", + "parameters": [ + { + "type": "integer", + "description": "Interpreter ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter" + } + } + } + }, + "put": { + "description": "Updates fields of a script interpreter", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "Update interpreter", + "parameters": [ + { + "type": "integer", + "description": "Interpreter ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Interpreter fields", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter" + } + } + } + }, + "delete": { + "description": "Removes a script interpreter by ID", + "tags": [ + "scripts" + ], + "summary": "Delete interpreter", + "parameters": [ + { + "type": "integer", + "description": "Interpreter ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/scripts/run": { + "post": { + "description": "Resolves interpreter argv[] and sends the full command to the agent", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "scripts" + ], + "summary": "Run a script on an agent", + "parameters": [ + { + "description": "Script request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/internal_handlers.RunScriptIn" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/internal_handlers.RunScriptOut" + } + } + } + } } }, "definitions": { - "handlers.AgentInfo": { - "type": "object", - "properties": { - "connected_at": { - "type": "string" - }, - "label": { - "type": "string" - }, - "services": { - "type": "array", - "items": { - "type": "string" - } - }, - "token": { - "type": "string" - } - } - }, - "handlers.InsertLogRequest": { - "type": "object", - "required": [ - "agent", - "level", - "message", - "service" - ], - "properties": { - "agent": { - "type": "string" - }, - "level": { - "type": "string" - }, - "message": { - "type": "string" - }, - "service": { - "type": "string" - }, - "timestamp": { - "type": "string" - } - } - }, - "handlers.InsertLogsRequest": { - "type": "object", - "required": [ - "logs" - ], - "properties": { - "logs": { - "type": "array", - "items": { - "$ref": "#/definitions/handlers.InsertLogRequest" - } - } - } - }, - "handlers.RegisterRequest": { - "type": "object", - "required": [ - "csr", - "token" - ], - "properties": { - "csr": { - "type": "string" - }, - "token": { - "type": "string" - } - } - }, - "handlers.RegisterResponse": { - "type": "object", - "properties": { - "ca_cert": { - "type": "string" - }, - "client_cert": { - "type": "string" - } - } - }, - "repository.AgentDeployConfig": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AgentDeployConfig": { "description": "Configuration for deploying HellreigN agent to a single server", "type": "object", "required": [ @@ -1236,7 +1423,7 @@ "authMethod": { "allOf": [ { - "$ref": "#/definitions/repository.AuthMethod" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AuthMethod" } ], "example": "key" @@ -1244,7 +1431,7 @@ "deployType": { "allOf": [ { - "$ref": "#/definitions/repository.DeployType" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployType" } ], "example": "docker" @@ -1271,7 +1458,7 @@ } } }, - "repository.AuthMethod": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AuthMethod": { "description": "SSH authentication method: key or password", "type": "string", "enum": [ @@ -1283,7 +1470,7 @@ "AuthMethodPassword" ] }, - "repository.DeployAgentsRequest": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployAgentsRequest": { "description": "Request to deploy HellreigN agents to multiple servers", "type": "object", "required": [ @@ -1294,12 +1481,12 @@ "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/repository.AgentDeployConfig" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AgentDeployConfig" } } } }, - "repository.DeployResponse": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResponse": { "description": "Response containing deployment results and registration tokens", "type": "object", "properties": { @@ -1310,12 +1497,12 @@ "results": { "type": "array", "items": { - "$ref": "#/definitions/repository.DeployResult" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResult" } } } }, - "repository.DeployResult": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResult": { "description": "Result of deploying to a single server", "type": "object", "properties": { @@ -1341,7 +1528,7 @@ } } }, - "repository.DeployType": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployType": { "description": "Type of deployment: docker or binary", "type": "string", "enum": [ @@ -1353,7 +1540,7 @@ "DeployTypeBinary" ] }, - "repository.LoginRequest": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest": { "type": "object", "required": [ "login", @@ -1368,7 +1555,7 @@ } } }, - "repository.LoginResponse": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse": { "type": "object", "properties": { "is_active": { @@ -1397,7 +1584,7 @@ } } }, - "repository.RegistrationRequest": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.RegistrationRequest": { "type": "object", "required": [ "label" @@ -1408,7 +1595,72 @@ } } }, - "repository.TokenCreate": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter": { + "type": "object", + "properties": { + "argv": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterCreate": { + "type": "object", + "required": [ + "argv", + "label", + "name" + ], + "properties": { + "argv": { + "type": "array", + "items": { + "type": "string" + } + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterUpdate": { + "type": "object", + "properties": { + "argv": { + "type": "array", + "items": { + "type": "string" + } + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate": { "type": "object", "required": [ "last_name", @@ -1443,7 +1695,7 @@ } } }, - "repository.TokenPasswordReset": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenPasswordReset": { "type": "object", "required": [ "new_password" @@ -1454,7 +1706,7 @@ } } }, - "repository.TokenUpdate": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdate": { "type": "object", "properties": { "last_name": { @@ -1465,7 +1717,7 @@ } } }, - "repository.TokenUpdatePermissions": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdatePermissions": { "type": "object", "properties": { "is_active": { @@ -1482,7 +1734,7 @@ } } }, - "repository.Tokens": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens": { "type": "object", "properties": { "id": { @@ -1514,7 +1766,30 @@ } } }, - "storage.LogEntry": { + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.UserRegister": { + "type": "object", + "required": [ + "last_name", + "login", + "name", + "password" + ], + "properties": { + "last_name": { + "type": "string" + }, + "login": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry": { "type": "object", "properties": { "agent": { @@ -1533,6 +1808,187 @@ "type": "string" } } + }, + "internal_handlers.AddJobIn": { + "type": "object", + "required": [ + "agent_id", + "command" + ], + "properties": { + "agent_id": { + "type": "string" + }, + "command": { + "type": "string" + }, + "interpreter_id": { + "type": "integer" + }, + "stdin": { + "type": "string" + } + } + }, + "internal_handlers.AddJobOut": { + "type": "object", + "properties": { + "command": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "status": { + "type": "integer" + }, + "stderr": { + "type": "string" + }, + "stdin": { + "type": "string" + }, + "stdout": { + "type": "string" + } + } + }, + "internal_handlers.AgentInfo": { + "type": "object", + "properties": { + "connected_at": { + "type": "string" + }, + "label": { + "type": "string" + }, + "services": { + "type": "array", + "items": { + "type": "string" + } + }, + "token": { + "type": "string" + } + } + }, + "internal_handlers.InsertLogRequest": { + "type": "object", + "required": [ + "agent", + "level", + "message", + "service" + ], + "properties": { + "agent": { + "type": "string" + }, + "level": { + "type": "string" + }, + "message": { + "type": "string" + }, + "service": { + "type": "string" + }, + "timestamp": { + "type": "string" + } + } + }, + "internal_handlers.InsertLogsRequest": { + "type": "object", + "required": [ + "logs" + ], + "properties": { + "logs": { + "type": "array", + "items": { + "$ref": "#/definitions/internal_handlers.InsertLogRequest" + } + } + } + }, + "internal_handlers.RegisterRequest": { + "type": "object", + "required": [ + "csr", + "token" + ], + "properties": { + "csr": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "internal_handlers.RegisterResponse": { + "type": "object", + "properties": { + "ca_cert": { + "type": "string" + }, + "client_cert": { + "type": "string" + } + } + }, + "internal_handlers.RunScriptIn": { + "type": "object", + "required": [ + "agent_id", + "interpreter_id", + "script_text" + ], + "properties": { + "agent_id": { + "type": "string" + }, + "interpreter_id": { + "type": "integer" + }, + "script_text": { + "type": "string" + }, + "stdin": { + "type": "string" + } + } + }, + "internal_handlers.RunScriptOut": { + "type": "object", + "properties": { + "command": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "status": { + "type": "integer" + }, + "stderr": { + "type": "string" + }, + "stdin": { + "type": "string" + }, + "stdout": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index d73b4eb..6bfb058 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -1,62 +1,5 @@ definitions: - handlers.AgentInfo: - properties: - connected_at: - type: string - label: - type: string - services: - items: - type: string - type: array - token: - type: string - type: object - handlers.InsertLogRequest: - properties: - agent: - type: string - level: - type: string - message: - type: string - service: - type: string - timestamp: - type: string - required: - - agent - - level - - message - - service - type: object - handlers.InsertLogsRequest: - properties: - logs: - items: - $ref: '#/definitions/handlers.InsertLogRequest' - type: array - required: - - logs - type: object - handlers.RegisterRequest: - properties: - csr: - type: string - token: - type: string - required: - - csr - - token - type: object - handlers.RegisterResponse: - properties: - ca_cert: - type: string - client_cert: - type: string - type: object - repository.AgentDeployConfig: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AgentDeployConfig: description: Configuration for deploying HellreigN agent to a single server properties: agentLabel: @@ -64,11 +7,11 @@ definitions: type: string authMethod: allOf: - - $ref: '#/definitions/repository.AuthMethod' + - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AuthMethod' example: key deployType: allOf: - - $ref: '#/definitions/repository.DeployType' + - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployType' example: docker ip: example: 192.168.1.100 @@ -92,7 +35,7 @@ definitions: - ip - user type: object - repository.AuthMethod: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AuthMethod: description: 'SSH authentication method: key or password' enum: - key @@ -101,18 +44,18 @@ definitions: x-enum-varnames: - AuthMethodKey - AuthMethodPassword - repository.DeployAgentsRequest: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployAgentsRequest: description: Request to deploy HellreigN agents to multiple servers properties: servers: items: - $ref: '#/definitions/repository.AgentDeployConfig' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.AgentDeployConfig' minItems: 1 type: array required: - servers type: object - repository.DeployResponse: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResponse: description: Response containing deployment results and registration tokens properties: message: @@ -120,10 +63,10 @@ definitions: type: string results: items: - $ref: '#/definitions/repository.DeployResult' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResult' type: array type: object - repository.DeployResult: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResult: description: Result of deploying to a single server properties: agent_label: @@ -142,7 +85,7 @@ definitions: example: abc123... type: string type: object - repository.DeployType: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployType: description: 'Type of deployment: docker or binary' enum: - docker @@ -151,7 +94,7 @@ definitions: x-enum-varnames: - DeployTypeDocker - DeployTypeBinary - repository.LoginRequest: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest: properties: login: type: string @@ -161,7 +104,7 @@ definitions: - login - password type: object - repository.LoginResponse: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse: properties: is_active: type: boolean @@ -180,14 +123,57 @@ definitions: token: type: string type: object - repository.RegistrationRequest: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.RegistrationRequest: properties: label: type: string required: - label type: object - repository.TokenCreate: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter: + properties: + argv: + items: + type: string + type: array + created_at: + type: string + id: + type: integer + label: + type: string + name: + type: string + updated_at: + type: string + type: object + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterCreate: + properties: + argv: + items: + type: string + type: array + label: + type: string + name: + type: string + required: + - argv + - label + - name + type: object + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterUpdate: + properties: + argv: + items: + type: string + type: array + label: + type: string + name: + type: string + type: object + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate: properties: is_active: type: boolean @@ -211,21 +197,21 @@ definitions: - name - password type: object - repository.TokenPasswordReset: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenPasswordReset: properties: new_password: type: string required: - new_password type: object - repository.TokenUpdate: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdate: properties: last_name: type: string name: type: string type: object - repository.TokenUpdatePermissions: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdatePermissions: properties: is_active: type: boolean @@ -236,7 +222,7 @@ definitions: permission_view: type: boolean type: object - repository.Tokens: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens: properties: id: type: integer @@ -257,7 +243,23 @@ definitions: token: type: string type: object - storage.LogEntry: + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.UserRegister: + properties: + last_name: + type: string + login: + type: string + name: + type: string + password: + type: string + required: + - last_name + - login + - name + - password + type: object + gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry: properties: agent: type: string @@ -270,6 +272,126 @@ definitions: timestamp: type: string type: object + internal_handlers.AddJobIn: + properties: + agent_id: + type: string + command: + type: string + interpreter_id: + type: integer + stdin: + type: string + required: + - agent_id + - command + type: object + internal_handlers.AddJobOut: + properties: + command: + items: + type: string + type: array + id: + type: integer + status: + type: integer + stderr: + type: string + stdin: + type: string + stdout: + type: string + type: object + internal_handlers.AgentInfo: + properties: + connected_at: + type: string + label: + type: string + services: + items: + type: string + type: array + token: + type: string + type: object + internal_handlers.InsertLogRequest: + properties: + agent: + type: string + level: + type: string + message: + type: string + service: + type: string + timestamp: + type: string + required: + - agent + - level + - message + - service + type: object + internal_handlers.InsertLogsRequest: + properties: + logs: + items: + $ref: '#/definitions/internal_handlers.InsertLogRequest' + type: array + required: + - logs + type: object + internal_handlers.RegisterRequest: + properties: + csr: + type: string + token: + type: string + required: + - csr + - token + type: object + internal_handlers.RegisterResponse: + properties: + ca_cert: + type: string + client_cert: + type: string + type: object + internal_handlers.RunScriptIn: + properties: + agent_id: + type: string + interpreter_id: + type: integer + script_text: + type: string + stdin: + type: string + required: + - agent_id + - interpreter_id + - script_text + type: object + internal_handlers.RunScriptOut: + properties: + command: + items: + type: string + type: array + id: + type: integer + status: + type: integer + stderr: + type: string + stdin: + type: string + stdout: + type: string + type: object info: contact: {} paths: @@ -284,7 +406,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/handlers.AgentInfo' + $ref: '#/definitions/internal_handlers.AgentInfo' type: array security: - Bearer: [] @@ -303,14 +425,14 @@ paths: name: request required: true schema: - $ref: '#/definitions/repository.DeployAgentsRequest' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployAgentsRequest' produces: - application/json responses: "200": description: Deployment results with tokens for each server schema: - $ref: '#/definitions/repository.DeployResponse' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.DeployResponse' "400": description: Invalid request schema: @@ -338,14 +460,14 @@ paths: name: request required: true schema: - $ref: '#/definitions/handlers.RegisterRequest' + $ref: '#/definitions/internal_handlers.RegisterRequest' produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/handlers.RegisterResponse' + $ref: '#/definitions/internal_handlers.RegisterResponse' summary: Register agent tags: - agents @@ -359,7 +481,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/repository.RegistrationRequest' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.RegistrationRequest' produces: - application/json responses: @@ -385,12 +507,12 @@ paths: name: request required: true schema: - $ref: '#/definitions/repository.LoginRequest' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginRequest' responses: "200": description: OK schema: - $ref: '#/definitions/repository.LoginResponse' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.LoginResponse' "400": description: Bad Request schema: @@ -412,6 +534,47 @@ paths: summary: Login tags: - auth + /auth/register: + post: + consumes: + - application/json + description: Registers a new user with login, password, name, last name. All + permissions are set to false. + parameters: + - description: Registration data + in: body + name: request + required: true + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.UserRegister' + responses: + "200": + description: OK + schema: + additionalProperties: + type: string + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "409": + description: Conflict + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: Register user + tags: + - auth /auth/token: delete: description: Deletes the current authenticated user @@ -447,7 +610,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/repository.TokenCreate' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenCreate' responses: "200": description: OK @@ -486,7 +649,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/repository.Tokens' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens' type: array "500": description: Internal Server Error @@ -543,7 +706,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/repository.Tokens' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens' "400": description: Bad Request schema: @@ -580,7 +743,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/repository.TokenUpdate' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdate' responses: "200": description: OK @@ -699,7 +862,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/repository.TokenPasswordReset' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenPasswordReset' responses: "200": description: OK @@ -744,7 +907,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/repository.TokenUpdatePermissions' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.TokenUpdatePermissions' responses: "200": description: OK @@ -783,7 +946,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/repository.Tokens' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens' type: array "500": description: Internal Server Error @@ -803,7 +966,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/repository.Tokens' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.Tokens' "401": description: Unauthorized schema: @@ -813,6 +976,29 @@ paths: summary: Validate token tags: - auth + /jobs: + post: + consumes: + - application/json + description: Sends a command to the specified agent, waits for execution, and + returns the result + parameters: + - description: Job request + in: body + name: body + required: true + schema: + $ref: '#/definitions/internal_handlers.AddJobIn' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/internal_handlers.AddJobOut' + summary: Create and run a job on an agent + tags: + - jobs /logs: get: description: Searches logs with various filters @@ -854,7 +1040,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/storage.LogEntry' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry' type: array security: - Bearer: [] @@ -871,7 +1057,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/handlers.InsertLogRequest' + $ref: '#/definitions/internal_handlers.InsertLogRequest' produces: - application/json responses: @@ -914,7 +1100,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/handlers.InsertLogsRequest' + $ref: '#/definitions/internal_handlers.InsertLogsRequest' produces: - application/json responses: @@ -980,7 +1166,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/storage.LogEntry' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_storage.LogEntry' type: array security: - Bearer: [] @@ -1004,6 +1190,123 @@ paths: summary: Get distinct services tags: - logs + /scripts/interpreters: + get: + description: Returns all script interpreters available in the system + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter' + type: array + summary: List interpreters + tags: + - scripts + post: + consumes: + - application/json + description: Registers a new script interpreter with name, label, and argv + parameters: + - description: Interpreter definition + in: body + name: body + required: true + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterCreate' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter' + summary: Create interpreter + tags: + - scripts + /scripts/interpreters/:id: + delete: + description: Removes a script interpreter by ID + parameters: + - description: Interpreter ID + in: path + name: id + required: true + type: integer + responses: + "204": + description: No Content + summary: Delete interpreter + tags: + - scripts + get: + description: Returns a script interpreter by ID + parameters: + - description: Interpreter ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter' + summary: Get interpreter + tags: + - scripts + put: + consumes: + - application/json + description: Updates fields of a script interpreter + parameters: + - description: Interpreter ID + in: path + name: id + required: true + type: integer + - description: Interpreter fields + in: body + name: body + required: true + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreterUpdate' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_HellreigN_backend_internal_repository.ScriptInterpreter' + summary: Update interpreter + tags: + - scripts + /scripts/run: + post: + consumes: + - application/json + description: Resolves interpreter argv[] and sends the full command to the agent + parameters: + - description: Script request + in: body + name: body + required: true + schema: + $ref: '#/definitions/internal_handlers.RunScriptIn' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/internal_handlers.RunScriptOut' + summary: Run a script on an agent + tags: + - scripts securityDefinitions: Bearer: description: Type "Bearer" followed by a space and the JWT token. diff --git a/backend/internal/handlers/auth.go b/backend/internal/handlers/auth.go index 7ff3ebd..28329df 100644 --- a/backend/internal/handlers/auth.go +++ b/backend/internal/handlers/auth.go @@ -49,6 +49,37 @@ func (ag *AuthGroup) Login(c *gin.Context) { c.JSON(http.StatusOK, resp) } +// RegisterUser registers a new user with all permissions set to false. +// @Summary Register user +// @Description Registers a new user with login, password, name, last name. All permissions are set to false. +// @Tags auth +// @Accept json +// @Param request body repository.UserRegister true "Registration data" +// @Success 200 {object} map[string]string +// @Failure 400 {object} map[string]string +// @Failure 409 {object} map[string]string +// @Failure 500 {object} map[string]string +// @Router /auth/register [post] +func (ag *AuthGroup) RegisterUser(c *gin.Context) { + var req repository.UserRegister + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"}) + return + } + + if ag.Repo.ExistsByLogin(req.Login) { + c.JSON(http.StatusConflict, gin.H{"error": "login already exists"}) + return + } + + if _, err := ag.Repo.RegisterUser(req); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to register user"}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "user registered"}) +} + // CreateToken creates a new user. // @Summary Create user // @Description Creates a new user with permissions diff --git a/backend/internal/handlers/scripts.go b/backend/internal/handlers/scripts.go index 5e3debd..6dbd295 100644 --- a/backend/internal/handlers/scripts.go +++ b/backend/internal/handlers/scripts.go @@ -21,6 +21,22 @@ func NewScriptHandlers(svc *service.ScriptService, cmder *commander.Commander) S return ScriptHandlers{svc: svc, cmder: cmder} } +type RunScriptIn struct { + AgentID string `json:"agent_id" binding:"required"` + InterpreterID int64 `json:"interpreter_id" binding:"required"` + ScriptText string `json:"script_text" binding:"required"` + Stdin *string `json:"stdin"` +} + +type RunScriptOut struct { + ID int64 `json:"id"` + Command []string `json:"command"` + Stdin *string `json:"stdin"` + Stdout string `json:"stdout"` + Stderr string `json:"stderr"` + Status int32 `json:"status"` +} + // RunScript executes a script on a target agent. // @Summary Run a script on an agent // @Description Resolves interpreter argv[] and sends the full command to the agent @@ -32,12 +48,6 @@ func NewScriptHandlers(svc *service.ScriptService, cmder *commander.Commander) S // @Router /scripts/run [post] func (self *ScriptHandlers) RunScript(c *gin.Context) { err := func() error { - type RunScriptIn struct { - AgentID string `json:"agent_id" binding:"required"` - InterpreterID int64 `json:"interpreter_id" binding:"required"` - ScriptText string `json:"script_text" binding:"required"` - Stdin *string `json:"stdin"` - } var in RunScriptIn if err := c.Bind(&in); err != nil { return err @@ -67,14 +77,6 @@ func (self *ScriptHandlers) RunScript(c *gin.Context) { return err } - type RunScriptOut struct { - ID int64 `json:"id"` - Command []string `json:"command"` - Stdin *string `json:"stdin"` - Stdout string `json:"stdout"` - Stderr string `json:"stderr"` - Status int32 `json:"status"` - } c.JSON(http.StatusCreated, RunScriptOut{ ID: job.ID, Command: job.Command, diff --git a/backend/internal/repository/models.go b/backend/internal/repository/models.go index 84e107c..7ba44b8 100644 --- a/backend/internal/repository/models.go +++ b/backend/internal/repository/models.go @@ -25,6 +25,14 @@ type TokenCreate struct { IsActive bool `json:"is_active"` } +// UserRegister is the request body for public user registration (all permissions false). +type UserRegister struct { + Name string `json:"name" binding:"required"` + LastName string `json:"last_name" binding:"required"` + Login string `json:"login" binding:"required"` + Password string `json:"password" binding:"required"` +} + // TokenUpdate is the request body for updating an existing user. type TokenUpdate struct { Name string `json:"name"` diff --git a/backend/internal/repository/repository.go b/backend/internal/repository/repository.go index a7941d8..842cac7 100644 --- a/backend/internal/repository/repository.go +++ b/backend/internal/repository/repository.go @@ -64,6 +64,34 @@ func (r *Repository) CreateToken(tc TokenCreate) (string, error) { return strconv.FormatInt(id, 10), nil } +// RegisterUser inserts a new user with all permissions set to false and is_active=false. +func (r *Repository) RegisterUser(ur UserRegister) (string, error) { + hashed, err := bcrypt.GenerateFromPassword([]byte(ur.Password), bcrypt.DefaultCost) + if err != nil { + return "", err + } + + token, err := utils.RandomToken() + if err != nil { + return "", err + } + + result, err := r.DB.Exec( + `INSERT INTO tokens (name, last_name, login, password, token, permission_view, permission_manage_agent, permission_admin, is_active) + VALUES (?, ?, ?, ?, ?, 0, 0, 0, 0)`, + ur.Name, ur.LastName, ur.Login, string(hashed), token, + ) + if err != nil { + return "", err + } + + id, err := result.LastInsertId() + if err != nil { + return "", err + } + return strconv.FormatInt(id, 10), nil +} + // Login authenticates by login/password, generates a new token, and returns LoginResponse. func (r *Repository) Login(login, password string) (*LoginResponse, error) { var t Tokens diff --git a/infra/agent/config.yml b/infra/agent/config.yml index 5ab5317..9ea00c1 100644 --- a/infra/agent/config.yml +++ b/infra/agent/config.yml @@ -1,7 +1,7 @@ backend_url: http://backend:8080 grpc_url: backend:9001 label: test-agent-1 -registration_token: "156616b56774d59ba53f1eb4b096488bb5f755bbf5b737d93a42bb1b583ad7fb" +registration_token: "3db3bc64affa93c3b95762a41cbad9c58762f8e49faa1bb1ec1588a75fb9188d" cert_dir: /etc/hellreign-agent/certs services: - name: system