From bdd03f96f770d5230419d188d19d5a63f1ee0848 Mon Sep 17 00:00:00 2001 From: Ada Werefox Date: Thu, 24 Apr 2025 18:17:30 -0700 Subject: [PATCH] Starting to implement database model interfaces. --- src/gin-cpularp.go | 2 + src/lib/api/api.go | 78 +++++++++++++++++---------- src/lib/database/commands/commands.go | 33 ++++++++++-- src/lib/database/models/models.go | 15 +++++- 4 files changed, 95 insertions(+), 33 deletions(-) diff --git a/src/gin-cpularp.go b/src/gin-cpularp.go index 877572b..922d0d1 100755 --- a/src/gin-cpularp.go +++ b/src/gin-cpularp.go @@ -23,6 +23,8 @@ func main() { // Read app.GET("/get/user/info", api.GetUserInfo) app.GET("/get/user/authorized", api.GetIsUserAuthorized) + app.GET("/get/group", api.GetDatabaseGroup) + app.GET("/get/groups", api.GetDatabaseGroups) // Delete app.Run(":31337") } diff --git a/src/lib/api/api.go b/src/lib/api/api.go index 497a32f..94dccb1 100644 --- a/src/lib/api/api.go +++ b/src/lib/api/api.go @@ -21,6 +21,31 @@ var GlobalDatabase *gorm.DB var GlobalConfig configserver.AppConfig var GlobalOAuth *oauth2.Config +// Private Functions + +func getDiscordUser(context *gin.Context, oauthToken *oauth2.Token) authdiscord.DiscordUser { + response, err := GlobalOAuth.Client(context, oauthToken).Get("https://discord.com/api/users/@me") + if err != nil || response.StatusCode != 200 { + responseMessage := "" + if err != nil { + responseMessage = err.Error() + } else { + responseMessage = response.Status + } + log.Println(responseMessage) + log.Println("Assuming the Discord OAuth Key has expired.") + context.Redirect(http.StatusUnauthorized, "https://localhost:15995/logout") + } + defer response.Body.Close() + body, err := io.ReadAll(response.Body) + if err != nil { + log.Println(err) + } + var user authdiscord.DiscordUser + json.Unmarshal(body, &user) + return user +} + // Authentication Workflow func AuthCallback(context *gin.Context) { @@ -76,7 +101,7 @@ func CreateOrUpdateUser(context *gin.Context) { LoginToken: string(oauthTokenJSON), LoggedIn: true, } - if databasecommands.DatabaseUserExists(GlobalDatabase, currentDiscordUser.Id) { + if databasecommands.GetDatabaseUserExists(GlobalDatabase, currentDiscordUser.Id) { dbOAuthToken := databasecommands.GetDatabaseUserToken(GlobalDatabase, currentDiscordUser.Id) if dbOAuthToken == "" { context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false) @@ -97,33 +122,12 @@ func CreateOrUpdateUser(context *gin.Context) { } } -// Read Endpoints (get/) +func CreateDatabaseGroup(context *gin.Context) { -func getDiscordUser(context *gin.Context, oauthToken *oauth2.Token) authdiscord.DiscordUser { - response, err := GlobalOAuth.Client(context.Request.Context(), oauthToken).Get("https://discord.com/api/users/@me") - if err != nil || response.StatusCode != 200 { - responseMessage := "" - if err != nil { - responseMessage = err.Error() - } else { - responseMessage = response.Status - } - context.JSON(http.StatusInternalServerError, gin.H{ - "message": responseMessage, - }) - } - defer response.Body.Close() - body, err := io.ReadAll(response.Body) - if err != nil { - context.JSON(http.StatusInternalServerError, gin.H{ - "message": err.Error(), - }) - } - var user authdiscord.DiscordUser - json.Unmarshal(body, &user) - return user } +// Read Endpoints (get/) + func GetUserInfo(context *gin.Context) { oauthTokenJSON, err := context.Cookie("discord-oauthtoken") if err == nil { @@ -132,7 +136,7 @@ func GetUserInfo(context *gin.Context) { if err == nil { if oauthToken.Valid() { user := getDiscordUser(context, oauthToken) - if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) { + if databasecommands.GetDatabaseUserLoggedIn(GlobalDatabase, oauthTokenJSON) { context.JSON(http.StatusOK, user) } else { context.Redirect(http.StatusTemporaryRedirect, "http://localhost:31337/auth/logout") @@ -160,8 +164,7 @@ func GetIsUserAuthorized(context *gin.Context) { err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken) if err == nil { if oauthToken.Valid() { - user := getDiscordUser(context, oauthToken) - if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) { + if databasecommands.GetDatabaseUserLoggedIn(GlobalDatabase, oauthTokenJSON) { context.JSON(http.StatusOK, gin.H{ "message": true, }) @@ -179,4 +182,23 @@ func GetIsUserAuthorized(context *gin.Context) { }) } +func GetDatabaseGroup(context *gin.Context) { + groupName := context.Query("group") + if groupName != "" { + group := databasecommands.GetDatabaseGroup(GlobalDatabase, groupName) + context.JSON(http.StatusOK, group) + } else { + context.JSON(http.StatusBadRequest, gin.H{ + "name": "", + }) + } +} + +func GetDatabaseGroups(context *gin.Context) { + groups := databasecommands.GetDatabaseGroups(GlobalDatabase) + context.JSON(http.StatusOK, gin.H{ + "groups": groups, + }) +} + // Delete Endpoints (delete/) diff --git a/src/lib/database/commands/commands.go b/src/lib/database/commands/commands.go index 4c88cd3..b356930 100644 --- a/src/lib/database/commands/commands.go +++ b/src/lib/database/commands/commands.go @@ -29,7 +29,7 @@ func GetDatabaseUserToken(db *gorm.DB, id string) string { } } -func DatabaseUserExists(db *gorm.DB, id string) bool { +func GetDatabaseUserExists(db *gorm.DB, id string) bool { var queryUser databasemodels.User result := db.Where("id = ?", id).Take(&queryUser) if errors.Is(result.Error, gorm.ErrRecordNotFound) { @@ -39,9 +39,9 @@ func DatabaseUserExists(db *gorm.DB, id string) bool { } } -func DatabaseUserLoggedIn(db *gorm.DB, id string) bool { +func GetDatabaseUserLoggedIn(db *gorm.DB, oauthTokenJSON string) bool { var queryUser databasemodels.User - result := db.Where("id = ?", id).Take(&queryUser) + result := db.Where("login_token = ?", oauthTokenJSON).Take(&queryUser) if errors.Is(result.Error, gorm.ErrRecordNotFound) { return false } else { @@ -67,5 +67,30 @@ func CreateDatabaseUser(db *gorm.DB, user databasemodels.User) error { func LogoutDatabaseUser(db *gorm.DB, oauthToken string) { db.Model(&databasemodels.User{}).Where("login_token = ?", oauthToken).Update("logged_in", false) - db.Model(&databasemodels.User{}).Where("login_token = ?", oauthToken).Update("login_token", "") +} + +func CreateDatabaseGroup(db *gorm.DB, group databasemodels.Group) error { + result := db.Create(&group) + if result.Error != nil { + return result.Error + } + return nil +} + +func GetDatabaseGroup(db *gorm.DB, inputGroup string) databasemodels.Group { + var outputGroup databasemodels.Group + result := db.Model(&databasemodels.Group{}).Where("name = ?", inputGroup).Take(&outputGroup) + if result.Error != nil { + return databasemodels.Group{} + } + return outputGroup +} + +func GetDatabaseGroups(db *gorm.DB) []databasemodels.Group { + var outputGroup []databasemodels.Group + result := db.Find(&outputGroup) + if result.Error != nil { + return []databasemodels.Group{} + } + return outputGroup } diff --git a/src/lib/database/models/models.go b/src/lib/database/models/models.go index 3125ec4..5e4264b 100644 --- a/src/lib/database/models/models.go +++ b/src/lib/database/models/models.go @@ -14,15 +14,18 @@ type User struct { } type Person struct { + gorm.Model Name string Groups []Group // Unique } type Group struct { - Name string + gorm.Model + Name string `json:"name"` } type Character struct { + gorm.Model Name string Owners []Person // Unique Roles []Role // Unique @@ -31,35 +34,42 @@ type Character struct { } type Role struct { + gorm.Model Name string Tiers []Tier Visibility []Group // Unique } type Tier struct { + gorm.Model FunctionSets []FunctionSet } type FunctionSet struct { + gorm.Model Functions []Function } type Function struct { + gorm.Model Name string Tags FunctionTag Requirements []Function } type FunctionTag struct { + gorm.Model Name string } type InventorySlot struct { + gorm.Model Item Item Quantity int64 // Positive } type Item struct { + gorm.Model Name string Functions []Function FlavorText string @@ -71,10 +81,12 @@ type Item struct { } type ItemTag struct { + gorm.Model Naem string } type Customization struct { + gorm.Model Name string Functions []Function FlavorText string @@ -85,6 +97,7 @@ type Customization struct { } type Schematic struct { + gorm.Model Material []InventorySlot Tools []InventorySlot Requirements []Function