@@ 30,6 30,7 @@ require (
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/oklog/ulid/v2 v2.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
@@ 61,6 61,9 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
+github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
+github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ 1,11 1,16 @@
package handlers
import (
+ "context"
+ "log"
"net/http"
"tixe/auth"
+ "tixe/db"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
+ "github.com/jackc/pgx/v5"
+ "github.com/oklog/ulid/v2"
)
func AuthCallback(auth *auth.Auth) gin.HandlerFunc {
@@ 30,14 35,43 @@ func AuthCallback(auth *auth.Auth) gin.HandlerFunc {
var profile map[string]interface{}
if err := idToken.Claims(&profile); err != nil {
- c.String(http.StatusInternalServerError, err.Error())
+ log.Printf("[tixe/auth] ERROR: Failed to get claims")
+ c.String(http.StatusInternalServerError, "Failed to get claims!")
return
}
+ // Try to get the relevant details of the user
+ var userId string
+ // idToken.Subject should be unique and should not change.
+ // I think. Maybe. Possibly. Hopefully.
+ scanErr := db.PgPool.QueryRow(context.Background(),
+ "SELECT id FROM users WHERE oidc_subject = $1", idToken.Subject).Scan(&userId)
+ if scanErr == pgx.ErrNoRows {
+ log.Printf("[tixe/auth] New user detected logging in, creating entry in database")
+ // The user does not exist in the db, create it
+ userId = ulid.Make().String()
+ _, err = db.PgPool.Exec(context.Background(),
+ "INSERT INTO users(id, display_name, oidc_subject) VALUES($1, $2, $3)",
+ userId, profile["name"].(string), idToken.Subject)
+ if err != nil {
+ log.Printf("[tixe/auth] ERROR: Could not create database entry for oidc user")
+ c.String(http.StatusInternalServerError, "Could not create database entry for oidc user")
+ return
+ }
+ } else if scanErr != nil {
+ // scanErr was some other error than ErrNoRows
+ log.Printf("[tixe/auth] ERROR: Could not query database for oidc user: %v", scanErr)
+ c.String(http.StatusInternalServerError, "Could not query database for oidc user")
+ return
+ }
+
+ // The user_id field is read in other requests to read user data from the db
+ session.Set("user_id", userId)
session.Set("access_token", token.AccessToken)
session.Set("profile", profile)
if err := session.Save(); err != nil {
- c.String(http.StatusInternalServerError, err.Error())
+ log.Printf("[tixe/auth] ERROR: Failed to save session")
+ c.String(http.StatusInternalServerError, "Failed to save session!")
return
}