feat: add support for Postgres database provider (#79)

This commit is contained in:
Elias Schneider
2024-12-12 17:21:28 +01:00
committed by GitHub
parent e9d83dd6c3
commit 9d20a98dbb
38 changed files with 433 additions and 81 deletions

View File

@@ -60,7 +60,7 @@ func (s *TestService) SeedDatabase() error {
userGroups := []model.UserGroup{
{
Base: model.Base{
ID: "4110f814-56f1-4b28-8998-752b69bc97c0e",
ID: "c7ae7c01-28a3-4f3c-9572-1ee734ea8368",
},
Name: "developers",
FriendlyName: "Developers",
@@ -146,7 +146,7 @@ func (s *TestService) SeedDatabase() error {
webauthnCredentials := []model.WebauthnCredential{
{
Name: "Passkey 1",
CredentialID: "test-credential-1",
CredentialID: []byte("test-credential-1"),
PublicKey: publicKey1,
AttestationType: "none",
Transport: model.AuthenticatorTransportList{protocol.Internal},
@@ -154,7 +154,7 @@ func (s *TestService) SeedDatabase() error {
},
{
Name: "Passkey 2",
CredentialID: "test-credential-2",
CredentialID: []byte("test-credential-2"),
PublicKey: publicKey2,
AttestationType: "none",
Transport: model.AuthenticatorTransportList{protocol.Internal},
@@ -169,7 +169,7 @@ func (s *TestService) SeedDatabase() error {
webauthnSession := model.WebauthnSession{
Challenge: "challenge",
ExpiresAt: time.Now().Add(1 * time.Hour),
ExpiresAt: datatype.DateTime(time.Now().Add(1 * time.Hour)),
UserVerification: "preferred",
}
if err := tx.Create(&webauthnSession).Error; err != nil {
@@ -183,13 +183,29 @@ func (s *TestService) SeedDatabase() error {
func (s *TestService) ResetDatabase() error {
err := s.db.Transaction(func(tx *gorm.DB) error {
var tables []string
if err := tx.Raw("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name != 'schema_migrations';").Scan(&tables).Error; err != nil {
return err
switch common.EnvConfig.DbProvider {
case common.DbProviderSqlite:
// Query to get all tables for SQLite
if err := tx.Raw("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name != 'schema_migrations';").Scan(&tables).Error; err != nil {
return err
}
case common.DbProviderPostgres:
// Query to get all tables for PostgreSQL
if err := tx.Raw(`
SELECT tablename
FROM pg_tables
WHERE schemaname = 'public' AND tablename != 'schema_migrations';
`).Scan(&tables).Error; err != nil {
return err
}
default:
return fmt.Errorf("unsupported database provider: %s", common.EnvConfig.DbProvider)
}
// Delete all rows from all tables
for _, table := range tables {
if err := tx.Exec("DELETE FROM " + table).Error; err != nil {
if err := tx.Exec(fmt.Sprintf("DELETE FROM %s;", table)).Error; err != nil {
return err
}
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/go-webauthn/webauthn/webauthn"
"github.com/stonith404/pocket-id/backend/internal/common"
"github.com/stonith404/pocket-id/backend/internal/model"
datatype "github.com/stonith404/pocket-id/backend/internal/model/types"
"github.com/stonith404/pocket-id/backend/internal/utils"
"gorm.io/gorm"
"net/http"
@@ -55,7 +56,7 @@ func (s *WebAuthnService) BeginRegistration(userID string) (*model.PublicKeyCred
}
sessionToStore := &model.WebauthnSession{
ExpiresAt: session.Expires,
ExpiresAt: datatype.DateTime(session.Expires),
Challenge: session.Challenge,
UserVerification: string(session.UserVerification),
}
@@ -79,7 +80,7 @@ func (s *WebAuthnService) VerifyRegistration(sessionID, userID string, r *http.R
session := webauthn.SessionData{
Challenge: storedSession.Challenge,
Expires: storedSession.ExpiresAt,
Expires: storedSession.ExpiresAt.ToTime(),
UserID: []byte(userID),
}
@@ -95,7 +96,7 @@ func (s *WebAuthnService) VerifyRegistration(sessionID, userID string, r *http.R
credentialToStore := model.WebauthnCredential{
Name: "New Passkey",
CredentialID: string(credential.ID),
CredentialID: credential.ID,
AttestationType: credential.AttestationType,
PublicKey: credential.PublicKey,
Transport: credential.Transport,
@@ -117,7 +118,7 @@ func (s *WebAuthnService) BeginLogin() (*model.PublicKeyCredentialRequestOptions
}
sessionToStore := &model.WebauthnSession{
ExpiresAt: session.Expires,
ExpiresAt: datatype.DateTime(session.Expires),
Challenge: session.Challenge,
UserVerification: string(session.UserVerification),
}
@@ -133,7 +134,7 @@ func (s *WebAuthnService) BeginLogin() (*model.PublicKeyCredentialRequestOptions
}, nil
}
func (s *WebAuthnService) VerifyLogin(sessionID, userID string, credentialAssertionData *protocol.ParsedCredentialAssertionData, ipAddress, userAgent string) (model.User, string, error) {
func (s *WebAuthnService) VerifyLogin(sessionID string, credentialAssertionData *protocol.ParsedCredentialAssertionData, ipAddress, userAgent string) (model.User, string, error) {
var storedSession model.WebauthnSession
if err := s.db.First(&storedSession, "id = ?", sessionID).Error; err != nil {
return model.User{}, "", err
@@ -141,7 +142,7 @@ func (s *WebAuthnService) VerifyLogin(sessionID, userID string, credentialAssert
session := webauthn.SessionData{
Challenge: storedSession.Challenge,
Expires: storedSession.ExpiresAt,
Expires: storedSession.ExpiresAt.ToTime(),
}
var user *model.User
@@ -156,10 +157,6 @@ func (s *WebAuthnService) VerifyLogin(sessionID, userID string, credentialAssert
return model.User{}, "", err
}
if err := s.db.Find(&user, "id = ?", userID).Error; err != nil {
return model.User{}, "", err
}
token, err := s.jwtService.GenerateAccessToken(*user)
if err != nil {
return model.User{}, "", err