Files
TaskPool/internal/services/login_log_service.go
T
2026-03-09 18:10:23 +08:00

113 lines
3.2 KiB
Go

package services
import (
"fmt"
"github.com/engigu/baihu-panel/internal/constant"
"github.com/engigu/baihu-panel/internal/database"
"github.com/engigu/baihu-panel/internal/eventbus"
"github.com/engigu/baihu-panel/internal/models"
"github.com/engigu/baihu-panel/internal/utils"
)
type LoginLogService struct{}
func NewLoginLogService() *LoginLogService {
return &LoginLogService{}
}
// Create 创建登录日志
func (s *LoginLogService) Create(username, ip, userAgent, status, message string) error {
log := &models.LoginLog{
ID: utils.GenerateID(),
Username: username,
IP: ip,
UserAgent: userAgent,
Status: status,
Message: message,
}
return database.DB.Create(log).Error
}
// SubscribeEvents 注册订阅事件
func (s *LoginLogService) SubscribeEvents(bus *eventbus.EventBus) {
// 用户登录事件
bus.Subscribe(constant.EventUserLogin, func(e eventbus.Event) {
payload, ok := e.Payload.(map[string]interface{})
if !ok {
return
}
username, _ := payload["username"].(string)
ip, _ := payload["ip"].(string)
userAgent, _ := payload["userAgent"].(string)
status, _ := payload["status"].(string)
message, _ := payload["message"].(string)
s.Create(username, ip, userAgent, status, message)
// 如果登录成功,触发系统通知
if status == "success" {
bus.Publish(eventbus.Event{
Type: constant.EventSystemNotice,
Payload: map[string]interface{}{
"title": "登录提醒",
"content": fmt.Sprintf("用户 %s 已从 IP %s 登录系统", username, ip),
"level": constant.LogLevelWarning,
},
})
}
})
// 暴力破解防御触发事件
bus.Subscribe(constant.EventBruteForceLogin, func(e eventbus.Event) {
payload, ok := e.Payload.(map[string]interface{})
if !ok {
return
}
username, _ := payload["username"].(string)
ip, _ := payload["ip"].(string)
userAgent, _ := payload["userAgent"].(string)
s.Create(username, ip, userAgent, "failed", "尝试次数过多,由于暴力破解防御机制已锁定")
// 触发系统通知
bus.Publish(eventbus.Event{
Type: constant.EventSystemNotice,
Payload: map[string]interface{}{
"title": "系统安全警告",
"content": fmt.Sprintf("检测到 IP %s 正在尝试暴力破解用户 %s", ip, username),
"level": constant.LogLevelError,
},
})
})
}
// List 获取登录日志列表
func (s *LoginLogService) List(page, pageSize int, username string) ([]models.LoginLog, int64, error) {
var logs []models.LoginLog
var total int64
query := database.DB.Model(&models.LoginLog{})
if username != "" {
query = query.Where("username LIKE ?", "%"+username+"%")
}
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
offset := (page - 1) * pageSize
if err := query.Order("created_at DESC").Offset(offset).Limit(pageSize).Find(&logs).Error; err != nil {
return nil, 0, err
}
return logs, total, nil
}
// CleanOldLogs 清理指定天数前的日志
func (s *LoginLogService) CleanOldLogs(days int) (int64, error) {
result := database.DB.Exec("DELETE FROM "+models.LoginLog{}.TableName()+" WHERE created_at < datetime('now', ?)", "-"+string(rune(days))+" days")
return result.RowsAffected, result.Error
}