72 lines
1.5 KiB
Go
72 lines
1.5 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"strings"
|
|
|
|
"github.com/rede5/gohorsejobs/backend/internal/models"
|
|
)
|
|
|
|
type AuditService struct {
|
|
DB *sql.DB
|
|
}
|
|
|
|
func NewAuditService(db *sql.DB) *AuditService {
|
|
return &AuditService{DB: db}
|
|
}
|
|
|
|
type LoginAuditInput struct {
|
|
UserID string
|
|
Identifier string
|
|
Roles []string
|
|
IPAddress *string
|
|
UserAgent *string
|
|
}
|
|
|
|
func (s *AuditService) RecordLogin(ctx context.Context, input LoginAuditInput) error {
|
|
roles := strings.Join(input.Roles, ",")
|
|
query := `
|
|
INSERT INTO login_audit (user_id, identifier, roles, ip_address, user_agent)
|
|
VALUES ($1, $2, $3, $4, $5)
|
|
`
|
|
_, err := s.DB.ExecContext(ctx, query, input.UserID, input.Identifier, roles, input.IPAddress, input.UserAgent)
|
|
return err
|
|
}
|
|
|
|
func (s *AuditService) ListLogins(ctx context.Context, limit int) ([]models.LoginAudit, error) {
|
|
if limit <= 0 {
|
|
limit = 50
|
|
}
|
|
|
|
query := `
|
|
SELECT id, user_id, identifier, roles, ip_address, user_agent, created_at
|
|
FROM login_audit
|
|
ORDER BY created_at DESC
|
|
LIMIT $1
|
|
`
|
|
rows, err := s.DB.QueryContext(ctx, query, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var audits []models.LoginAudit
|
|
for rows.Next() {
|
|
var entry models.LoginAudit
|
|
if err := rows.Scan(
|
|
&entry.ID,
|
|
&entry.UserID,
|
|
&entry.Identifier,
|
|
&entry.Roles,
|
|
&entry.IPAddress,
|
|
&entry.UserAgent,
|
|
&entry.CreatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
audits = append(audits, entry)
|
|
}
|
|
|
|
return audits, nil
|
|
}
|