diff --git a/api/util/logger.go b/api/util/logger.go index d00d4f62f5..defd9aa71b 100644 --- a/api/util/logger.go +++ b/api/util/logger.go @@ -25,6 +25,7 @@ import ( "github.com/devtron-labs/devtron/internal/middleware" "github.com/devtron-labs/devtron/pkg/auth/user" + "github.com/devtron-labs/devtron/util" ) type AuditLoggerDTO struct { @@ -36,6 +37,7 @@ type AuditLoggerDTO struct { RequestPayload []byte `json:"requestPayload"` RequestMethod string `json:"requestMethod"` ResponseTime time.Duration `json:"responseTime"` + ClientIp string `json:"clientIp"` } type LoggingMiddlewareImpl struct { @@ -56,13 +58,12 @@ type LoggingMiddleware interface { func (impl LoggingMiddlewareImpl) LoggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { d := middleware.NewDelegator(w, nil) - token := r.Header.Get("token") userEmail, err := impl.userService.GetEmailFromToken(token) if err != nil { log.Printf("AUDIT_LOG: user does not exists") } - + clientIp := util.GetClientIP(r) // Read the request body into a buffer var bodyBuffer bytes.Buffer _, err = io.Copy(&bodyBuffer, r.Body) @@ -83,6 +84,7 @@ func (impl LoggingMiddlewareImpl) LoggingMiddleware(next http.Handler) http.Hand QueryParams: r.URL.Query().Encode(), RequestPayload: bodyBuffer.Bytes(), RequestMethod: r.Method, + ClientIp: clientIp, } // Call the next handler in the chain. next.ServeHTTP(d, r) @@ -95,5 +97,5 @@ func (impl LoggingMiddlewareImpl) LoggingMiddleware(next http.Handler) http.Hand } func LogRequest(auditLogDto *AuditLoggerDTO) { - log.Printf("AUDIT_LOG: requestMethod: %s, urlPath: %s, queryParams: %s, updatedBy: %s, updatedOn: %s, apiResponseCode: %d, responseTime: %s, requestPayload: %s", auditLogDto.RequestMethod, auditLogDto.UrlPath, auditLogDto.QueryParams, auditLogDto.UserEmail, auditLogDto.UpdatedOn, auditLogDto.ApiResponseCode, auditLogDto.ResponseTime, auditLogDto.RequestPayload) + log.Printf("AUDIT_LOG: clientIp: %s, requestMethod: %s, urlPath: %s, queryParams: %s, updatedBy: %s, updatedOn: %s, apiResponseCode: %d, responseTime: %s, requestPayload: %s", auditLogDto.ClientIp, auditLogDto.RequestMethod, auditLogDto.UrlPath, auditLogDto.QueryParams, auditLogDto.UserEmail, auditLogDto.UpdatedOn, auditLogDto.ApiResponseCode, auditLogDto.ResponseTime, auditLogDto.RequestPayload) } diff --git a/pkg/auth/user/UserService.go b/pkg/auth/user/UserService.go index 3bb8e45e8a..5be9e8f017 100644 --- a/pkg/auth/user/UserService.go +++ b/pkg/auth/user/UserService.go @@ -19,17 +19,18 @@ package user import ( "context" "fmt" + "net/http" + "strconv" + "strings" + "sync" + "time" + bean4 "github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin/bean" "github.com/devtron-labs/devtron/pkg/auth/user/adapter" userHelper "github.com/devtron-labs/devtron/pkg/auth/user/helper" adapter2 "github.com/devtron-labs/devtron/pkg/auth/user/repository/adapter" "github.com/devtron-labs/devtron/pkg/auth/user/repository/helper" util3 "github.com/devtron-labs/devtron/pkg/auth/user/util" - "net/http" - "strconv" - "strings" - "sync" - "time" "github.com/devtron-labs/authenticator/jwt" "github.com/devtron-labs/authenticator/middleware" @@ -1237,7 +1238,7 @@ func (impl *UserServiceImpl) GetLoggedInUser(r *http.Request) (int32, error) { userId, userType, err := impl.GetUserByToken(r.Context(), token) // if user is of api-token type, then update lastUsedBy and lastUsedAt if err == nil && userType == userBean.USER_TYPE_API_TOKEN { - go impl.saveUserAudit(r, userId) + go impl.updateUserAudit(r, userId) } return userId, err } @@ -1664,9 +1665,15 @@ func (impl *UserServiceImpl) saveUserAudit(r *http.Request, userId int32) { CreatedOn: time.Now(), UpdatedOn: time.Now(), } - // Using Update instead of Save to upsert (update if exists, insert if not) - // This prevents the user_audit table from filling up with duplicate entries - // for API token users + impl.userAuditService.Save(userAudit) +} + +func (impl *UserServiceImpl) updateUserAudit(r *http.Request, userId int32) { + clientIp := util2.GetClientIP(r) + userAudit := &UserAudit{ + UserId: userId, + ClientIp: clientIp, + } impl.userAuditService.Update(userAudit) }