We can interface with a db now.

This commit is contained in:
Ada Werefox 2025-04-21 21:05:50 -07:00
parent 719832b790
commit ccb06f2184
16 changed files with 126 additions and 57 deletions

3
.gitignore vendored
View file

@ -1,6 +1,9 @@
# Ignore config, don't commit credentials.
**/config.toml
# Ignore db/, don't commit the database.
*.db
# Ignore node_modules.
**/node_modules/*

0
db/.gitkeep Normal file
View file

View file

@ -8,6 +8,7 @@ import (
"os"
"strconv"
// "example.com/lib/dbcommands"
"github.com/gin-gonic/gin"
"github.com/pelletier/go-toml/v2"
"github.com/ravener/discord-oauth2"
@ -24,7 +25,6 @@ type appConfig struct {
}
type discordUser struct {
LoggedIn bool
Id string
Username string
Avatar string
@ -51,7 +51,6 @@ type discordUser struct {
var config appConfig
var oauthConfig *oauth2.Config
var oauthToken *oauth2.Token
var userInfo discordUser
func parseConfig(configPath string) {
configFile, err := os.Open(configPath)
@ -80,7 +79,7 @@ func createDiscordOAuthConfig(clientId string, clientSecret string, redirectUrl
}
func loginDisplay(context *gin.Context) {
if userInfo.LoggedIn {
if oauthToken.Valid() {
context.Redirect(http.StatusTemporaryRedirect, "/dashboard")
} else {
context.HTML(http.StatusOK, "root.html", gin.H{
@ -104,6 +103,10 @@ func authCallback(context *gin.Context) {
"message": "internalservererror",
})
}
context.Redirect(http.StatusTemporaryRedirect, "/dashboard")
}
func getDiscordUserInfo(context *gin.Context) discordUser {
response, err := oauthConfig.Client(context.Request.Context(), oauthToken).Get("https://discord.com/api/users/@me")
if err != nil || response.StatusCode != 200 {
responseMessage := ""
@ -125,13 +128,12 @@ func authCallback(context *gin.Context) {
}
var discordUserInfo discordUser
json.Unmarshal(body, &discordUserInfo)
discordUserInfo.LoggedIn = true
userInfo = discordUserInfo
context.Redirect(http.StatusTemporaryRedirect, "/dashboard")
return discordUserInfo
}
func dashboardDisplay(context *gin.Context) {
if userInfo.LoggedIn {
if oauthToken.Valid() {
userInfo := getDiscordUserInfo(context)
context.HTML(http.StatusOK, "dashboard.html", gin.H{
"discordUser": gin.H{
"id": userInfo.Id,
@ -163,6 +165,7 @@ func dashboardDisplay(context *gin.Context) {
}
func main() {
// db := dbcommands.InitializeDatabase()
parseConfig("config.toml")
oauthConfig = createDiscordOAuthConfig(config.OAuth.ClientID, config.OAuth.ClientSecret, config.OAuth.RedirectUrl)
app := gin.Default()
@ -172,5 +175,5 @@ func main() {
app.GET("/login", loginRedirect)
app.GET("/auth/callback", authCallback)
app.GET("/dashboard", dashboardDisplay)
app.Run()
app.Run(":8080")
}

9
go.mod
View file

@ -2,7 +2,10 @@ module gin-cpularp
go 1.24.2
replace example.com/lib/dbcommands => ./lib/dbcommands
require (
example.com/lib/dbcommands v0.0.0
github.com/bytedance/sonic v1.13.2 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
@ -14,10 +17,13 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.26.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
@ -33,4 +39,7 @@ require (
golang.org/x/text v0.24.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/sqlite v1.5.7 // indirect
gorm.io/gorm v1.25.12 // indirect
)

10
go.sum
View file

@ -24,6 +24,10 @@ github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAu
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
@ -34,6 +38,8 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -77,5 +83,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View file

@ -0,0 +1,24 @@
package dbcommands
import (
"log"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string
Id string
LoginToken string
}
func InitializeDatabase() *gorm.DB {
db, err := gorm.Open(sqlite.Open("db/main.db"), &gorm.Config{})
if err != nil {
log.Fatal("Failed to connect to database.")
}
db.AutoMigrate(&User{})
return db
}

12
lib/dbcommands/go.mod Normal file
View file

@ -0,0 +1,12 @@
module example.com/lib/dbc
go 1.24.2
require (
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
golang.org/x/text v0.14.0 // indirect
gorm.io/driver/sqlite v1.5.7 // indirect
gorm.io/gorm v1.25.12 // indirect
)

14
lib/dbcommands/go.sum Normal file
View file

@ -0,0 +1,14 @@
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde h1:9DShaph9qhkIYw7QF91I/ynrr4cOO2PZra2PFD7Mfeg=
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=

View file

@ -1 +1,6 @@
@import "tailwindcss" source("../templates");
@theme {
--color-primary: oklch(0.1 0 0);
--color-secondary: oklch(0.85 0.1733 93.56);
--color-accent: oklch(0.6 0.1556 246.71);
}

View file

@ -13,7 +13,7 @@
<body>
<div class="bg-gray-200">
<div class="min-h-screen">
<div class="container space-y-4 pt-4 pb-4 max-w-3xl">
<div class="container max-w-3xl pt-4 pb-4 space-y-4">
<h1 class="text-left">Oops!</h1>
<p class="text-lg">There was some problem with the authentication process...</p>
<p>{{ .message }}</p>

View file

@ -4,20 +4,26 @@
<head>
<title>Dashboard</title>
<meta charset="UTF-8">
<meta name="description" content="User dashboard.">
<meta name="keywords" content="HTML, CSS, JavaScript">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/public/css/style.css" />
</head>
<body>
<div class="bg-gray-950">
<div class="min-h-screen p-4">
<div class="container space-y-4 p-4 max-w-3xl ring-4 ring-cyan-200 bg-gray-950 mx-auto">
<div class="text-left text-lg pb-1 font-mono ring-4 ring-cyan-400 bg-gray-800 text-white px-4">
<h1>> USER AUTHENTICATED</h1>
<div class="bg-black">
<div class="min-h-screen p-2 md:p-4">
<div
class="container max-w-3xl p-4 mx-auto space-y-2 font-mono text-white bg-primary min-w-xs md:space-y-4">
<div class="p-2 bg-secondary md:p-4 ring-2 ring-secondary/80">
<div class="bg-primary ring-2 ring-primary/80">
<div class="flex flex-col w-full h-full p-2 space-x-4 rounded-sm space-2 drop-shadow-md drop-shadow-accent">
<h1 class="text-md md:text-xl">> USER AUTHENTICATED</h1>
</div>
</div>
</div>
<div class="p-2 bg-secondary md:p-4 ring-2 ring-secondary/80">
{{ template "userinfo.html" .discordUser }}
</div>
{{ template "userinfo.html" .discordUser }}
</div>
</div>
</div>

View file

View file

@ -13,7 +13,7 @@
<body>
<div class="bg-gray-200">
<div class="min-h-screen">
<div class="container space-y-4 pt-4 pb-4 max-w-3xl">
<div class="container max-w-3xl pt-4 pb-4 space-y-4">
<h1 class="text-left">Oops!</h1>
<p class="text-lg">We experienced some kind of server error...</p>
<p>{{ .message }}</p>

View file

@ -4,7 +4,6 @@
<head>
<title>Hello!</title>
<meta charset="UTF-8">
<meta name="description" content="Root page.">
<meta name="keywords" content="HTML, CSS, JavaScript">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/public/css/style.css" />
@ -13,14 +12,14 @@
<body>
<div class="bg-gray-200">
<div class="min-h-screen px-4">
<div class="container space-y-4 pt-4 pb-4 max-w-3xl m-auto w-full">
<h1 class="text-center text-3xl">Welcome!</h1>
<div class="container w-full max-w-3xl pt-4 pb-4 m-auto space-y-4">
<h1 class="text-3xl text-center">Welcome!</h1>
<div class="border-2 border-gray-900 border-solid bg-[#eeea] p-4">
<div class="flex flex-col text-lg text-left align-middle m-auto">
<div class="flex flex-col m-auto text-lg text-left align-middle">
<div class="flex flex-col space-y-2">
<p>There really isn't much here yet, but you can log in with Discord.</p>
<a class="ring-2 ring-black bg-blue-600 text-lg" href="/login">
<div class="m-auto align-middle text-center text-lg text-white">
<a class="text-lg bg-blue-600 ring-2 ring-black" href="/login">
<div class="m-auto text-lg text-center text-white align-middle">
Login to Discord
</div>
</a>

View file

@ -1,35 +1,19 @@
<div class="flex flex-col ring-4 ring-cyan-400 p-4 space-y-2 text-white font-mono"
style="background-color: {{ .banner_color }};">
<p>> ID: {{ .id }}</p>
<p>> USERNAME: {{ .username }}</p>
<p>> DISPLAY NAME: {{ .global_name }}</p>
<p>> AVATAR</p>
<div class="ring-2 ring-cyan-600 p-2 bg-gray-700 max-w-fit">
<img src="https://cdn.discordapp.com/avatars/{{ .id }}/{{ .avatar }}.png" />
</div>
<p>> BANNER</p>
<div class="ring-2 ring-cyan-600 p-2 bg-gray-700 max-w-fit">
<img src="https://cdn.discordapp.com/banners/{{ .id }}/{{ .banner }}.png?size=512" />
</div>
<p>discriminator: {{ .discriminator }}</p>
<p>public_flags: {{ .public_flags }}</p>
<p>flags: {{ .flags }}</p>
<p>accent_color: {{ .accent_color }}</p>
<details class="p-2 ring-2 ring-cyan-400 bg-gray-700 space-y-2">
<summary>avatar_decoration_data</summary>
<div class="text-lg ring-2 ring-cyan-400 p-2 space-y-2">
<div class="flex flex-col space-y-2">
<p>asset: {{ .avatar_decoration_data.asset }}</p>
<p>sku_id: {{ .avatar_decoration_data.sku_id }}</p>
<p>expires_at: {{ .avatar_decoration_data.expires_at }}</p>
</div>
<div class="bg-primary ring-2 ring-primary/80">
<div class="flex flex-row w-full h-full p-4 space-x-4 rounded-sm">
<div class="md:min-w-fit md:min-h-fit md:max-w-fit md:max-h-fit max-w-32 max-h-32">
<img class="fixed z-1 max-w-[96px] max-h-[96px] md:max-w-[128px] md:max-h-[128px]"
src="https://cdn.discordapp.com/avatar-decoration-presets/{{ .avatar_decoration_data.asset }}.png" />
<img class="max-w-[96px] max-h-[96px] mask-clip-border rounded-full md:max-w-[128px] md:max-h-[128px] drop-shadow-accent drop-shadow-md border-8 border-accent"
src="https://cdn.discordapp.com/avatars/{{ .id }}/{{ .avatar }}.png" />
</div>
</details>
<p>collectibles: {{ .collectibles }}</p>
<p>banner_color: {{ .banner_color }}</p>
<p>clan: {{ .clan }}</p>
<p>primary_guild: {{ .primary_guild }}</p>
<p>mfa_enabled: {{ .mfa_enabled }}</p>
<p>locale: {{ .locale }}</p>
<p>premium_type: {{ .premium_type }}</p>
<div class="w-full m-auto drop-shadow-md drop-shadow-accent text-accent">
<p class="text-xl md:text-3xl">
{{ .global_name }}
</p>
<a class="ml-2 text-white text-md md:text-xl hover:text-gray-300" href="https://discord.com/users/{{ .id }}"
target="_blank">
@{{ .username }}
</a>
</div>
</div>
</div>

0
tailwind.config.js Normal file
View file