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