feat: update activity logs svc
This commit is contained in:
parent
2579548a63
commit
95d79ed1df
|
|
@ -6,6 +6,7 @@ type ActivityLogs struct {
|
||||||
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
|
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
|
||||||
ActivityTypeId int `json:"activity_type_id" gorm:"type:int4"`
|
ActivityTypeId int `json:"activity_type_id" gorm:"type:int4"`
|
||||||
Url string `json:"url" gorm:"type:varchar"`
|
Url string `json:"url" gorm:"type:varchar"`
|
||||||
|
VisitorIp *string `json:"visitor_ip" gorm:"type:varchar"`
|
||||||
ArticleId *uint `json:"article_id" gorm:"type:int4"`
|
ArticleId *uint `json:"article_id" gorm:"type:int4"`
|
||||||
UserId *uint `json:"user_id" gorm:"type:int4"`
|
UserId *uint `json:"user_id" gorm:"type:int4"`
|
||||||
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
utilSvc "go-humas-be/utils/service"
|
utilSvc "go-humas-be/utils/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -26,7 +27,7 @@ func AuditTrailsMiddleware(db *gorm.DB) fiber.Handler {
|
||||||
audit := entity.AuditTrails{
|
audit := entity.AuditTrails{
|
||||||
Method: c.Method(),
|
Method: c.Method(),
|
||||||
Path: c.OriginalURL(),
|
Path: c.OriginalURL(),
|
||||||
IP: c.IP(),
|
IP: getIP(c),
|
||||||
Status: c.Response().StatusCode(),
|
Status: c.Response().StatusCode(),
|
||||||
UserID: userId,
|
UserID: userId,
|
||||||
RequestHeaders: string(headersJSON),
|
RequestHeaders: string(headersJSON),
|
||||||
|
|
@ -50,7 +51,18 @@ func StartAuditTrailCleanup(db *gorm.DB, retention int) {
|
||||||
cutoff := time.Now().AddDate(0, 0, retention)
|
cutoff := time.Now().AddDate(0, 0, retention)
|
||||||
db.Where("created_at < ?", cutoff).Delete(&entity.AuditTrails{})
|
db.Where("created_at < ?", cutoff).Delete(&entity.AuditTrails{})
|
||||||
|
|
||||||
log.Printf("Audit Trail Cleanup at: %s", cutoff)
|
log.Printf(" at: %s", cutoff)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getIP(c *fiber.Ctx) string {
|
||||||
|
ip := c.Get("X-Forwarded-For")
|
||||||
|
if ip == "" {
|
||||||
|
ip = c.IP()
|
||||||
|
}
|
||||||
|
if strings.Contains(ip, ":") {
|
||||||
|
ip = strings.Split(ip, ":")[0]
|
||||||
|
}
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
utilRes "go-humas-be/utils/response"
|
utilRes "go-humas-be/utils/response"
|
||||||
utilVal "go-humas-be/utils/validator"
|
utilVal "go-humas-be/utils/validator"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type activityLogsController struct {
|
type activityLogsController struct {
|
||||||
|
|
@ -126,6 +127,8 @@ func (_i *activityLogsController) Save(c *fiber.Ctx) error {
|
||||||
} else {
|
} else {
|
||||||
authToken = &getTokenFromHeader
|
authToken = &getTokenFromHeader
|
||||||
}
|
}
|
||||||
|
visitorIp := GetVisitorIP(c)
|
||||||
|
req.VisitorIp = &visitorIp
|
||||||
dataResult, err := _i.activityLogsService.Save(*req, authToken)
|
dataResult, err := _i.activityLogsService.Save(*req, authToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -201,3 +204,14 @@ func (_i *activityLogsController) Delete(c *fiber.Ctx) error {
|
||||||
Messages: utilRes.Messages{"ActivityLogs successfully deleted"},
|
Messages: utilRes.Messages{"ActivityLogs successfully deleted"},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetVisitorIP(c *fiber.Ctx) string {
|
||||||
|
ip := c.Get("X-Forwarded-For")
|
||||||
|
if ip == "" {
|
||||||
|
ip = c.IP()
|
||||||
|
}
|
||||||
|
if strings.Contains(ip, ":") {
|
||||||
|
ip = strings.Split(ip, ":")[0]
|
||||||
|
}
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"go-humas-be/app/module/activity_logs/request"
|
"go-humas-be/app/module/activity_logs/request"
|
||||||
"go-humas-be/utils/paginator"
|
"go-humas-be/utils/paginator"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type activityLogsRepository struct {
|
type activityLogsRepository struct {
|
||||||
|
|
@ -22,6 +23,8 @@ type ActivityLogsRepository interface {
|
||||||
Create(activityLogs *entity.ActivityLogs) (activityLogsReturn *entity.ActivityLogs, err error)
|
Create(activityLogs *entity.ActivityLogs) (activityLogsReturn *entity.ActivityLogs, err error)
|
||||||
Update(id uint, activityLogs *entity.ActivityLogs) (err error)
|
Update(id uint, activityLogs *entity.ActivityLogs) (err error)
|
||||||
Delete(id uint) (err error)
|
Delete(id uint) (err error)
|
||||||
|
CountUniqueVisitorAllTime() (count int64, err error)
|
||||||
|
CountUniqueVisitorToday() (count int64, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewActivityLogsRepository(db *database.Database, logger zerolog.Logger) ActivityLogsRepository {
|
func NewActivityLogsRepository(db *database.Database, logger zerolog.Logger) ActivityLogsRepository {
|
||||||
|
|
@ -95,3 +98,25 @@ func (_i *activityLogsRepository) Update(id uint, activityLogs *entity.ActivityL
|
||||||
func (_i *activityLogsRepository) Delete(id uint) error {
|
func (_i *activityLogsRepository) Delete(id uint) error {
|
||||||
return _i.DB.DB.Delete(&entity.ActivityLogs{}, id).Error
|
return _i.DB.DB.Delete(&entity.ActivityLogs{}, id).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_i *activityLogsRepository) CountUniqueVisitorAllTime() (count int64, err error) {
|
||||||
|
err = _i.DB.DB.
|
||||||
|
Model(&entity.ActivityLogs{}).
|
||||||
|
Distinct("visitor_ip").
|
||||||
|
Count(&count).Error
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_i *activityLogsRepository) CountUniqueVisitorToday() (count int64, err error) {
|
||||||
|
tenMinutesAgo := time.Now().Add(-10 * time.Minute)
|
||||||
|
|
||||||
|
err = _i.DB.DB.
|
||||||
|
Model(&entity.AuditTrails{}).
|
||||||
|
Where("created_at >= ?", tenMinutesAgo).
|
||||||
|
Select("ip").
|
||||||
|
Group("ip").
|
||||||
|
Count(&count).Error
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ type ActivityLogsCreateRequest struct {
|
||||||
Url string `json:"url" validate:"required"`
|
Url string `json:"url" validate:"required"`
|
||||||
ArticleId *uint `json:"articleId"`
|
ArticleId *uint `json:"articleId"`
|
||||||
UserId *uint `json:"userId"`
|
UserId *uint `json:"userId"`
|
||||||
|
VisitorIp *string `json:"visitorIp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req ActivityLogsCreateRequest) ToEntity() *entity.ActivityLogs {
|
func (req ActivityLogsCreateRequest) ToEntity() *entity.ActivityLogs {
|
||||||
|
|
@ -32,6 +33,7 @@ func (req ActivityLogsCreateRequest) ToEntity() *entity.ActivityLogs {
|
||||||
Url: req.Url,
|
Url: req.Url,
|
||||||
ArticleId: req.ArticleId,
|
ArticleId: req.ArticleId,
|
||||||
UserId: req.UserId,
|
UserId: req.UserId,
|
||||||
|
VisitorIp: req.VisitorIp,
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,3 +30,7 @@ type UsersResponse struct {
|
||||||
type ParetoLoginResponse struct {
|
type ParetoLoginResponse struct {
|
||||||
AccessToken string `json:"accessToken"`
|
AccessToken string `json:"accessToken"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VisitorStatistic struct {
|
||||||
|
TotalVisitor string `json:"accessToken"`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,3 +161,27 @@ func (_keycloak *KeycloakConfig) SetPasswordWithoutToken(keycloakId string, pass
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_keycloak *KeycloakConfig) GetUserSessions() ([]*gocloak.UserSessionRepresentation, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
client := gocloak.NewClient(_keycloak.Cfg.Keycloak.Endpoint)
|
||||||
|
|
||||||
|
token, err := client.Login(
|
||||||
|
ctx,
|
||||||
|
_keycloak.Cfg.Keycloak.ClientId,
|
||||||
|
_keycloak.Cfg.Keycloak.ClientSecret,
|
||||||
|
_keycloak.Cfg.Keycloak.Realm,
|
||||||
|
_keycloak.Cfg.Keycloak.AdminUsername,
|
||||||
|
_keycloak.Cfg.Keycloak.AdminPassword,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic("Something wrong with the credentials or url")
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionData, err := client.GetClientUserSessions(ctx, token.AccessToken, _keycloak.Cfg.Keycloak.Realm, _keycloak.Cfg.Keycloak.ClientId)
|
||||||
|
if err != nil {
|
||||||
|
panic("Oh no!, failed to set password :(")
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionData, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,6 @@ services:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- ./data/web-humas-be/logs:/app
|
||||||
ports:
|
ports:
|
||||||
- "8800:8800"
|
- "8800:8800"
|
||||||
|
|
@ -9974,6 +9974,9 @@ const docTemplate = `{
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"visitorIp": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -9963,6 +9963,9 @@
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"visitorIp": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
userId:
|
userId:
|
||||||
type: integer
|
type: integer
|
||||||
|
visitorIp:
|
||||||
|
type: string
|
||||||
required:
|
required:
|
||||||
- activityTypeId
|
- activityTypeId
|
||||||
- url
|
- url
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue