From dd39d8c86667c5446020458f8fe5171149d9ed5c Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Wed, 18 Jan 2023 22:12:38 +0300 Subject: feat: refresh/update user via steam (#30) --- backend/controllers/homeController.go | 57 --------------------- backend/controllers/loginController.go | 92 ++++++++++++++++++++++++++++++++++ backend/controllers/userController.go | 35 +++++++++++++ 3 files changed, 127 insertions(+), 57 deletions(-) create mode 100644 backend/controllers/loginController.go (limited to 'backend/controllers') diff --git a/backend/controllers/homeController.go b/backend/controllers/homeController.go index 42dfaa7..8b52ff3 100644 --- a/backend/controllers/homeController.go +++ b/backend/controllers/homeController.go @@ -2,14 +2,10 @@ package controllers import ( "net/http" - "os" - "time" "github.com/gin-gonic/gin" - "github.com/golang-jwt/jwt/v4" "github.com/pektezol/leastportals/backend/database" "github.com/pektezol/leastportals/backend/models" - "github.com/solovev/steam_go" ) func Home(c *gin.Context) { @@ -23,59 +19,6 @@ func Home(c *gin.Context) { } } -func Login(c *gin.Context) { - openID := steam_go.NewOpenId(c.Request) - switch openID.Mode() { - case "": - c.Redirect(http.StatusMovedPermanently, openID.AuthUrl()) - case "cancel": - c.Redirect(http.StatusMovedPermanently, "/") - default: - steamID, err := openID.ValidateAndGetId() - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - // Create user if new - var checkSteamID int64 - err = database.DB.QueryRow("SELECT steam_id FROM users WHERE steam_id = $1", steamID).Scan(&checkSteamID) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - // User does not exist - if checkSteamID == 0 { - user, err := steam_go.GetPlayerSummaries(steamID, os.Getenv("API_KEY")) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - // Insert new user to database - database.DB.Exec(`INSERT INTO users (steam_id, username, avatar_link, country_code) - VALUES ($1, $2, $3, $4)`, steamID, user.PersonaName, user.AvatarFull, user.LocCountryCode) - } - // Generate JWT token - token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ - "sub": steamID, - "exp": time.Now().Add(time.Hour * 24 * 365).Unix(), - }) - // 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 { - c.JSON(http.StatusBadRequest, models.ErrorResponse("Failed to generate token.")) - return - } - c.JSON(http.StatusOK, models.Response{ - Success: true, - Message: "Successfully generated token.", - Data: models.LoginResponse{ - Token: tokenString, - }, - }) - return - } -} - func Rankings(c *gin.Context) { rows, err := database.DB.Query(`SELECT steam_id, username FROM users;`) if err != nil { diff --git a/backend/controllers/loginController.go b/backend/controllers/loginController.go new file mode 100644 index 0000000..50189e8 --- /dev/null +++ b/backend/controllers/loginController.go @@ -0,0 +1,92 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v4" + "github.com/pektezol/leastportals/backend/database" + "github.com/pektezol/leastportals/backend/models" + "github.com/solovev/steam_go" +) + +func Login(c *gin.Context) { + openID := steam_go.NewOpenId(c.Request) + switch openID.Mode() { + case "": + c.Redirect(http.StatusMovedPermanently, openID.AuthUrl()) + case "cancel": + c.Redirect(http.StatusMovedPermanently, "/") + default: + steamID, err := openID.ValidateAndGetId() + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Create user if new + var checkSteamID int64 + err = database.DB.QueryRow("SELECT steam_id FROM users WHERE steam_id = $1", steamID).Scan(&checkSteamID) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // User does not exist + if checkSteamID == 0 { + user, err := GetPlayerSummaries(steamID, os.Getenv("API_KEY")) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Insert new user to database + database.DB.Exec(`INSERT INTO users (steam_id, username, avatar_link, country_code) + VALUES ($1, $2, $3, $4)`, steamID, user.PersonaName, user.AvatarFull, user.LocCountryCode) + } + // Generate JWT token + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ + "sub": steamID, + "exp": time.Now().Add(time.Hour * 24 * 365).Unix(), + }) + // 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 { + c.JSON(http.StatusBadRequest, models.ErrorResponse("Failed to generate token.")) + return + } + c.JSON(http.StatusOK, models.Response{ + Success: true, + Message: "Successfully generated token.", + Data: models.LoginResponse{ + Token: tokenString, + }, + }) + return + } +} + +func GetPlayerSummaries(steamId, apiKey string) (*models.PlayerSummaries, error) { + url := fmt.Sprintf("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=%s&steamids=%s", apiKey, steamId) + resp, err := http.Get(url) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + type Result struct { + Response struct { + Players []models.PlayerSummaries `json:"players"` + } `json:"response"` + } + var data Result + if err := json.Unmarshal(body, &data); err != nil { + return nil, err + } + return &data.Response.Players[0], err +} diff --git a/backend/controllers/userController.go b/backend/controllers/userController.go index 6bca5b9..95b2b52 100644 --- a/backend/controllers/userController.go +++ b/backend/controllers/userController.go @@ -2,7 +2,9 @@ package controllers import ( "net/http" + "os" "regexp" + "time" "github.com/gin-gonic/gin" "github.com/pektezol/leastportals/backend/database" @@ -176,6 +178,39 @@ func FetchUser(c *gin.Context) { return } +func UpdateUser(c *gin.Context) { + // Check if user exists + user, exists := c.Get("user") + if !exists { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("User not logged in.")) + return + } + profile, err := GetPlayerSummaries(user.(models.User).SteamID, os.Getenv("API_KEY")) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Update profile + _, err = database.DB.Exec(`UPDATE users SET username = $1, avatar_link = $2, country_code = $3, updated_at = $4 + WHERE steam_id = $5;`, profile.PersonaName, profile.AvatarFull, profile.LocCountryCode, time.Now().UTC(), user.(models.User).SteamID) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + c.JSON(http.StatusOK, models.Response{ + Success: true, + Message: "Successfully updated user.", + Data: models.ProfileResponse{ + Profile: true, + SteamID: user.(models.User).SteamID, + Username: profile.PersonaName, + AvatarLink: profile.AvatarFull, + CountryCode: profile.LocCountryCode, + }, + }) + return +} + func UpdateCountryCode(c *gin.Context) { // Check if user exists user, exists := c.Get("user") -- cgit v1.2.3