From 69c5423f7954b641109166e03ad0ab174b3d55c6 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Sat, 2 Sep 2023 11:09:42 +0300 Subject: feat: testing logging system (#55) Former-commit-id: d8c5fda30ab08b42218aead1febdf83200948763 --- backend/api/routes.go | 2 + backend/database/init.sql | 10 ++++ backend/handlers/login.go | 4 ++ backend/handlers/logs.go | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 backend/handlers/logs.go (limited to 'backend') diff --git a/backend/api/routes.go b/backend/api/routes.go index 4dd8660..ac622d4 100644 --- a/backend/api/routes.go +++ b/backend/api/routes.go @@ -36,5 +36,7 @@ func InitRoutes(router *gin.Engine) { v1.GET("/games", handlers.FetchGames) v1.GET("/games/:id", handlers.FetchChapters) v1.GET("/chapters/:id", handlers.FetchChapterMaps) + v1.GET("/logs/score", handlers.ScoreLogs) + v1.GET("/logs/mod", CheckAuth, handlers.ModLogs) } } diff --git a/backend/database/init.sql b/backend/database/init.sql index 25de872..abace5c 100644 --- a/backend/database/init.sql +++ b/backend/database/init.sql @@ -139,3 +139,13 @@ CREATE TABLE countries ( country_name TEXT NOT NULL, PRIMARY KEY (country_code) ); + +CREATE TABLE logs ( + id SERIAL, + user_id TEXT NOT NULL, + type TEXT NOT NULL, + description TEXT NOT NULL, + date TIMESTAMP NOT NULL DEFAULT now(), + PRIMARY KEY (id), + FOREIGN KEY (user_id) REFERENCES users(steam_id) +); \ No newline at end of file diff --git a/backend/handlers/login.go b/backend/handlers/login.go index 4b151c2..80f697e 100644 --- a/backend/handlers/login.go +++ b/backend/handlers/login.go @@ -38,6 +38,7 @@ func Login(c *gin.Context) { default: steamID, err := openID.ValidateAndGetId() if err != nil { + CreateLog(steamID, LogTypeLogin, LogDescriptionLoginFailValidate) c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } @@ -48,6 +49,7 @@ func Login(c *gin.Context) { if checkSteamID == 0 { user, err := GetPlayerSummaries(steamID, os.Getenv("API_KEY")) if err != nil { + CreateLog(steamID, LogTypeLogin, LogDescriptionLoginFailSummary) c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } @@ -77,10 +79,12 @@ func Login(c *gin.Context) { // Sign and get the complete encoded token as a string using the secret tokenString, err := token.SignedString([]byte(os.Getenv("SECRET_KEY"))) if err != nil { + CreateLog(steamID, LogTypeLogin, LogDescriptionLoginFailToken) c.JSON(http.StatusBadRequest, models.ErrorResponse("Failed to generate token.")) return } c.SetCookie("token", tokenString, 3600*24*30, "/", "", true, true) + CreateLog(steamID, LogTypeLogin, LogDescriptionLoginSuccess) c.Redirect(http.StatusTemporaryRedirect, "/") // c.JSON(http.StatusOK, models.Response{ // Success: true, diff --git a/backend/handlers/logs.go b/backend/handlers/logs.go new file mode 100644 index 0000000..2b5713d --- /dev/null +++ b/backend/handlers/logs.go @@ -0,0 +1,114 @@ +package handlers + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/pektezol/leastportalshub/backend/database" + "github.com/pektezol/leastportalshub/backend/models" +) + +const ( + LogTypeMod string = "Mod" + LogTypeScore string = "Score" + LogTypeLogin string = "Login" + + LogDescriptionLoginSuccess string = "Success" + LogDescriptionLoginFailToken string = "TokenFail" + LogDescriptionLoginFailValidate string = "ValidateFail" + LogDescriptionLoginFailSummary string = "SummaryFail" +) + +type Log struct { + User models.UserShort `json:"user"` + Type string `json:"type"` + Description string `json:"description"` +} + +type LogsResponse struct { + Logs []LogsResponseDetails `json:"logs"` +} + +type LogsResponseDetails struct { + User models.UserShort `json:"user"` + Log string `json:"detail"` +} + +func ModLogs(c *gin.Context) { + mod, exists := c.Get("mod") + if !exists || !mod.(bool) { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("Insufficient permissions.")) + return + } + response := LogsResponse{Logs: []LogsResponseDetails{}} + sql := `SELECT u.user_name, l.user_id, l.type, l.description + FROM logs l INNER JOIN users u ON l.user_id = u.steam_id WHERE type != 'Score'` + rows, err := database.DB.Query(sql) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + for rows.Next() { + log := Log{} + err = rows.Scan(log.User.UserName, log.User.SteamID, log.Type, log.Description) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + detail := fmt.Sprintf("%s.%s", log.Type, log.Description) + response.Logs = append(response.Logs, LogsResponseDetails{ + User: models.UserShort{ + SteamID: log.User.SteamID, + UserName: log.User.UserName, + }, + Log: detail, + }) + } + c.JSON(http.StatusOK, models.Response{ + Success: true, + Message: "Successfully retrieved logs.", + Data: response, + }) +} + +func ScoreLogs(c *gin.Context) { + response := LogsResponse{Logs: []LogsResponseDetails{}} + sql := `SELECT u.user_name, l.user_id, l.type, l.description + FROM logs l INNER JOIN users u ON l.user_id = u.steam_id WHERE type = 'Score'` + rows, err := database.DB.Query(sql) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + for rows.Next() { + log := Log{} + err = rows.Scan(log.User.UserName, log.User.SteamID, log.Type, log.Description) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + detail := fmt.Sprintf("%s.%s", log.Type, log.Description) + response.Logs = append(response.Logs, LogsResponseDetails{ + User: models.UserShort{ + SteamID: log.User.SteamID, + UserName: log.User.UserName, + }, + Log: detail, + }) + } + c.JSON(http.StatusOK, models.Response{ + Success: true, + Message: "Successfully retrieved score logs.", + Data: response, + }) +} + +func CreateLog(user_id string, log_type string, log_description string) (err error) { + sql := `INSERT INTO logs (user_id, "type", description) VALUES($1, $2, $3)` + _, err = database.DB.Exec(sql) + if err != nil { + return err + } + return nil +} -- cgit v1.2.3