cpularp-manager-api/src/lib/api/api.go

271 lines
7.7 KiB
Go
Raw Normal View History

2025-04-24 13:58:05 -05:00
package api
import (
"encoding/json"
"fmt"
2025-04-24 13:58:05 -05:00
"log"
"net/http"
authdiscord "example.com/auth/discord"
configserver "example.com/config/server"
function "example.com/database/function"
functiontag "example.com/database/functiontag"
group "example.com/database/group"
user "example.com/database/user"
2025-04-24 13:58:05 -05:00
"github.com/gin-gonic/gin"
"github.com/xyproto/randomstring"
"golang.org/x/oauth2"
"gorm.io/gorm"
)
var GlobalDatabase *gorm.DB
var GlobalConfig configserver.AppConfig
var GlobalOAuth *oauth2.Config
// Private Functions
2025-04-24 17:08:09 -05:00
// Authentication Workflow
func AuthCallback(context *gin.Context) {
oauthState := randomstring.CookieFriendlyString(32)
context.Set("state", oauthState)
var err error
oauthToken, err := GlobalOAuth.Exchange(context.Request.Context(), context.Query("code"))
if err != nil {
context.Redirect(http.StatusInternalServerError, GlobalConfig.GetFrontendRootDomain())
2025-04-24 17:08:09 -05:00
}
oauthTokenJSON, _ := json.Marshal(oauthToken)
context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
context.Set("discord-oauthtoken", string(oauthTokenJSON))
CreateOrUpdateUser(context)
context.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%sdashboard", GlobalConfig.GetFrontendRootDomain()))
2025-04-24 17:08:09 -05:00
}
func AuthLoginRedirect(context *gin.Context) {
2025-04-24 13:58:05 -05:00
context.Redirect(302, GlobalOAuth.AuthCodeURL(context.GetString("state")))
}
2025-04-24 17:08:09 -05:00
func AuthLogoutRedirect(context *gin.Context) {
2025-04-24 13:58:05 -05:00
oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
if err == nil {
2025-04-29 00:42:57 -05:00
user.Logout(GlobalDatabase, oauthTokenJSON)
2025-04-24 13:58:05 -05:00
context.SetCookie("discord-oauthtoken", "", -1, "", GlobalConfig.API.Domain, false, true)
} else {
log.Println(err)
}
context.Redirect(http.StatusTemporaryRedirect, GlobalConfig.GetFrontendRootDomain())
2025-04-24 13:58:05 -05:00
}
2025-04-24 17:08:09 -05:00
func CreateOrUpdateUser(context *gin.Context) {
2025-04-25 17:39:40 -05:00
oauthTokenJSON := context.GetString("discord-oauthtoken")
err := error(nil)
if oauthTokenJSON == "" {
oauthTokenJSON, err = context.Cookie("discord-oauthtoken")
if err != nil {
log.Printf("This really shouldn't happen. %s", err)
context.AbortWithStatus(http.StatusInternalServerError)
}
2025-04-24 17:08:09 -05:00
}
var oauthToken *oauth2.Token
err = json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
if err != nil {
log.Println(err)
context.AbortWithStatus(http.StatusBadRequest)
}
var currentDiscordUser authdiscord.DiscordUser
currentDiscordUser.GetDiscordUser(context, oauthToken, GlobalConfig, GlobalOAuth)
updatedDatabaseUser := user.User{
2025-04-24 17:08:09 -05:00
DisplayName: currentDiscordUser.Global_Name,
Username: currentDiscordUser.Username,
Id: currentDiscordUser.Id,
Avatar: currentDiscordUser.Avatar,
AvatarDecoration: currentDiscordUser.Avatar_Decoration_Data.Asset,
LoginToken: string(oauthTokenJSON),
LoggedIn: true,
ApiKey: nil,
2025-04-24 17:08:09 -05:00
}
if user.Exists(GlobalDatabase, currentDiscordUser.Id) {
dbOAuthToken := user.GetTokenFromUserId(GlobalDatabase, currentDiscordUser.Id)
if user.GetLoggedInFromDiscordId(GlobalDatabase, currentDiscordUser.Id) {
2025-04-24 17:08:09 -05:00
context.SetCookie("discord-oauthtoken", dbOAuthToken, 0, "", GlobalConfig.API.Domain, false, false)
2025-04-25 17:39:40 -05:00
updatedDatabaseUser.LoginToken = string(dbOAuthToken)
} else {
context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
}
err := updatedDatabaseUser.Update(GlobalDatabase)
if err != nil {
log.Println(err)
context.AbortWithStatus(http.StatusInternalServerError)
2025-04-24 17:08:09 -05:00
}
} else {
err := updatedDatabaseUser.Create(GlobalDatabase)
2025-04-24 17:08:09 -05:00
if err != nil {
log.Println(err)
context.Copy().AbortWithStatus(http.StatusInternalServerError)
}
2025-04-24 13:58:05 -05:00
}
}
2025-04-29 00:42:57 -05:00
// Create Endpoints (post/)
func CreateGroup(context *gin.Context) {
GetUserLoggedIn(context)
isAuthorized := context.GetBool("is-authorized")
if isAuthorized {
2025-04-29 00:42:57 -05:00
name, nameOk := context.GetQuery("name")
if nameOk {
group.Create(GlobalDatabase, name)
context.Status(http.StatusOK)
} else {
context.AbortWithStatus(http.StatusBadRequest)
}
} else {
context.AbortWithStatus(http.StatusUnauthorized)
}
2025-04-24 13:58:05 -05:00
}
2025-04-29 00:42:57 -05:00
func CreateFunction(context *gin.Context) {
GetUserLoggedIn(context)
2025-04-25 17:39:40 -05:00
isAuthorized := context.GetBool("is-authorized")
if isAuthorized {
name, nameOk := context.GetQuery("name")
2025-04-29 00:42:57 -05:00
tags := context.QueryArray("tags")
requirements := context.QueryArray("requirements")
if nameOk {
2025-04-29 00:42:57 -05:00
function.Create(GlobalDatabase, name, tags, requirements)
2025-04-25 17:39:40 -05:00
context.Status(http.StatusOK)
} else {
context.AbortWithStatus(http.StatusBadRequest)
}
} else {
context.AbortWithStatus(http.StatusUnauthorized)
}
}
2025-04-29 00:42:57 -05:00
func CreateFunctionTag(context *gin.Context) {
GetUserLoggedIn(context)
2025-04-25 17:39:40 -05:00
isAuthorized := context.GetBool("is-authorized")
if isAuthorized {
name := context.Query("name")
if name != "" {
2025-04-29 00:42:57 -05:00
functiontag.Create(GlobalDatabase, name)
2025-04-25 17:39:40 -05:00
context.Status(http.StatusOK)
} else {
context.AbortWithStatus(http.StatusBadRequest)
}
} else {
context.AbortWithStatus(http.StatusUnauthorized)
}
}
2025-04-29 00:42:57 -05:00
// Update Endpoints (put/)
// Read Endpoints (get/)
2025-04-29 00:42:57 -05:00
func GetDiscordUser(context *gin.Context) {
2025-04-24 13:58:05 -05:00
oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
if err == nil {
var oauthToken *oauth2.Token
err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
if err == nil {
if oauthToken.Valid() {
var discordUser authdiscord.DiscordUser
discordUser.GetDiscordUser(context, oauthToken, GlobalConfig, GlobalOAuth)
if user.GetLoggedInFromDiscordId(GlobalDatabase, discordUser.Id) {
context.JSON(http.StatusOK, discordUser)
2025-04-24 13:58:05 -05:00
} else {
context.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%slogout", GlobalConfig.GetAPIRootDomain()))
2025-04-24 13:58:05 -05:00
}
return
2025-04-24 17:08:09 -05:00
} else {
log.Println(err)
context.AbortWithStatus(http.StatusBadRequest)
2025-04-24 13:58:05 -05:00
}
} else {
log.Println(err)
2025-04-24 17:08:09 -05:00
context.AbortWithStatus(http.StatusBadRequest)
2025-04-24 13:58:05 -05:00
}
} else {
log.Println(err)
2025-04-24 17:08:09 -05:00
context.AbortWithStatus(http.StatusBadRequest)
2025-04-24 13:58:05 -05:00
}
context.Redirect(http.StatusTemporaryRedirect, GlobalConfig.GetFrontendRootDomain())
2025-04-24 13:58:05 -05:00
}
2025-04-29 00:42:57 -05:00
func GetUserLoggedIn(context *gin.Context) {
2025-04-24 13:58:05 -05:00
oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
if err == nil {
var oauthToken *oauth2.Token
err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
if err == nil {
if oauthToken.Valid() {
if user.GetLoggedInFromOAuthToken(GlobalDatabase, oauthTokenJSON) {
2025-04-24 13:58:05 -05:00
context.JSON(http.StatusOK, gin.H{
"message": true,
})
context.Set("is-authorized", true)
return
2025-04-24 13:58:05 -05:00
}
}
}
}
context.JSON(http.StatusUnauthorized, gin.H{
"message": false,
})
context.Set("is-authorized", false)
2025-04-24 13:58:05 -05:00
}
2025-04-24 17:08:09 -05:00
2025-04-29 00:42:57 -05:00
func GetGroups(context *gin.Context) {
groupNames, ok := context.GetQueryArray("groups")
if ok {
context.JSON(http.StatusOK, gin.H{
2025-04-29 00:42:57 -05:00
"groups": group.Get(GlobalDatabase, groupNames),
})
} else {
2025-04-29 00:42:57 -05:00
context.Status(http.StatusBadRequest)
}
}
2025-04-29 00:42:57 -05:00
func GetAllGroups(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
2025-04-29 00:42:57 -05:00
"groups": group.GetAll(GlobalDatabase),
})
}
2025-04-29 00:42:57 -05:00
func GetFunctions(context *gin.Context) {
functionNames, ok := context.GetQueryArray("functions")
if ok {
context.JSON(http.StatusOK, gin.H{
2025-04-29 00:42:57 -05:00
"functions": function.Get(GlobalDatabase, functionNames),
})
2025-04-25 17:39:40 -05:00
} else {
2025-04-29 00:42:57 -05:00
context.Status(http.StatusBadRequest)
2025-04-25 17:39:40 -05:00
}
}
2025-04-29 00:42:57 -05:00
func GetAllFunctions(context *gin.Context) {
2025-04-25 17:39:40 -05:00
context.JSON(http.StatusOK, gin.H{
2025-04-29 00:42:57 -05:00
"functions": function.GetAll(GlobalDatabase),
2025-04-25 17:39:40 -05:00
})
}
2025-04-29 00:42:57 -05:00
func GetFunctionTags(context *gin.Context) {
functionTagNames, ok := context.GetQueryArray("functiontags")
if ok {
context.JSON(http.StatusOK, gin.H{
2025-04-29 00:42:57 -05:00
"function_tags": functiontag.Get(GlobalDatabase, functionTagNames),
})
2025-04-25 17:39:40 -05:00
} else {
2025-04-29 00:42:57 -05:00
context.Status(http.StatusBadRequest)
2025-04-25 17:39:40 -05:00
}
}
2025-04-29 00:42:57 -05:00
func GetAllFunctionTags(context *gin.Context) {
2025-04-25 17:39:40 -05:00
context.JSON(http.StatusOK, gin.H{
2025-04-29 00:42:57 -05:00
"function_tags": functiontag.GetAll(GlobalDatabase),
2025-04-25 17:39:40 -05:00
})
}
2025-04-24 17:08:09 -05:00
// Delete Endpoints (delete/)