mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-06-12 22:40:13 +00:00
feat: add backend for oidc consent
This commit is contained in:
@@ -59,6 +59,7 @@ type AuthService struct {
|
||||
log *logger.Logger
|
||||
config model.Config
|
||||
runtime model.RuntimeConfig
|
||||
helpers model.RuntimeHelpers
|
||||
ctx context.Context
|
||||
|
||||
ldap *LdapService
|
||||
@@ -86,6 +87,7 @@ func NewAuthService(
|
||||
log *logger.Logger,
|
||||
config model.Config,
|
||||
runtime model.RuntimeConfig,
|
||||
helpers model.RuntimeHelpers,
|
||||
ctx context.Context,
|
||||
dg *ding.Ding,
|
||||
ldap *LdapService,
|
||||
@@ -97,6 +99,7 @@ func NewAuthService(
|
||||
service := &AuthService{
|
||||
log: log,
|
||||
runtime: runtime,
|
||||
helpers: helpers,
|
||||
ctx: ctx,
|
||||
config: config,
|
||||
ldap: ldap,
|
||||
@@ -322,7 +325,7 @@ func (auth *AuthService) IsEmailWhitelisted(provider string, email string) bool
|
||||
})
|
||||
}
|
||||
|
||||
func (auth *AuthService) CreateSession(ctx context.Context, data repository.Session) (*http.Cookie, error) {
|
||||
func (auth *AuthService) CreateSession(ctx context.Context, data repository.Session, ip string) (*http.Cookie, error) {
|
||||
if data.Provider == "tailscale" && auth.tailscale == nil {
|
||||
return nil, fmt.Errorf("tailscale service not configured, cannot create session for tailscale user")
|
||||
}
|
||||
@@ -363,33 +366,17 @@ func (auth *AuthService) CreateSession(ctx context.Context, data repository.Sess
|
||||
return nil, fmt.Errorf("failed to create session entry: %w", err)
|
||||
}
|
||||
|
||||
if data.Provider == "tailscale" {
|
||||
auth.log.App.Trace().Str("url", fmt.Sprintf("https://%s", auth.tailscale.GetHostname())).Msg("Extracting root domain from Tailscale hostname")
|
||||
cookieDomain, err := auth.helpers.GetCookieDomain(ctx, ip)
|
||||
|
||||
tsCookieDomain, err := utils.GetCookieDomain(fmt.Sprintf("https://%s", auth.tailscale.GetHostname()))
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get cookie domain for tailscale user: %w", err)
|
||||
}
|
||||
|
||||
return &http.Cookie{
|
||||
Name: auth.runtime.SessionCookieName,
|
||||
Value: session.UUID,
|
||||
Path: "/",
|
||||
Domain: fmt.Sprintf(".%s", tsCookieDomain),
|
||||
Expires: expiresAt,
|
||||
MaxAge: int(time.Until(expiresAt).Seconds()),
|
||||
Secure: auth.config.Auth.SecureCookie,
|
||||
HttpOnly: true,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
}, nil
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to determine cookie domain: %w", err)
|
||||
}
|
||||
|
||||
return &http.Cookie{
|
||||
Name: auth.runtime.SessionCookieName,
|
||||
Value: session.UUID,
|
||||
Path: "/",
|
||||
Domain: fmt.Sprintf(".%s", auth.runtime.CookieDomain),
|
||||
Domain: cookieDomain,
|
||||
Expires: expiresAt,
|
||||
MaxAge: int(time.Until(expiresAt).Seconds()),
|
||||
Secure: auth.config.Auth.SecureCookie,
|
||||
@@ -398,13 +385,17 @@ func (auth *AuthService) CreateSession(ctx context.Context, data repository.Sess
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (auth *AuthService) RefreshSession(ctx context.Context, uuid string) (*http.Cookie, error) {
|
||||
func (auth *AuthService) RefreshSession(ctx context.Context, uuid string, ip string) (*http.Cookie, error) {
|
||||
session, err := auth.queries.GetSession(ctx, uuid)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to retrieve session: %w", err)
|
||||
}
|
||||
|
||||
if session.Provider == "tailscale" && auth.tailscale == nil {
|
||||
return nil, fmt.Errorf("tailscale service not configured, cannot create session for tailscale user")
|
||||
}
|
||||
|
||||
currentTime := time.Now().Unix()
|
||||
|
||||
var refreshThreshold int64
|
||||
@@ -438,11 +429,17 @@ func (auth *AuthService) RefreshSession(ctx context.Context, uuid string) (*http
|
||||
return nil, fmt.Errorf("failed to update session expiry: %w", err)
|
||||
}
|
||||
|
||||
cookieDomain, err := auth.helpers.GetCookieDomain(ctx, ip)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to determine cookie domain: %w", err)
|
||||
}
|
||||
|
||||
return &http.Cookie{
|
||||
Name: auth.runtime.SessionCookieName,
|
||||
Value: session.UUID,
|
||||
Path: "/",
|
||||
Domain: fmt.Sprintf(".%s", auth.runtime.CookieDomain),
|
||||
Domain: cookieDomain,
|
||||
Expires: time.Now().Add(time.Duration(newExpiry-currentTime) * time.Second),
|
||||
MaxAge: int(newExpiry - currentTime),
|
||||
Secure: auth.config.Auth.SecureCookie,
|
||||
@@ -452,18 +449,24 @@ func (auth *AuthService) RefreshSession(ctx context.Context, uuid string) (*http
|
||||
|
||||
}
|
||||
|
||||
func (auth *AuthService) DeleteSession(ctx context.Context, uuid string) (*http.Cookie, error) {
|
||||
func (auth *AuthService) DeleteSession(ctx context.Context, uuid string, ip string) (*http.Cookie, error) {
|
||||
err := auth.queries.DeleteSession(ctx, uuid)
|
||||
|
||||
if err != nil {
|
||||
auth.log.App.Error().Err(err).Str("uuid", uuid).Msg("Failed to delete session from database")
|
||||
}
|
||||
|
||||
cookieDomain, err := auth.helpers.GetCookieDomain(ctx, ip)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to determine cookie domain: %w", err)
|
||||
}
|
||||
|
||||
return &http.Cookie{
|
||||
Name: auth.runtime.SessionCookieName,
|
||||
Value: "",
|
||||
Path: "/",
|
||||
Domain: fmt.Sprintf(".%s", auth.runtime.CookieDomain),
|
||||
Domain: cookieDomain,
|
||||
Expires: time.Now(),
|
||||
MaxAge: -1,
|
||||
Secure: auth.config.Auth.SecureCookie,
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/google/uuid"
|
||||
"github.com/steveiliop56/ding"
|
||||
"github.com/tinyauthapp/tinyauth/internal/model"
|
||||
"github.com/tinyauthapp/tinyauth/internal/repository"
|
||||
@@ -904,3 +905,47 @@ func (service *OIDCService) DecodeAuthorizeJWT(tokenString string) (*AuthorizeRe
|
||||
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func (service *OIDCService) CreateConsentEntry(ctx context.Context, clientId string, scope string) (string, error) {
|
||||
u := uuid.New()
|
||||
|
||||
entry := repository.CreateOIDCConsentParams{
|
||||
UUID: u.String(),
|
||||
ClientID: clientId,
|
||||
Scopes: scope,
|
||||
}
|
||||
|
||||
_, err := service.queries.CreateOIDCConsent(ctx, entry)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return entry.UUID, nil
|
||||
}
|
||||
|
||||
func (service *OIDCService) GetConsentEntry(ctx context.Context, uuid string) (*repository.OidcConsent, error) {
|
||||
entry, err := service.queries.GetOIDCConsentByUUID(ctx, uuid)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, repository.ErrNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &entry, nil
|
||||
}
|
||||
|
||||
func (service *OIDCService) DeleteConsentEntry(ctx context.Context, uuid string) error {
|
||||
return service.queries.DeleteOIDCConsentByUUID(ctx, uuid)
|
||||
}
|
||||
|
||||
func (service *OIDCService) UpdateConsentEntry(ctx context.Context, uuid string, scopes string) error {
|
||||
_, err := service.queries.UpdateOIDCConsent(ctx, repository.UpdateOIDCConsentParams{
|
||||
UUID: uuid,
|
||||
Scopes: scopes,
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user