tijl.dev-core/internal/oidc/handler.go
tijl d246f5e270
All checks were successful
build / build (push) Successful in 40s
release-tag / release-image (push) Successful in 15m1s
flags
2024-08-26 14:22:24 +02:00

95 lines
2.3 KiB
Go

package oidc
import (
"context"
"database/sql"
"errors"
"net/http"
"git.tijl.dev/tijl/tijl.dev-core/internal/queries"
"git.tijl.dev/tijl/tijl.dev-core/internal/user"
"git.tijl.dev/tijl/tijl.dev-core/internal/utils"
"git.tijl.dev/tijl/tijl.dev-core/modules/db"
log "git.tijl.dev/tijl/tijl.dev-core/modules/logger"
"github.com/gofiber/fiber/v2"
)
func HandleRedirect(c *fiber.Ctx) error {
if c.Query("redirect") != "" {
setCallbackCookie(c, "internal_redirect", c.Query("redirect"))
}
state := utils.RandString(16)
setCallbackCookie(c, "state", state)
return c.Redirect(Config.AuthCodeURL(state), http.StatusFound)
}
func HandleCallback(c *fiber.Ctx) error {
ctx := context.Background()
state := c.Cookies("state")
if c.Query("state") != state {
return errors.New("invalid state")
}
oauth2Token, err := Config.Exchange(ctx, c.Query("code"))
if err != nil {
return err
}
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
return err
}
idToken, err := Verifier.Verify(ctx, rawIDToken)
if err != nil {
return err
}
var claims struct {
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
Name string `json:"name"`
Username string `json:"preferred_username"`
}
if err := idToken.Claims(&claims); err != nil {
log.Error().Err(err).Msg("error getting claims")
return err
}
_, err = db.Queries.GetUser(ctx, idToken.Subject)
if err == nil {
err = db.Queries.UpdateUserData(ctx, queries.UpdateUserDataParams{
Uid: idToken.Subject,
Email: claims.Email,
EmailVerified: claims.EmailVerified,
Username: claims.Username,
FullName: claims.Name,
})
} else if err == sql.ErrNoRows {
err = db.Queries.CreateUser(ctx, queries.CreateUserParams{
Uid: idToken.Subject,
Email: claims.Email,
EmailVerified: claims.EmailVerified,
Username: claims.Username,
FullName: claims.Name,
})
} else {
log.Error().Err(err).Msg("error getting user")
return err
}
if err != nil {
return err
}
_, err = user.NewSession(idToken.Subject, c)
if err != nil {
return err
}
redirect := c.Cookies("internal_redirect")
utils.ClearCookie(c, "internal_redirect")
utils.ClearCookie(c, "state")
if redirect != "" {
return c.Redirect(redirect, http.StatusFound)
}
return c.Redirect("/loggedin", http.StatusFound)
}