From 92bc8bdbcfb0e9727a0341ab6b7b1195f6e2ca7d Mon Sep 17 00:00:00 2001 From: "taekyu.kang" Date: Thu, 25 Apr 2024 13:49:18 +0900 Subject: [PATCH] feature. change audit scheme and remove database constraint --- api/swagger/docs.go | 42 +++++-------------- api/swagger/swagger.json | 42 +++++-------------- api/swagger/swagger.yaml | 29 ++++--------- internal/delivery/http/audit.go | 6 --- internal/middleware/audit/audit.go | 25 +++++++++-- internal/model/audit.go | 6 ++- internal/model/user.go | 3 +- internal/repository/audit.go | 12 +++--- .../repository/system-notification-rule.go | 4 -- internal/usecase/audit.go | 31 +++++++++++--- pkg/domain/audit.go | 22 +++++----- 11 files changed, 102 insertions(+), 120 deletions(-) diff --git a/api/swagger/docs.go b/api/swagger/docs.go index 95641852..a785a78d 100644 --- a/api/swagger/docs.go +++ b/api/swagger/docs.go @@ -10974,17 +10974,23 @@ const docTemplate = `{ "message": { "type": "string" }, - "organization": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleOrganizationResponse" - }, "organizationId": { "type": "string" }, "updatedAt": { "type": "string" }, - "user": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponseWithRoles" + "userAccountId": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "userName": { + "type": "string" + }, + "userRoles": { + "type": "string" } } }, @@ -14849,32 +14855,6 @@ const docTemplate = `{ } } }, - "github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponseWithRoles": { - "type": "object", - "properties": { - "accountId": { - "type": "string" - }, - "department": { - "type": "string" - }, - "email": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleRoleResponse" - } - } - } - }, "github_com_openinfradev_tks-api_pkg_domain.StackConfResponse": { "type": "object", "required": [ diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index 77d95ec3..8e3be501 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -10968,17 +10968,23 @@ "message": { "type": "string" }, - "organization": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleOrganizationResponse" - }, "organizationId": { "type": "string" }, "updatedAt": { "type": "string" }, - "user": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponseWithRoles" + "userAccountId": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "userName": { + "type": "string" + }, + "userRoles": { + "type": "string" } } }, @@ -14843,32 +14849,6 @@ } } }, - "github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponseWithRoles": { - "type": "object", - "properties": { - "accountId": { - "type": "string" - }, - "department": { - "type": "string" - }, - "email": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleRoleResponse" - } - } - } - }, "github_com_openinfradev_tks-api_pkg_domain.StackConfResponse": { "type": "object", "required": [ diff --git a/api/swagger/swagger.yaml b/api/swagger/swagger.yaml index 37c5bb82..94b618be 100644 --- a/api/swagger/swagger.yaml +++ b/api/swagger/swagger.yaml @@ -500,14 +500,18 @@ definitions: type: string message: type: string - organization: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleOrganizationResponse' organizationId: type: string updatedAt: type: string - user: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponseWithRoles' + userAccountId: + type: string + userId: + type: string + userName: + type: string + userRoles: + type: string type: object github_com_openinfradev_tks-api_pkg_domain.Axis: properties: @@ -3072,23 +3076,6 @@ definitions: name: type: string type: object - github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponseWithRoles: - properties: - accountId: - type: string - department: - type: string - email: - type: string - id: - type: string - name: - type: string - roles: - items: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleRoleResponse' - type: array - type: object github_com_openinfradev_tks-api_pkg_domain.StackConfResponse: properties: tksCpNode: diff --git a/internal/delivery/http/audit.go b/internal/delivery/http/audit.go index 58fda3fb..520521c1 100644 --- a/internal/delivery/http/audit.go +++ b/internal/delivery/http/audit.go @@ -71,12 +71,6 @@ func (h *AuditHandler) GetAudits(w http.ResponseWriter, r *http.Request) { if err := serializer.Map(r.Context(), audit, &out.Audits[i]); err != nil { log.Info(r.Context(), err) } - out.Audits[i].User.Roles = make([]domain.SimpleRoleResponse, len(audit.User.Roles)) - for j, role := range audit.User.Roles { - if err := serializer.Map(r.Context(), role, &out.Audits[i].User.Roles[j]); err != nil { - log.Info(r.Context(), err) - } - } } if out.Pagination, err = pg.Response(r.Context()); err != nil { diff --git a/internal/middleware/audit/audit.go b/internal/middleware/audit/audit.go index c8e30c7f..f3d81d7e 100644 --- a/internal/middleware/audit/audit.go +++ b/internal/middleware/audit/audit.go @@ -20,12 +20,14 @@ type Interface interface { } type defaultAudit struct { - repo repository.IAuditRepository + repo repository.IAuditRepository + userRepo repository.IUserRepository } func NewDefaultAudit(repo repository.Repository) *defaultAudit { return &defaultAudit{ - repo: repo.Audit, + repo: repo.Audit, + userRepo: repo.User, } } @@ -59,13 +61,30 @@ func (a *defaultAudit) WithAudit(endpoint internalApi.Endpoint, handler http.Han message, description = fn(r.Context(), lrw.GetBody().Bytes(), body, statusCode) r.Body = io.NopCloser(bytes.NewBuffer(body)) + u, err := a.userRepo.GetByUuid(r.Context(), userId) + if err != nil { + log.Error(r.Context(), err) + return + } + + userRoles := "" + for i, role := range u.Roles { + if i > 0 { + userRoles = userRoles + "," + } + userRoles = userRoles + role.Name + } + dto := model.Audit{ OrganizationId: organizationId, Group: internalApi.ApiMap[endpoint].Group, Message: message, Description: description, ClientIP: GetClientIpAddress(w, r), - UserId: &userId, + UserId: &u.ID, + UserAccountId: u.AccountId, + UserName: u.Name, + UserRoles: userRoles, } if _, err := a.repo.Create(r.Context(), dto); err != nil { log.Error(r.Context(), err) diff --git a/internal/model/audit.go b/internal/model/audit.go index 1f39c252..0059d02c 100644 --- a/internal/model/audit.go +++ b/internal/model/audit.go @@ -11,11 +11,13 @@ type Audit struct { ID uuid.UUID `gorm:"primarykey"` OrganizationId string - Organization Organization `gorm:"foreignKey:OrganizationId"` + Organization Organization Group string Message string Description string ClientIP string UserId *uuid.UUID `gorm:"type:uuid"` - User User `gorm:"foreignKey:UserId"` + UserAccountId string + UserName string + UserRoles string } diff --git a/internal/model/user.go b/internal/model/user.go index a6b34a82..dfaa0db7 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -1,9 +1,10 @@ package model import ( - "gorm.io/gorm" "time" + "gorm.io/gorm" + "github.com/google/uuid" ) diff --git a/internal/repository/audit.go b/internal/repository/audit.go index b62cda44..7988e396 100644 --- a/internal/repository/audit.go +++ b/internal/repository/audit.go @@ -6,7 +6,6 @@ import ( "github.com/google/uuid" "gorm.io/gorm" - "gorm.io/gorm/clause" "github.com/openinfradev/tks-api/internal/model" "github.com/openinfradev/tks-api/internal/pagination" @@ -32,7 +31,7 @@ func NewAuditRepository(db *gorm.DB) IAuditRepository { // Logics func (r *AuditRepository) Get(ctx context.Context, auditId uuid.UUID) (out model.Audit, err error) { - res := r.db.WithContext(ctx).Preload(clause.Associations).Preload("User.Roles").First(&out, "id = ?", auditId) + res := r.db.WithContext(ctx).First(&out, "id = ?", auditId) if res.Error != nil { return } @@ -44,8 +43,7 @@ func (r *AuditRepository) Fetch(ctx context.Context, pg *pagination.Pagination) pg = pagination.NewPagination(nil) } - db := r.db.WithContext(ctx).Model(&model.Audit{}).Preload(clause.Associations). - Preload("User.Roles") + db := r.db.WithContext(ctx).Model(&model.Audit{}) _, res := pg.Fetch(db, &out) if res.Error != nil { @@ -62,7 +60,11 @@ func (r *AuditRepository) Create(ctx context.Context, dto model.Audit) (auditId Message: dto.Message, Description: dto.Description, ClientIP: dto.ClientIP, - UserId: dto.UserId} + UserId: &dto.ID, + UserAccountId: dto.UserAccountId, + UserName: dto.UserName, + UserRoles: dto.UserRoles, + } res := r.db.WithContext(ctx).Create(&audit) if res.Error != nil { return uuid.Nil, res.Error diff --git a/internal/repository/system-notification-rule.go b/internal/repository/system-notification-rule.go index 7edb3a8e..21ccbf99 100644 --- a/internal/repository/system-notification-rule.go +++ b/internal/repository/system-notification-rule.go @@ -10,7 +10,6 @@ import ( "github.com/openinfradev/tks-api/internal/model" "github.com/openinfradev/tks-api/internal/pagination" "github.com/openinfradev/tks-api/pkg/domain" - "github.com/openinfradev/tks-api/pkg/log" ) // Interfaces @@ -125,9 +124,6 @@ func (r *SystemNotificationRuleRepository) Update(ctx context.Context, dto model m.MessageActionProposal = dto.MessageActionProposal m.UpdatorId = dto.UpdatorId - log.Info(ctx, "KTKFREE1 ", m.SystemNotificationCondition.EnableEmail) - log.Info(ctx, "KTKFREE2 ", m.SystemNotificationCondition.EnablePortal) - res = r.db.WithContext(ctx).Session(&gorm.Session{FullSaveAssociations: true}).Save(&m) if res.Error != nil { return res.Error diff --git a/internal/usecase/audit.go b/internal/usecase/audit.go index 9a0f06cc..09b09ee0 100644 --- a/internal/usecase/audit.go +++ b/internal/usecase/audit.go @@ -19,23 +19,42 @@ type IAuditUsecase interface { } type AuditUsecase struct { - repo repository.IAuditRepository + repo repository.IAuditRepository + userRepo repository.IUserRepository } func NewAuditUsecase(r repository.Repository) IAuditUsecase { return &AuditUsecase{ - repo: r.Audit, + repo: r.Audit, + userRepo: r.User, } } func (u *AuditUsecase) Create(ctx context.Context, dto model.Audit) (auditId uuid.UUID, err error) { - if dto.UserId == nil { - user, ok := request.UserFrom(ctx) + if dto.UserId == nil || *dto.UserId == uuid.Nil { + userInfo, ok := request.UserFrom(ctx) if ok { - userId := user.GetUserId() - dto.UserId = &userId + id := userInfo.GetUserId() + dto.UserId = &id } } + + user, err := u.userRepo.GetByUuid(ctx, *dto.UserId) + if err != nil { + return auditId, err + } + + userRoles := "" + for i, role := range user.Roles { + if i > 0 { + userRoles = userRoles + "," + } + userRoles = userRoles + role.Name + } + dto.UserAccountId = user.AccountId + dto.UserName = user.Name + dto.UserRoles = userRoles + auditId, err = u.repo.Create(ctx, dto) if err != nil { return uuid.Nil, httpErrors.NewInternalServerError(err, "", "") diff --git a/pkg/domain/audit.go b/pkg/domain/audit.go index 2353b2bb..feca68e7 100644 --- a/pkg/domain/audit.go +++ b/pkg/domain/audit.go @@ -5,16 +5,18 @@ import ( ) type AuditResponse struct { - ID string `json:"id"` - OrganizationId string `json:"organizationId"` - Organization SimpleOrganizationResponse `json:"organization"` - Description string `json:"description"` - Group string `json:"group"` - Message string `json:"message"` - ClientIP string `json:"clientIP"` - User SimpleUserResponseWithRoles `json:"user"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID string `json:"id"` + OrganizationId string `json:"organizationId"` + Description string `json:"description"` + Group string `json:"group"` + Message string `json:"message"` + ClientIP string `json:"clientIP"` + UserId string `json:"userId"` + UserAccountId string `json:"userAccountId"` + UserName string `json:"userName"` + UserRoles string `json:"userRoles"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` } type CreateAuditRequest struct {