| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- package auth
- import (
- "context"
- "database/sql"
- "errors"
- "fmt"
- "time"
- )
- // 授信设备管理(api.md 第四节 / auth.md 第四节)。
- //
- // 不提供创建设备接口:授信只能在登录时通过 trust_device=true 在那台
- // 浏览器上创建(api.md 4.2 说明)。
- // ErrTrustedDeviceNotFound 表示设备不存在或不属于当前用户(404)。
- var ErrTrustedDeviceNotFound = errors.New("授信设备不存在")
- // TrustedDeviceSummary 是 GET /api/trusted-devices 的列表项(api.md 4.1)。
- type TrustedDeviceSummary struct {
- ID string `json:"id"`
- DeviceName string `json:"device_name"`
- CreatedAt time.Time `json:"created_at"`
- LastUsedAt time.Time `json:"last_used_at"`
- ExpiresAt time.Time `json:"expires_at"`
- }
- // ListTrustedDevices 返回当前用户的全部授信设备,按最近使用倒序。
- func (s *Service) ListTrustedDevices(ctx context.Context, userID string) ([]TrustedDeviceSummary, error) {
- const q = `
- SELECT id, device_name, created_at, last_used_at, expires_at
- FROM trusted_devices
- WHERE user_id = $1
- ORDER BY last_used_at DESC`
- rows, err := s.db.QueryContext(ctx, q, userID)
- if err != nil {
- return nil, fmt.Errorf("查询授信设备失败: %w", err)
- }
- defer rows.Close()
- out := make([]TrustedDeviceSummary, 0, 4)
- for rows.Next() {
- var item TrustedDeviceSummary
- if err := rows.Scan(&item.ID, &item.DeviceName, &item.CreatedAt, &item.LastUsedAt, &item.ExpiresAt); err != nil {
- return nil, fmt.Errorf("扫描授信设备失败: %w", err)
- }
- out = append(out, item)
- }
- if err := rows.Err(); err != nil {
- return nil, fmt.Errorf("读取授信设备失败: %w", err)
- }
- return out, nil
- }
- // FindTrustedDevice 返回设备的展示名,用于撤销时写审计事件(audit.md 第三节)。
- func (s *Service) FindTrustedDevice(ctx context.Context, userID, deviceID string) (TrustedDeviceSummary, error) {
- const q = `
- SELECT id, device_name, created_at, last_used_at, expires_at
- FROM trusted_devices WHERE id = $1 AND user_id = $2`
- var item TrustedDeviceSummary
- err := s.db.QueryRowContext(ctx, q, deviceID, userID).Scan(
- &item.ID, &item.DeviceName, &item.CreatedAt, &item.LastUsedAt, &item.ExpiresAt)
- if errors.Is(err, sql.ErrNoRows) {
- return TrustedDeviceSummary{}, ErrTrustedDeviceNotFound
- }
- if err != nil {
- return TrustedDeviceSummary{}, fmt.Errorf("查询授信设备失败: %w", err)
- }
- return item, nil
- }
- // RevokeTrustedDevice 撤销即硬删除(api.md 4.2)。
- func (s *Service) RevokeTrustedDevice(ctx context.Context, userID, deviceID string) error {
- const q = `DELETE FROM trusted_devices WHERE id = $1 AND user_id = $2`
- res, err := s.db.ExecContext(ctx, q, deviceID, userID)
- if err != nil {
- return fmt.Errorf("删除授信设备失败: %w", err)
- }
- n, err := res.RowsAffected()
- if err != nil {
- return fmt.Errorf("读取删除结果失败: %w", err)
- }
- if n == 0 {
- return ErrTrustedDeviceNotFound
- }
- return nil
- }
|