sipd-auth/utils/captcha_store/postgresql_store.go
2025-09-16 08:32:11 +07:00

89 lines
2.2 KiB
Go

package captcha_store
import (
"context"
"log"
"time"
"github.com/dchest/captcha"
"github.com/jackc/pgx/v5/pgxpool"
)
// PostgreSQLStore implements captcha.Store interface for PostgreSQL storage.
type PostgreSQLStore struct {
db *pgxpool.Pool
}
// NewPostgreSQLStore creates a new PostgreSQLStore instance.
func NewPostgreSQLStore(db *pgxpool.Pool) *PostgreSQLStore {
return &PostgreSQLStore{db: db}
}
// Set stores the captcha value with the provided ID.
func (s *PostgreSQLStore) Set(id string, digits []byte) {
q := `INSERT INTO captchas (captcha_id, captcha_value, created_at)
VALUES ($1, $2, $3)
ON CONFLICT(captcha_id) DO UPDATE SET captcha_value=EXCLUDED.captcha_value`
_, err := s.db.Exec(context.Background(), q, id, digits, time.Now())
if err != nil {
log.Println("Error inserting captcha into database:", err)
}
}
// Get retrieves the captcha value for the provided ID.
func (s *PostgreSQLStore) Get(id string, clear bool) (digits []byte) {
var err error
var captchaValue []byte
/*tx, err := s.db.BeginTx(context.Background(), pgx.TxOptions{})
if err != nil {
log.Println("Error creating tx:", err)
}
defer func() {
if err != nil {
tx.Rollback(context.Background())
} else {
tx.Commit(context.Background())
}
}()*/
q := `SELECT captcha_value FROM captchas WHERE captcha_id = $1`
err = s.db.QueryRow(context.Background(), q, id).Scan(&captchaValue)
if err != nil {
if err.Error() == "no rows in result set" {
log.Println("Captcha ID not found:", err)
} else {
log.Println("Error retrieving captcha from database:", err)
}
return
}
// log.Println("captchaValue: ", captchaValue)
digits = captchaValue
if clear {
q = `DELETE FROM captchas WHERE captcha_id = $1`
_, err = s.db.Exec(context.Background(), q, id)
if err != nil {
log.Println("Error deleting captcha from database:", err)
}
}
return
}
// Verify verifies whether the given captcha ID and solution are correct.
func (s *PostgreSQLStore) Verify(id, solution string, clear bool) bool {
if stored := s.Get(id, clear); stored != nil {
return captcha.VerifyString(id, solution)
}
return false
}
// Cleanup can be implemented to clean up expired captchas if necessary.
func (s *PostgreSQLStore) Cleanup() {
// Implement cleanup logic if needed
}