DEVELOPMENT ENVIRONMENT

~liljamo/tixe

3c1030aaeb6a4c3f4035c202e87ae85076e992a0 — Jonni Liljamo 1 year, 29 days ago 364eac5
feat: create user in db on login
3 files changed, 40 insertions(+), 2 deletions(-)

M go.mod
M go.sum
M handlers/auth.go
M go.mod => go.mod +1 -0
@@ 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

M go.sum => go.sum +3 -0
@@ 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=

M handlers/auth.go => handlers/auth.go +36 -2
@@ 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
		}