82 lines
2.7 KiB
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
|
|
}
|