Skip to content

Commit

Permalink
feature. implementation audit
Browse files Browse the repository at this point in the history
  • Loading branch information
ktkfree committed Feb 8, 2024
1 parent ff35f44 commit a7095c3
Show file tree
Hide file tree
Showing 14 changed files with 287 additions and 76 deletions.
5 changes: 5 additions & 0 deletions internal/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,10 @@ func migrateSchema(db *gorm.DB) error {
return err
}

// Alert
if err := db.AutoMigrate(&repository.Alert{}); err != nil {
return err
}

return nil
}
9 changes: 0 additions & 9 deletions internal/delivery/http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package http
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"

ut "github.com/go-playground/universal-translator"
validator_ "github.com/go-playground/validator/v10"
"github.com/openinfradev/tks-api/internal/helper"
"github.com/openinfradev/tks-api/internal/validator"
"github.com/openinfradev/tks-api/pkg/httpErrors"
"github.com/openinfradev/tks-api/pkg/log"
Expand Down Expand Up @@ -41,13 +39,6 @@ func ResponseJSON(w http.ResponseWriter, r *http.Request, httpStatus int, data i
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(httpStatus)

responseStr := helper.ModelToJson(out)
if len(responseStr) > MAX_LOG_LEN {
log.InfoWithContext(r.Context(), fmt.Sprintf("[API_RESPONSE] [%s]", responseStr[:MAX_LOG_LEN-1]))
} else {
log.InfoWithContext(r.Context(), fmt.Sprintf("[API_RESPONSE] [%s]", responseStr))
}
log.DebugWithContext(r.Context(), fmt.Sprintf("[API_RESPONSE] [%s]", responseStr))
if err := json.NewEncoder(w).Encode(out); err != nil {
log.ErrorWithContext(r.Context(), err)
}
Expand Down
4 changes: 0 additions & 4 deletions internal/filter/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"strings"
"time"

"github.com/openinfradev/tks-api/pkg/log"
"gorm.io/gorm/schema"
"goyave.dev/goyave/v4/util/sliceutil"
)
Expand Down Expand Up @@ -156,9 +155,6 @@ func getDataType(field *schema.Field) DataType {
}

func ConvertToSafeType(arg string, dataType DataType) (interface{}, bool) {
log.Info(arg)
log.Info(dataType)

switch dataType {
case DataTypeText, DataTypeTextArray, DataTypeEnum, DataTypeEnumArray:
return arg, true
Expand Down
47 changes: 39 additions & 8 deletions internal/middleware/audit/audit.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,60 @@
package audit

import (
"github.com/openinfradev/tks-api/internal/repository"
"fmt"
"net"
"net/http"

internalApi "github.com/openinfradev/tks-api/internal/delivery/api"
"github.com/openinfradev/tks-api/internal/middleware/logging"
"github.com/openinfradev/tks-api/internal/repository"
"github.com/openinfradev/tks-api/pkg/log"
)

type Interface interface {
WithAudit(handler http.Handler) http.Handler
WithAudit(endpoint internalApi.Endpoint, handler http.Handler) http.Handler
}

type defaultAudit struct {
repo repository.Repository
repo repository.IAuditRepository
}

func NewDefaultAudit(repo repository.Repository) *defaultAudit {
return &defaultAudit{
repo: repo,
repo: repo.Audit,
}
}

// TODO: implement audit logic
func (a *defaultAudit) WithAudit(handler http.Handler) http.Handler {
func (a *defaultAudit) WithAudit(endpoint internalApi.Endpoint, handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// TODO: implement audit logic
ctx := r.Context()

log.InfoWithContext(ctx, endpoint)

GetIpAddress(w, r)

lrw := logging.NewLoggingResponseWriter(w)
handler.ServeHTTP(lrw, r)

handler.ServeHTTP(w, r)
statusCode := lrw.GetStatusCode()

log.Infof("%v", endpoint)
log.Infof("%v", internalApi.CreateStack)

// check & matching
if statusCode >= 200 && statusCode < 300 {
if endpoint == internalApi.CreateStack {
log.Info("스택을 생성하였습니다.")
}
}
})
}

func GetIpAddress(w http.ResponseWriter, r *http.Request) {
clientAddr, _, err := net.SplitHostPort(r.RemoteAddr)
log.Info(err)
log.Info(clientAddr)

xforward := r.Header.Get("X-Forwarded-For")
fmt.Println("X-Forwarded-For : ", xforward)
}
1 change: 1 addition & 0 deletions internal/middleware/auth/request/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package request

import (
"context"

internalApi "github.com/openinfradev/tks-api/internal/delivery/api"
"github.com/openinfradev/tks-api/internal/middleware/auth/user"
)
Expand Down
35 changes: 35 additions & 0 deletions internal/middleware/logging/logging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package logging

import (
"bytes"
"context"
"fmt"
"io"
"net/http"

"github.com/google/uuid"
"github.com/openinfradev/tks-api/internal"
"github.com/openinfradev/tks-api/pkg/log"
)

func LoggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
r = r.WithContext(context.WithValue(ctx, internal.ContextKeyRequestID, uuid.New().String()))

log.InfoWithContext(r.Context(), fmt.Sprintf("***** START [%s %s] ***** ", r.Method, r.RequestURI))

body, err := io.ReadAll(r.Body)
if err == nil {
log.InfoWithContext(r.Context(), fmt.Sprintf("REQUEST BODY : %s", bytes.NewBuffer(body).String()))
}
r.Body = io.NopCloser(bytes.NewBuffer(body))
lrw := NewLoggingResponseWriter(w)

next.ServeHTTP(lrw, r)

statusCode := lrw.GetStatusCode()
log.InfofWithContext(r.Context(), "[API_RESPONSE] [%d][%s][%s]", statusCode, http.StatusText(statusCode), lrw.GetBody().String())
log.InfofWithContext(r.Context(), "***** END [%s %s] *****", r.Method, r.RequestURI)
})
}
35 changes: 35 additions & 0 deletions internal/middleware/logging/respose-writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package logging

import (
"bytes"
"net/http"
)

type loggingResponseWriter struct {
http.ResponseWriter
statusCode int
body bytes.Buffer
}

func NewLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter {
var buf bytes.Buffer
return &loggingResponseWriter{w, http.StatusOK, buf}
}

func (lrw *loggingResponseWriter) WriteHeader(code int) {
lrw.statusCode = code
lrw.ResponseWriter.WriteHeader(code)
}

func (lrw *loggingResponseWriter) Write(buf []byte) (int, error) {
lrw.body.Write(buf)
return lrw.ResponseWriter.Write(buf)
}

func (lrw *loggingResponseWriter) GetBody() *bytes.Buffer {
return &lrw.body
}

func (lrw *loggingResponseWriter) GetStatusCode() int {
return lrw.statusCode
}
15 changes: 3 additions & 12 deletions internal/middleware/middleware.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package middleware

import (
"net/http"

internalApi "github.com/openinfradev/tks-api/internal/delivery/api"
"github.com/openinfradev/tks-api/internal/middleware/audit"
"github.com/openinfradev/tks-api/internal/middleware/auth/authenticator"
"github.com/openinfradev/tks-api/internal/middleware/auth/authorizer"
"github.com/openinfradev/tks-api/internal/middleware/auth/requestRecoder"
"net/http"
)

type Middleware struct {
Expand All @@ -33,21 +34,11 @@ func (m *Middleware) Handle(endpoint internalApi.Endpoint, handle http.Handler)

// pre-handler
preHandler := m.authorizer.WithAuthorization(handle)
// TODO: this is a temporary solution. check if this is the right place to put audit middleware
preHandler = m.audit.WithAudit(preHandler)
preHandler = m.requestRecoder.WithRequestRecoder(endpoint, preHandler)
preHandler = m.authenticator.WithAuthentication(preHandler)

// post-handler
emptyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})

// append post-handler below
// TODO: this is a temporary solution. check if this is the right place to put audit middleware
postHandler := m.audit.WithAudit(emptyHandler)
preHandler = m.audit.WithAudit(endpoint, preHandler)

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
preHandler.ServeHTTP(w, r)

postHandler.ServeHTTP(w, r)
})
}
87 changes: 87 additions & 0 deletions internal/repository/audit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package repository

import (
"fmt"

"github.com/google/uuid"
"gorm.io/gorm"

"github.com/openinfradev/tks-api/internal/pagination"
"github.com/openinfradev/tks-api/pkg/domain"
)

// Interfaces
type IAuditRepository interface {
Get(auditId uuid.UUID) (domain.Audit, error)
Fetch(pg *pagination.Pagination) ([]domain.Audit, error)
Create(dto domain.Audit) (auditId uuid.UUID, err error)
Delete(dto domain.Audit) (err error)
}

type AuditRepository struct {
db *gorm.DB
}

func NewAuditRepository(db *gorm.DB) IAuditRepository {
return &AuditRepository{
db: db,
}
}

// Models
type Audit struct {
gorm.Model

ID uuid.UUID `gorm:"primarykey"`
OrganizationId string
Organization Organization `gorm:"foreignKey:OrganizationId"`
Type string
Message string
ClientIP string
UserId *uuid.UUID `gorm:"type:uuid"`
User User `gorm:"foreignKey:UserId"`
}

func (c *Audit) BeforeCreate(tx *gorm.DB) (err error) {
c.ID = uuid.New()
return nil
}

// Logics
func (r *AuditRepository) Get(auditId uuid.UUID) (out domain.Audit, err error) {
return out, fmt.Errorf("to be implemented")
}

func (r *AuditRepository) Fetch(pg *pagination.Pagination) (out []domain.Audit, err error) {
return out, fmt.Errorf("to be implemented")
}

func (r *AuditRepository) Create(dto domain.Audit) (auditId uuid.UUID, err error) {
audit := Audit{
OrganizationId: dto.OrganizationId,
Type: dto.Type,
Message: dto.Message,
ClientIP: dto.ClientIP,
UserId: dto.UserId}
res := r.db.Create(&audit)
if res.Error != nil {
return uuid.Nil, res.Error
}
return audit.ID, nil
}

func (r *AuditRepository) Delete(dto domain.Audit) (err error) {
return fmt.Errorf("to be implemented")
}

/*
func reflectAudit(audit Audit) (out domain.Audit) {
if err := serializer.Map(audit.Model, &out); err != nil {
log.Error(err)
}
if err := serializer.Map(audit, &out); err != nil {
log.Error(err)
}
return
}
*/
1 change: 1 addition & 0 deletions internal/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Repository struct {
StackTemplate IStackTemplateRepository
Alert IAlertRepository
Project IProjectRepository
Audit IAuditRepository
}

func CombinedGormFilter(table string, filters []pagination.Filter, combinedFilter pagination.CombinedFilter) FilterFunc {
Expand Down
6 changes: 1 addition & 5 deletions internal/repository/stack-template.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"gorm.io/gorm"
"gorm.io/gorm/clause"

"github.com/openinfradev/tks-api/internal/helper"
"github.com/openinfradev/tks-api/internal/pagination"
"github.com/openinfradev/tks-api/internal/serializer"
"github.com/openinfradev/tks-api/pkg/domain"
Expand Down Expand Up @@ -97,7 +96,7 @@ func (r *StackTemplateRepository) Fetch(pg *pagination.Pagination) (out []domain
*/

// paginator, res := filter.Scope(r.db.Order("kube_type DESC,template_type ASC"), pg.GetPaginationRequest(), &stackTemplates)
paginator, res := pg.Fetch(r.db, &stackTemplates)
_, res := pg.Fetch(r.db, &stackTemplates)
if res.Error != nil {
return nil, res.Error
}
Expand All @@ -106,9 +105,6 @@ func (r *StackTemplateRepository) Fetch(pg *pagination.Pagination) (out []domain
out = append(out, reflectStackTemplate(stackTemplate))
}

log.Info(helper.ModelToJson(paginator.Total))
//log.Info(helper.ModelToJson(stackTemplates))

return
}

Expand Down
Loading

0 comments on commit a7095c3

Please sign in to comment.