2024-08-21 15:43:24 +02:00
|
|
|
package oidc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-08-21 17:31:03 +02:00
|
|
|
"database/sql"
|
2024-08-21 15:43:24 +02:00
|
|
|
"errors"
|
|
|
|
"net/http"
|
|
|
|
|
2024-08-22 15:15:16 +02:00
|
|
|
"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"
|
2024-08-21 15:43:24 +02:00
|
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
func HandleRedirect(c *fiber.Ctx) error {
|
2024-08-22 18:04:08 +02:00
|
|
|
if c.Query("redirect") != "" {
|
|
|
|
setCallbackCookie(c, "internal_redirect", c.Query("redirect"))
|
|
|
|
}
|
2024-08-21 17:31:03 +02:00
|
|
|
state := utils.RandString(16)
|
2024-08-21 15:43:24 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-08-21 17:31:03 +02:00
|
|
|
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")
|
2024-08-21 15:43:24 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-08-21 17:31:03 +02:00
|
|
|
_, err = db.Queries.GetUser(ctx, idToken.Subject)
|
|
|
|
if err == nil {
|
2024-08-22 14:58:43 +02:00
|
|
|
db.Queries.UpdateUserData(ctx, queries.UpdateUserDataParams{
|
2024-08-21 17:31:03 +02:00
|
|
|
Uid: idToken.Subject,
|
|
|
|
Email: claims.Email,
|
|
|
|
EmailVerified: claims.EmailVerified,
|
|
|
|
Username: claims.Username,
|
|
|
|
FullName: claims.Name,
|
|
|
|
})
|
|
|
|
} else if err == sql.ErrNoRows {
|
2024-08-22 14:58:43 +02:00
|
|
|
db.Queries.CreateUser(ctx, queries.CreateUserParams{
|
2024-08-21 17:31:03 +02:00
|
|
|
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
|
|
|
|
}
|
2024-08-21 15:43:24 +02:00
|
|
|
|
2024-08-22 12:57:38 +02:00
|
|
|
_, err = user.NewSession(idToken.Subject, c)
|
2024-08-21 17:31:03 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-08-21 15:43:24 +02:00
|
|
|
|
2024-08-22 18:04:08 +02:00
|
|
|
redirect := c.Cookies("internal_redirect")
|
2024-08-25 17:43:55 +02:00
|
|
|
c.ClearCookie("internal_redirect", "state")
|
2024-08-22 18:04:08 +02:00
|
|
|
if redirect != "" {
|
2024-08-25 17:43:55 +02:00
|
|
|
return c.Redirect(redirect, http.StatusFound)
|
2024-08-22 18:04:08 +02:00
|
|
|
}
|
2024-08-25 17:43:55 +02:00
|
|
|
return c.Redirect("/loggedin", http.StatusFound)
|
2024-08-21 15:43:24 +02:00
|
|
|
}
|