Files
codit/backend/internal/db/user_totp.go

82 lines
2.7 KiB
Go

package db
import "database/sql"
import "time"
type UserTOTP struct {
SecretEncrypted string
PendingSecretEncrypted string
Enabled bool
CreatedAt int64
UpdatedAt int64
}
func (s *Store) GetUserTOTP(userID string) (UserTOTP, error) {
var item UserTOTP
var row *sql.Row
var created time.Time
var updated time.Time
var err error
row = s.QueryRow(`
SELECT COALESCE(t.secret_encrypted, ''), COALESCE(t.pending_secret_encrypted, ''), COALESCE(t.enabled, 0), t.created_at, t.updated_at
FROM user_totp t JOIN users u ON u.id = t.user_id
WHERE u.public_id = ?
`, userID)
err = row.Scan(&item.SecretEncrypted, &item.PendingSecretEncrypted, &item.Enabled, &created, &updated)
if err != nil {
return item, err
}
item.CreatedAt = created.Unix()
item.UpdatedAt = updated.Unix()
return item, nil
}
func (s *Store) UserRequiresTOTP(userID string) (bool, error) {
var row *sql.Row
var required bool
var err error
row = s.QueryRow(`
SELECT (u.totp_required OR EXISTS (
SELECT 1 FROM user_group_members m JOIN user_groups g ON g.id = m.group_id
WHERE m.user_id = u.id AND g.disabled = 0 AND g.totp_required = 1
) OR EXISTS (
SELECT 1 FROM user_groups g
WHERE g.disabled = 0 AND g.totp_required = 1 AND g.scope = 'all_users'
))
FROM users u
WHERE u.public_id = ? AND u.disabled = 0
`, userID)
err = row.Scan(&required)
return required, err
}
func (s *Store) UpsertUserTOTPPending(userID string, pendingSecretEncrypted string) error {
var err error
var now time.Time
now = time.Now().UTC()
_, err = s.Exec(`
INSERT INTO user_totp (user_id, secret_encrypted, pending_secret_encrypted, enabled, created_at, updated_at)
VALUES ((SELECT id FROM users WHERE public_id = ?), '', ?, 0, ?, ?)
ON CONFLICT(user_id) DO UPDATE SET pending_secret_encrypted = excluded.pending_secret_encrypted, updated_at = excluded.updated_at
`, userID, pendingSecretEncrypted, now, now)
return err
}
func (s *Store) EnableUserTOTP(userID string, secretEncrypted string) error {
var err error
var now time.Time
now = time.Now().UTC()
_, err = s.Exec(`
INSERT INTO user_totp (user_id, secret_encrypted, pending_secret_encrypted, enabled, created_at, updated_at)
VALUES ((SELECT id FROM users WHERE public_id = ?), ?, '', 1, ?, ?)
ON CONFLICT(user_id) DO UPDATE SET secret_encrypted = excluded.secret_encrypted, pending_secret_encrypted = '', enabled = 1, updated_at = excluded.updated_at
`, userID, secretEncrypted, now, now)
return err
}
func (s *Store) DeleteUserTOTP(userID string) error {
var err error
_, err = s.Exec(`DELETE FROM user_totp WHERE user_id = (SELECT id FROM users WHERE public_id = ?)`, userID)
return err
}