feat: Implement Oauth2 login log service and repository
- Added Oauth2LogLoginService for managing user authorization logs. - Implemented methods for inserting logs, cleaning logs, and exporting log data. - Created a new file for Oauth2 login log service. refactor: Remove unused open_api module - Deleted the open_api.go file as it was not utilized in the project. fix: Update error codes in SysProfileController - Changed error codes for binding errors and user authentication errors to more descriptive values. fix: Update cache handling in SysConfig and SysDictType services - Modified Redis set operations to include expiration time for cached values. refactor: Update middleware authorization checks - Replaced PreAuthorize middleware with AuthorizeUser across multiple routes in system and tool modules for consistency. chore: Clean up trace and ws modules - Updated middleware authorization in trace and ws modules to use AuthorizeUser.
This commit is contained in:
86
src/modules/oauth2/service/oauth2.go
Normal file
86
src/modules/oauth2/service/oauth2.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/database/redis"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/framework/utils/crypto"
|
||||
"be.ems/src/framework/utils/generate"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/oauth2/repository"
|
||||
)
|
||||
|
||||
// NewOauth2Service 实例化服务层
|
||||
var NewOauth2Service = &Oauth2Service{
|
||||
oauth2ClientRepository: repository.NewOauth2Client,
|
||||
}
|
||||
|
||||
// Oauth2Service 用户授权第三方应用信息 服务层处理
|
||||
type Oauth2Service struct {
|
||||
oauth2ClientRepository *repository.Oauth2Client // 用户授权第三方应用表
|
||||
}
|
||||
|
||||
// CreateCode 创建授权码
|
||||
func (s Oauth2Service) CreateCode() string {
|
||||
code := generate.Code(8)
|
||||
uuid := crypto.MD5(code)
|
||||
verifyKey := constants.CACHE_OAUTH2_CODE + ":" + uuid
|
||||
// 授权码有效期,单位秒
|
||||
codeExpiration := 2 * 60 * time.Second
|
||||
_ = redis.Set("", verifyKey, code, codeExpiration)
|
||||
return code
|
||||
}
|
||||
|
||||
// ValidateCode 校验授权码
|
||||
func (s Oauth2Service) ValidateCode(code string) error {
|
||||
if len(code) > 16 {
|
||||
return fmt.Errorf("code length error")
|
||||
}
|
||||
uuid := crypto.MD5(code)
|
||||
verifyKey := constants.CACHE_OAUTH2_CODE + ":" + uuid
|
||||
captcha, _ := redis.Get("", verifyKey)
|
||||
if captcha == "" {
|
||||
return fmt.Errorf("code expire")
|
||||
}
|
||||
_ = redis.Del("", verifyKey)
|
||||
if captcha != strings.ToLower(code) {
|
||||
return fmt.Errorf("code error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ByClient 客户端信息
|
||||
func (s Oauth2Service) ByClient(clientId, clientSecret string) (token.Oauth2Info, error) {
|
||||
info := token.Oauth2Info{}
|
||||
|
||||
// 查询用户登录账号
|
||||
var item model.Oauth2Client
|
||||
rows := s.oauth2ClientRepository.Select(model.Oauth2Client{
|
||||
ClientId: clientId,
|
||||
ClientSecret: clientSecret,
|
||||
})
|
||||
if len(rows) > 0 {
|
||||
item = rows[0]
|
||||
}
|
||||
if item.ClientId == "" {
|
||||
return info, fmt.Errorf("clientId or clientSecret is not exist")
|
||||
}
|
||||
|
||||
info.ClientId = clientId
|
||||
// 用户权限组标识
|
||||
info.Scope = []string{}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// UpdateLoginDateAndIP 更新登录时间和IP
|
||||
func (s Oauth2Service) UpdateLoginDateAndIP(info token.Oauth2Info) bool {
|
||||
item := s.oauth2ClientRepository.SelectByClientId(info.ClientId)
|
||||
item.LoginIp = info.LoginIp
|
||||
item.LoginTime = info.LoginTime
|
||||
rows := s.oauth2ClientRepository.Update(item)
|
||||
return rows > 0
|
||||
}
|
||||
65
src/modules/oauth2/service/oauth2_client.go
Normal file
65
src/modules/oauth2/service/oauth2_client.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/utils/generate"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/oauth2/repository"
|
||||
)
|
||||
|
||||
// NewOauth2ClientService 实例化服务层
|
||||
var NewOauth2ClientService = &Oauth2ClientService{
|
||||
oauth2ClientRepository: repository.NewOauth2Client,
|
||||
}
|
||||
|
||||
// Oauth2ClientService 用户授权第三方应用信息 服务层处理
|
||||
type Oauth2ClientService struct {
|
||||
oauth2ClientRepository *repository.Oauth2Client // 用户授权第三方应用表
|
||||
}
|
||||
|
||||
// FindByPage 分页查询
|
||||
func (s Oauth2ClientService) FindByPage(query map[string]string) ([]model.Oauth2Client, int64) {
|
||||
return s.oauth2ClientRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// FindById 查询ID
|
||||
func (s Oauth2ClientService) FindById(id int64) model.Oauth2Client {
|
||||
rows := s.oauth2ClientRepository.SelectByIds([]int64{id})
|
||||
if len(rows) > 0 {
|
||||
return rows[0]
|
||||
}
|
||||
return model.Oauth2Client{}
|
||||
}
|
||||
|
||||
// FindByClientId 查询ClientId
|
||||
func (s Oauth2ClientService) FindByClientId(clientId string) model.Oauth2Client {
|
||||
return s.oauth2ClientRepository.SelectByClientId(clientId)
|
||||
}
|
||||
|
||||
// Insert 新增
|
||||
func (s Oauth2ClientService) Insert(param model.Oauth2Client) int64 {
|
||||
param.ClientId = generate.Code(16)
|
||||
param.ClientSecret = generate.Code(32)
|
||||
return s.oauth2ClientRepository.Insert(param)
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (s Oauth2ClientService) Update(param model.Oauth2Client) int64 {
|
||||
return s.oauth2ClientRepository.Update(param)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除
|
||||
func (s Oauth2ClientService) DeleteByIds(ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
arr := s.oauth2ClientRepository.SelectByIds(ids)
|
||||
if len(arr) <= 0 {
|
||||
// return 0, fmt.Errorf("没有权限访问用户授权第三方应用数据!")
|
||||
return 0, fmt.Errorf("No permission to access user-authorized third-party application data!")
|
||||
}
|
||||
if len(arr) == len(ids) {
|
||||
return s.oauth2ClientRepository.DeleteByIds(ids), nil
|
||||
}
|
||||
// return 0, fmt.Errorf("删除用户授权第三方应用信息失败!")
|
||||
return 0, fmt.Errorf("Failed to delete user-authorized third-party application information!")
|
||||
}
|
||||
85
src/modules/oauth2/service/oauth2_log_login.go
Normal file
85
src/modules/oauth2/service/oauth2_log_login.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/oauth2/repository"
|
||||
)
|
||||
|
||||
// NewOauth2LogLogin 实例化服务层
|
||||
var NewOauth2LogLogin = &Oauth2LogLoginService{
|
||||
oauth2LogLoginRepository: repository.NewOauth2LogLogin,
|
||||
}
|
||||
|
||||
// Oauth2LogLogin 用户授权第三方应用登录日志 服务层处理
|
||||
type Oauth2LogLoginService struct {
|
||||
oauth2LogLoginRepository *repository.Oauth2LogLoginRepository // 用户授权第三方应用登录日志信息
|
||||
}
|
||||
|
||||
// FindByPage 分页查询列表数据
|
||||
func (s Oauth2LogLoginService) FindByPage(query map[string]string) ([]model.Oauth2LogLogin, int64) {
|
||||
return s.oauth2LogLoginRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// Insert 新增信息
|
||||
func (s Oauth2LogLoginService) Insert(clientId, status, msg string, ilobArr [4]string) int64 {
|
||||
sysOauth2LogLogin := model.Oauth2LogLogin{
|
||||
LoginIp: ilobArr[0],
|
||||
LoginLocation: ilobArr[1],
|
||||
OS: ilobArr[2],
|
||||
Browser: ilobArr[3],
|
||||
ClientId: clientId,
|
||||
StatusFlag: status,
|
||||
Msg: msg,
|
||||
}
|
||||
return s.oauth2LogLoginRepository.Insert(sysOauth2LogLogin)
|
||||
}
|
||||
|
||||
// Clean 清空用户授权第三方应用登录日志
|
||||
func (s Oauth2LogLoginService) Clean() int64 {
|
||||
return s.oauth2LogLoginRepository.Clean()
|
||||
}
|
||||
|
||||
// ExportData 导出数据表格
|
||||
func (s Oauth2LogLoginService) ExportData(rows []model.Oauth2LogLogin, fileName string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "序号",
|
||||
"B1": "应用的唯一标识",
|
||||
"C1": "登录状态",
|
||||
"D1": "登录地址",
|
||||
"E1": "登录地点",
|
||||
"F1": "浏览器",
|
||||
"G1": "操作系统",
|
||||
"H1": "提示消息",
|
||||
"I1": "访问时间",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 状态
|
||||
statusValue := "失败"
|
||||
if row.StatusFlag == constants.STATUS_YES {
|
||||
statusValue = "成功"
|
||||
}
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.ClientId,
|
||||
"C" + idx: statusValue,
|
||||
"D" + idx: row.LoginIp,
|
||||
"E" + idx: row.LoginLocation,
|
||||
"F" + idx: row.Browser,
|
||||
"G" + idx: row.OS,
|
||||
"H" + idx: row.Msg,
|
||||
"I" + idx: date.ParseDateToStr(row.LoginTime, date.YYYY_MM_DD_HH_MM_SS),
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
Reference in New Issue
Block a user