Standardizing the API endpoints.
This commit is contained in:
		
							parent
							
								
									326fbe79a3
								
							
						
					
					
						commit
						10db069eea
					
				
					 3 changed files with 166 additions and 66 deletions
				
			
		| 
						 | 
					@ -14,10 +14,15 @@ func main() {
 | 
				
			||||||
	api.GlobalConfig = configserver.ParseConfig("../config.toml")
 | 
						api.GlobalConfig = configserver.ParseConfig("../config.toml")
 | 
				
			||||||
	api.GlobalOAuth = authdiscord.CreateDiscordOAuthConfig(api.GlobalConfig)
 | 
						api.GlobalOAuth = authdiscord.CreateDiscordOAuthConfig(api.GlobalConfig)
 | 
				
			||||||
	app := gin.Default()
 | 
						app := gin.Default()
 | 
				
			||||||
	app.GET("/login", api.LoginRedirect)
 | 
						// Authentication Workflow
 | 
				
			||||||
	app.GET("/auth/callback", api.AuthCallback)
 | 
						app.GET("/auth/callback", api.AuthCallback)
 | 
				
			||||||
	app.GET("/logout", api.LogoutRedirect)
 | 
						app.GET("/auth/login", api.AuthLoginRedirect)
 | 
				
			||||||
	app.GET("/dashboard", api.GetDashboardInfo)
 | 
						app.GET("/auth/logout", api.AuthLogoutRedirect)
 | 
				
			||||||
	app.GET("/authorized", api.IsUserAuthorized)
 | 
						// Create & Update
 | 
				
			||||||
 | 
						app.POST("/post/user/update", api.CreateOrUpdateUser)
 | 
				
			||||||
 | 
						// Read
 | 
				
			||||||
 | 
						app.GET("/get/user/info", api.GetUserInfo)
 | 
				
			||||||
 | 
						app.GET("/get/user/authorized", api.GetIsUserAuthorized)
 | 
				
			||||||
 | 
						// Delete
 | 
				
			||||||
	app.Run(":31337")
 | 
						app.Run(":31337")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,20 +21,7 @@ var GlobalDatabase *gorm.DB
 | 
				
			||||||
var GlobalConfig configserver.AppConfig
 | 
					var GlobalConfig configserver.AppConfig
 | 
				
			||||||
var GlobalOAuth *oauth2.Config
 | 
					var GlobalOAuth *oauth2.Config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LoginRedirect(context *gin.Context) {
 | 
					// Authentication Workflow
 | 
				
			||||||
	context.Redirect(302, GlobalOAuth.AuthCodeURL(context.GetString("state")))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func LogoutRedirect(context *gin.Context) {
 | 
					 | 
				
			||||||
	oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		databasecommands.LogoutDatabaseUser(GlobalDatabase, oauthTokenJSON)
 | 
					 | 
				
			||||||
		context.SetCookie("discord-oauthtoken", "", -1, "", GlobalConfig.API.Domain, false, true)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func AuthCallback(context *gin.Context) {
 | 
					func AuthCallback(context *gin.Context) {
 | 
				
			||||||
	oauthState := randomstring.CookieFriendlyString(32)
 | 
						oauthState := randomstring.CookieFriendlyString(32)
 | 
				
			||||||
| 
						 | 
					@ -46,12 +33,73 @@ func AuthCallback(context *gin.Context) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oauthTokenJSON, _ := json.Marshal(oauthToken)
 | 
						oauthTokenJSON, _ := json.Marshal(oauthToken)
 | 
				
			||||||
	context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
 | 
						context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
 | 
				
			||||||
	user := GetDiscordUser(context, oauthToken)
 | 
						context.Set("discord-oauthtoken", string(oauthTokenJSON))
 | 
				
			||||||
	CreateOrUpdateUser(context, oauthToken, user)
 | 
						CreateOrUpdateUser(context)
 | 
				
			||||||
	context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/dashboard")
 | 
						context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/dashboard")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetDiscordUser(context *gin.Context, oauthToken *oauth2.Token) authdiscord.DiscordUser {
 | 
					func AuthLoginRedirect(context *gin.Context) {
 | 
				
			||||||
 | 
						context.Redirect(302, GlobalOAuth.AuthCodeURL(context.GetString("state")))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func AuthLogoutRedirect(context *gin.Context) {
 | 
				
			||||||
 | 
						oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							databasecommands.LogoutDatabaseUser(GlobalDatabase, oauthTokenJSON)
 | 
				
			||||||
 | 
							context.SetCookie("discord-oauthtoken", "", -1, "", GlobalConfig.API.Domain, false, true)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create & Update Endpoints (post/, put/, patch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CreateOrUpdateUser(context *gin.Context) {
 | 
				
			||||||
 | 
						oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							oauthTokenJSON = context.GetString("discord-oauthtoken")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var oauthToken *oauth2.Token
 | 
				
			||||||
 | 
						err = json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							context.AbortWithStatus(http.StatusBadRequest)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						currentDiscordUser := getDiscordUser(context, oauthToken)
 | 
				
			||||||
 | 
						updatedDatabaseUser := databasemodels.User{
 | 
				
			||||||
 | 
							DisplayName:      currentDiscordUser.Global_Name,
 | 
				
			||||||
 | 
							Username:         currentDiscordUser.Username,
 | 
				
			||||||
 | 
							Id:               currentDiscordUser.Id,
 | 
				
			||||||
 | 
							Avatar:           currentDiscordUser.Avatar,
 | 
				
			||||||
 | 
							AvatarDecoration: currentDiscordUser.Avatar_Decoration_Data.Asset,
 | 
				
			||||||
 | 
							LoginToken:       string(oauthTokenJSON),
 | 
				
			||||||
 | 
							LoggedIn:         true,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if databasecommands.DatabaseUserExists(GlobalDatabase, currentDiscordUser.Id) {
 | 
				
			||||||
 | 
							dbOAuthToken := databasecommands.GetDatabaseUserToken(GlobalDatabase, currentDiscordUser.Id)
 | 
				
			||||||
 | 
							if dbOAuthToken == "" {
 | 
				
			||||||
 | 
								context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
 | 
				
			||||||
 | 
								err := databasecommands.UpdateDatabaseUser(GlobalDatabase, updatedDatabaseUser)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Println(err)
 | 
				
			||||||
 | 
									context.AbortWithStatus(http.StatusInternalServerError)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								context.SetCookie("discord-oauthtoken", dbOAuthToken, 0, "", GlobalConfig.API.Domain, false, false)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							err := databasecommands.CreateDatabaseUser(GlobalDatabase, updatedDatabaseUser)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Println(err)
 | 
				
			||||||
 | 
								context.Copy().AbortWithStatus(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Read Endpoints (get/)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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")
 | 
						response, err := GlobalOAuth.Client(context.Request.Context(), oauthToken).Get("https://discord.com/api/users/@me")
 | 
				
			||||||
	if err != nil || response.StatusCode != 200 {
 | 
						if err != nil || response.StatusCode != 200 {
 | 
				
			||||||
		responseMessage := ""
 | 
							responseMessage := ""
 | 
				
			||||||
| 
						 | 
					@ -76,72 +124,43 @@ func GetDiscordUser(context *gin.Context, oauthToken *oauth2.Token) authdiscord.
 | 
				
			||||||
	return user
 | 
						return user
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func CreateOrUpdateUser(context *gin.Context, oauthToken *oauth2.Token, user authdiscord.DiscordUser) {
 | 
					func GetUserInfo(context *gin.Context) {
 | 
				
			||||||
	oauthTokenJSON, err := json.Marshal(oauthToken)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dbUser := databasemodels.User{
 | 
					 | 
				
			||||||
		DisplayName:      user.Global_Name,
 | 
					 | 
				
			||||||
		Username:         user.Username,
 | 
					 | 
				
			||||||
		Id:               user.Id,
 | 
					 | 
				
			||||||
		Avatar:           user.Avatar,
 | 
					 | 
				
			||||||
		AvatarDecoration: user.Avatar_Decoration_Data.Asset,
 | 
					 | 
				
			||||||
		LoginToken:       string(oauthTokenJSON),
 | 
					 | 
				
			||||||
		LoggedIn:         true,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if databasecommands.DatabaseUserExists(GlobalDatabase, user.Id) {
 | 
					 | 
				
			||||||
		dbOAuthToken := databasecommands.GetDatabaseUserToken(GlobalDatabase, user.Id)
 | 
					 | 
				
			||||||
		if dbOAuthToken == "" {
 | 
					 | 
				
			||||||
			context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
 | 
					 | 
				
			||||||
			err := databasecommands.UpdateDatabaseUser(GlobalDatabase, dbUser)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				log.Println(err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			context.SetCookie("discord-oauthtoken", dbOAuthToken, 0, "", GlobalConfig.API.Domain, false, false)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		err := databasecommands.CreateDatabaseUser(GlobalDatabase, dbUser)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			log.Println(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func GetDashboardInfo(context *gin.Context) {
 | 
					 | 
				
			||||||
	oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
						oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		var oauthToken *oauth2.Token
 | 
							var oauthToken *oauth2.Token
 | 
				
			||||||
		err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
 | 
							err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
 | 
				
			||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			if oauthToken.Valid() {
 | 
								if oauthToken.Valid() {
 | 
				
			||||||
				user := GetDiscordUser(context, oauthToken)
 | 
									user := getDiscordUser(context, oauthToken)
 | 
				
			||||||
				if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) {
 | 
									if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) {
 | 
				
			||||||
					context.JSON(http.StatusOK, user)
 | 
										context.JSON(http.StatusOK, user)
 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					context.Redirect(http.StatusTemporaryRedirect, "http://localhost:31337/logout")
 | 
										context.Redirect(http.StatusTemporaryRedirect, "http://localhost:31337/auth/logout")
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									log.Println(err)
 | 
				
			||||||
 | 
									context.AbortWithStatus(http.StatusBadRequest)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			log.Println(err)
 | 
								log.Println(err)
 | 
				
			||||||
 | 
								context.AbortWithStatus(http.StatusBadRequest)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		log.Println(err)
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							context.AbortWithStatus(http.StatusBadRequest)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
 | 
						context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func IsUserAuthorized(context *gin.Context) {
 | 
					func GetIsUserAuthorized(context *gin.Context) {
 | 
				
			||||||
	oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
						oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		var oauthToken *oauth2.Token
 | 
							var oauthToken *oauth2.Token
 | 
				
			||||||
		err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
 | 
							err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
 | 
				
			||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			if oauthToken.Valid() {
 | 
								if oauthToken.Valid() {
 | 
				
			||||||
				user := GetDiscordUser(context, oauthToken)
 | 
									user := getDiscordUser(context, oauthToken)
 | 
				
			||||||
				if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) {
 | 
									if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) {
 | 
				
			||||||
					context.JSON(http.StatusOK, gin.H{
 | 
										context.JSON(http.StatusOK, gin.H{
 | 
				
			||||||
						"message": true,
 | 
											"message": true,
 | 
				
			||||||
| 
						 | 
					@ -152,16 +171,12 @@ func IsUserAuthorized(context *gin.Context) {
 | 
				
			||||||
					})
 | 
										})
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				log.Println(err)
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			log.Println(err)
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	context.JSON(http.StatusUnauthorized, gin.H{
 | 
						context.JSON(http.StatusUnauthorized, gin.H{
 | 
				
			||||||
		"message": false,
 | 
							"message": false,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Delete Endpoints (delete/)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,3 +12,83 @@ type User struct {
 | 
				
			||||||
	LoginToken       string
 | 
						LoginToken       string
 | 
				
			||||||
	LoggedIn         bool
 | 
						LoggedIn         bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Person struct {
 | 
				
			||||||
 | 
						Name   string
 | 
				
			||||||
 | 
						Groups []Group // Unique
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Group struct {
 | 
				
			||||||
 | 
						Name string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Character struct {
 | 
				
			||||||
 | 
						Name         string
 | 
				
			||||||
 | 
						Owners       []Person // Unique
 | 
				
			||||||
 | 
						Roles        []Role   // Unique
 | 
				
			||||||
 | 
						FunctionSets []FunctionSet
 | 
				
			||||||
 | 
						Inventory    []InventorySlot
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Role struct {
 | 
				
			||||||
 | 
						Name       string
 | 
				
			||||||
 | 
						Tiers      []Tier
 | 
				
			||||||
 | 
						Visibility []Group // Unique
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Tier struct {
 | 
				
			||||||
 | 
						FunctionSets []FunctionSet
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FunctionSet struct {
 | 
				
			||||||
 | 
						Functions []Function
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Function struct {
 | 
				
			||||||
 | 
						Name         string
 | 
				
			||||||
 | 
						Tags         FunctionTag
 | 
				
			||||||
 | 
						Requirements []Function
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FunctionTag struct {
 | 
				
			||||||
 | 
						Name string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InventorySlot struct {
 | 
				
			||||||
 | 
						Item     Item
 | 
				
			||||||
 | 
						Quantity int64 // Positive
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Item struct {
 | 
				
			||||||
 | 
						Name                string
 | 
				
			||||||
 | 
						Functions           []Function
 | 
				
			||||||
 | 
						FlavorText          string
 | 
				
			||||||
 | 
						RulesDescription    string
 | 
				
			||||||
 | 
						PhysrepRequirements string
 | 
				
			||||||
 | 
						Tags                []ItemTag // Unique
 | 
				
			||||||
 | 
						Customizations      []Customization
 | 
				
			||||||
 | 
						Visibility          []Group // Unique
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ItemTag struct {
 | 
				
			||||||
 | 
						Naem string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Customization struct {
 | 
				
			||||||
 | 
						Name                string
 | 
				
			||||||
 | 
						Functions           []Function
 | 
				
			||||||
 | 
						FlavorText          string
 | 
				
			||||||
 | 
						RulesDescription    string
 | 
				
			||||||
 | 
						PhysrepRequirements string
 | 
				
			||||||
 | 
						Tags                []ItemTag // Unique
 | 
				
			||||||
 | 
						Visibility          []Group   // Unique
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Schematic struct {
 | 
				
			||||||
 | 
						Material     []InventorySlot
 | 
				
			||||||
 | 
						Tools        []InventorySlot
 | 
				
			||||||
 | 
						Requirements []Function
 | 
				
			||||||
 | 
						TimeUnits    int64 // Positive
 | 
				
			||||||
 | 
						Result       InventorySlot
 | 
				
			||||||
 | 
						Visibility   []Group // Unique
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue