任务执行1-19
This commit is contained in:
207
internal/logic/audit/controller.go
Normal file
207
internal/logic/audit/controller.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/ops/logs/internal/impl"
|
||||
"git.apinb.com/ops/logs/internal/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ListAuditLogs(ctx *gin.Context) {
|
||||
page, size := pageAndSize(ctx.DefaultQuery("page", "1"), ctx.DefaultQuery("page_size", "50"))
|
||||
q := impl.DBService.Model(&models.AuditLog{})
|
||||
if v := strings.TrimSpace(ctx.Query("source_service")); v != "" {
|
||||
q = q.Where("source_service = ?", v)
|
||||
}
|
||||
if v := strings.TrimSpace(ctx.Query("actor_id")); v != "" {
|
||||
q = q.Where("actor_id = ?", v)
|
||||
}
|
||||
if v := strings.TrimSpace(ctx.Query("action")); v != "" {
|
||||
q = q.Where("action = ?", v)
|
||||
}
|
||||
if v := strings.TrimSpace(ctx.Query("object_type")); v != "" {
|
||||
q = q.Where("object_type = ?", v)
|
||||
}
|
||||
if v := strings.TrimSpace(ctx.Query("object_id")); v != "" {
|
||||
q = q.Where("object_id = ?", v)
|
||||
}
|
||||
if v := strings.TrimSpace(ctx.Query("operation_risk")); v != "" {
|
||||
q = q.Where("operation_risk = ?", v)
|
||||
}
|
||||
if v := strings.TrimSpace(ctx.Query("result")); v != "" {
|
||||
q = q.Where("result = ?", v)
|
||||
}
|
||||
var total int64
|
||||
_ = q.Count(&total).Error
|
||||
var rows []models.AuditLog
|
||||
if err := q.Order("id desc").Offset((page - 1) * size).Limit(size).Find(&rows).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(ctx, gin.H{"total": total, "page": page, "page_size": size, "items": rows})
|
||||
}
|
||||
|
||||
func CreateAuditLog(ctx *gin.Context) {
|
||||
var req Record
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
req.ClientIP = firstNonEmpty(req.ClientIP, ctx.ClientIP())
|
||||
req.RequestMethod = firstNonEmpty(req.RequestMethod, ctx.Request.Method)
|
||||
req.RequestPath = firstNonEmpty(req.RequestPath, ctx.FullPath())
|
||||
row, err := SaveRecord(req)
|
||||
if err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(ctx, row)
|
||||
}
|
||||
|
||||
func ListApprovals(ctx *gin.Context) {
|
||||
page, size := pageAndSize(ctx.DefaultQuery("page", "1"), ctx.DefaultQuery("page_size", "50"))
|
||||
q := impl.DBService.Model(&models.DangerousOperationApproval{})
|
||||
if v := strings.TrimSpace(ctx.Query("source_service")); v != "" {
|
||||
q = q.Where("source_service = ?", v)
|
||||
}
|
||||
if v := strings.TrimSpace(ctx.Query("status")); v != "" {
|
||||
q = q.Where("status = ?", v)
|
||||
}
|
||||
if v := strings.TrimSpace(ctx.Query("requester_id")); v != "" {
|
||||
q = q.Where("requester_id = ?", v)
|
||||
}
|
||||
if v := strings.TrimSpace(ctx.Query("object_type")); v != "" {
|
||||
q = q.Where("object_type = ?", v)
|
||||
}
|
||||
var total int64
|
||||
_ = q.Count(&total).Error
|
||||
var rows []models.DangerousOperationApproval
|
||||
if err := q.Order("id desc").Offset((page - 1) * size).Limit(size).Find(&rows).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(ctx, gin.H{"total": total, "page": page, "page_size": size, "items": rows})
|
||||
}
|
||||
|
||||
func CreateApproval(ctx *gin.Context) {
|
||||
var req ApprovalRequest
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
req = NormalizeApproval(req)
|
||||
if req.RequestID == "" {
|
||||
req.RequestID = fmt.Sprintf("apr-%d", time.Now().UnixNano())
|
||||
}
|
||||
if err := ValidateApprovalRequest(req); err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
row := models.DangerousOperationApproval{
|
||||
RequestID: req.RequestID,
|
||||
SourceService: req.SourceService,
|
||||
Action: req.Action,
|
||||
ObjectType: req.ObjectType,
|
||||
ObjectID: req.ObjectID,
|
||||
RequesterID: req.RequesterID,
|
||||
RequesterName: req.RequesterName,
|
||||
Reason: req.Reason,
|
||||
BeforeJSON: req.BeforeJSON,
|
||||
AfterJSON: req.AfterJSON,
|
||||
Status: ApprovalPending,
|
||||
}
|
||||
if err := impl.DBService.Create(&row).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(ctx, row)
|
||||
}
|
||||
|
||||
func ApproveApproval(ctx *gin.Context) {
|
||||
reviewApproval(ctx, ApprovalApproved)
|
||||
}
|
||||
|
||||
func RejectApproval(ctx *gin.Context) {
|
||||
reviewApproval(ctx, ApprovalRejected)
|
||||
}
|
||||
|
||||
func reviewApproval(ctx *gin.Context, next string) {
|
||||
id, err := parseUintParam(ctx, "id")
|
||||
if err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
var body struct {
|
||||
ReviewerID string `json:"reviewer_id"`
|
||||
ReviewerName string `json:"reviewer_name"`
|
||||
ReviewComment string `json:"review_comment"`
|
||||
}
|
||||
if err := ctx.ShouldBindJSON(&body); err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
var row models.DangerousOperationApproval
|
||||
if err := impl.DBService.First(&row, id).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
req := ApprovalRequest{
|
||||
RequestID: row.RequestID,
|
||||
SourceService: row.SourceService,
|
||||
Action: row.Action,
|
||||
ObjectType: row.ObjectType,
|
||||
ObjectID: row.ObjectID,
|
||||
RequesterID: row.RequesterID,
|
||||
Status: row.Status,
|
||||
}
|
||||
nextReq, err := Transition(req, next, body.ReviewerID, body.ReviewComment)
|
||||
if err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
row.Status = nextReq.Status
|
||||
row.ReviewerID = nextReq.ReviewerID
|
||||
row.ReviewerName = strings.TrimSpace(body.ReviewerName)
|
||||
row.ReviewComment = nextReq.ReviewComment
|
||||
row.ReviewedAt = nextReq.ReviewedAt
|
||||
if err := impl.DBService.Save(&row).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(ctx, row)
|
||||
}
|
||||
|
||||
func parseUintParam(ctx *gin.Context, name string) (uint, error) {
|
||||
v, err := strconv.ParseUint(ctx.Param(name), 10, 32)
|
||||
if err != nil || v == 0 {
|
||||
return 0, errors.New("invalid id")
|
||||
}
|
||||
return uint(v), nil
|
||||
}
|
||||
|
||||
func pageAndSize(pageText, sizeText string) (int, int) {
|
||||
page, _ := strconv.Atoi(pageText)
|
||||
size, _ := strconv.Atoi(sizeText)
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if size < 1 || size > 500 {
|
||||
size = 50
|
||||
}
|
||||
return page, size
|
||||
}
|
||||
|
||||
func firstNonEmpty(values ...string) string {
|
||||
for _, value := range values {
|
||||
if strings.TrimSpace(value) != "" {
|
||||
return strings.TrimSpace(value)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user