mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
activity: route to show activity activity log
filterable by type, sortable by time, and paginated.
This commit is contained in:
parent
9d1c7bba6f
commit
df1581d48e
141
api-activities.go
Normal file
141
api-activities.go
Normal file
@ -0,0 +1,141 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/timshannon/badgerhold/v4"
|
||||
)
|
||||
|
||||
func stringToActivityType(v string) ActivityType {
|
||||
switch v {
|
||||
case "creation":
|
||||
return ActivityCreation
|
||||
case "deletion":
|
||||
return ActivityDeletion
|
||||
case "disabled":
|
||||
return ActivityDisabled
|
||||
case "enabled":
|
||||
return ActivityEnabled
|
||||
case "contactLinked":
|
||||
return ActivityContactLinked
|
||||
case "contactUnlinked":
|
||||
return ActivityContactUnlinked
|
||||
case "changePassword":
|
||||
return ActivityChangePassword
|
||||
case "resetPassword":
|
||||
return ActivityResetPassword
|
||||
case "createInvite":
|
||||
return ActivityCreateInvite
|
||||
case "deleteInvite":
|
||||
return ActivityDeleteInvite
|
||||
}
|
||||
return ActivityUnknown
|
||||
}
|
||||
|
||||
func activityTypeToString(v ActivityType) string {
|
||||
switch v {
|
||||
case ActivityCreation:
|
||||
return "creation"
|
||||
case ActivityDeletion:
|
||||
return "deletion"
|
||||
case ActivityDisabled:
|
||||
return "disabled"
|
||||
case ActivityEnabled:
|
||||
return "enabled"
|
||||
case ActivityContactLinked:
|
||||
return "contactLinked"
|
||||
case ActivityContactUnlinked:
|
||||
return "contactUnlinked"
|
||||
case ActivityChangePassword:
|
||||
return "changePassword"
|
||||
case ActivityResetPassword:
|
||||
return "resetPassword"
|
||||
case ActivityCreateInvite:
|
||||
return "createInvite"
|
||||
case ActivityDeleteInvite:
|
||||
return "deleteInvite"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
func stringToActivitySource(v string) ActivitySource {
|
||||
switch v {
|
||||
case "user":
|
||||
return ActivityUser
|
||||
case "admin":
|
||||
return ActivityAdmin
|
||||
case "anon":
|
||||
return ActivityAnon
|
||||
case "daemon":
|
||||
return ActivityDaemon
|
||||
}
|
||||
return ActivityAnon
|
||||
}
|
||||
|
||||
func activitySourceToString(v ActivitySource) string {
|
||||
switch v {
|
||||
case ActivityUser:
|
||||
return "user"
|
||||
case ActivityAdmin:
|
||||
return "admin"
|
||||
case ActivityAnon:
|
||||
return "anon"
|
||||
case ActivityDaemon:
|
||||
return "daemon"
|
||||
}
|
||||
return "anon"
|
||||
}
|
||||
|
||||
// @Summary Get the requested set of activities, Paginated, filtered and sorted.
|
||||
// @Produce json
|
||||
// @Param GetActivitiesDTO body GetActivitiesDTO true "search parameters"
|
||||
// @Success 200 {object} GetActivitiesRespDTO
|
||||
// @Router /activity [get]
|
||||
// @Security Bearer
|
||||
// @tags Activity
|
||||
func (app *appContext) GetActivities(gc *gin.Context) {
|
||||
req := GetActivitiesDTO{}
|
||||
gc.BindJSON(&req)
|
||||
query := &badgerhold.Query{}
|
||||
activityType := stringToActivityType(req.Type)
|
||||
if activityType != ActivityUnknown {
|
||||
query = badgerhold.Where("Type").Eq(activityType)
|
||||
}
|
||||
|
||||
if req.Ascending {
|
||||
query = query.Reverse()
|
||||
}
|
||||
|
||||
query = query.SortBy("Time")
|
||||
|
||||
if req.Limit == 0 {
|
||||
req.Limit = 10
|
||||
}
|
||||
|
||||
query = query.Skip(req.Page * req.Limit).Limit(req.Limit)
|
||||
|
||||
var results []Activity
|
||||
err := app.storage.db.Find(&results, query)
|
||||
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to read activities from DB: %v\n", err)
|
||||
}
|
||||
|
||||
resp := GetActivitiesRespDTO{
|
||||
Activities: make([]ActivityDTO, len(results)),
|
||||
}
|
||||
|
||||
for i, act := range results {
|
||||
resp.Activities[i] = ActivityDTO{
|
||||
ID: act.ID,
|
||||
Type: activityTypeToString(act.Type),
|
||||
UserID: act.UserID,
|
||||
SourceType: activitySourceToString(act.SourceType),
|
||||
Source: act.Source,
|
||||
InviteCode: act.InviteCode,
|
||||
Value: act.Value,
|
||||
Time: act.Time.Unix(),
|
||||
}
|
||||
}
|
||||
|
||||
gc.JSON(200, resp)
|
||||
}
|
3
main.go
3
main.go
@ -638,6 +638,9 @@ func flagPassed(name string) (found bool) {
|
||||
// @tag.name Profiles & Settings
|
||||
// @tag.description Profile and settings related operations.
|
||||
|
||||
// @tag.name Activity
|
||||
// @tag.description Routes related to the activity log.
|
||||
|
||||
// @tag.name Configuration
|
||||
// @tag.description jfa-go settings.
|
||||
|
||||
|
22
models.go
22
models.go
@ -430,3 +430,25 @@ type GetMyReferralRespDTO struct {
|
||||
type EnableDisableReferralDTO struct {
|
||||
Users []string `json:"users"`
|
||||
}
|
||||
|
||||
type ActivityDTO struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
UserID string `json:"user_id"`
|
||||
SourceType string `json:"source_type"`
|
||||
Source string `json:"source"`
|
||||
InviteCode string `json:"invite_code"`
|
||||
Value string `json:"value"`
|
||||
Time int64 `json:"time"`
|
||||
}
|
||||
|
||||
type GetActivitiesDTO struct {
|
||||
Type string `json:"type"` // Type of activity to get. Leave blank for all.
|
||||
Limit int `json:"limit"`
|
||||
Page int `json:"page"` // zero-indexed
|
||||
Ascending bool `json:"ascending"`
|
||||
}
|
||||
|
||||
type GetActivitiesRespDTO struct {
|
||||
Activities []ActivityDTO `json:"activities"`
|
||||
}
|
||||
|
@ -232,6 +232,8 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
||||
api.DELETE(p+"/profiles/referral/:profile", app.DisableReferralForProfile)
|
||||
}
|
||||
|
||||
api.GET(p+"/activity", app.GetActivities)
|
||||
|
||||
if userPageEnabled {
|
||||
user.GET("/details", app.MyDetails)
|
||||
user.POST("/contact", app.SetMyContactMethods)
|
||||
|
@ -34,6 +34,7 @@ const (
|
||||
ActivityResetPassword
|
||||
ActivityCreateInvite
|
||||
ActivityDeleteInvite
|
||||
ActivityUnknown
|
||||
)
|
||||
|
||||
type ActivitySource int
|
||||
@ -46,6 +47,7 @@ const (
|
||||
)
|
||||
|
||||
type Activity struct {
|
||||
ID string `badgerhold:"key"`
|
||||
Type ActivityType `badgerhold:"index"`
|
||||
UserID string // ID of target user. For account creation, this will be the newly created account
|
||||
SourceType ActivitySource
|
||||
@ -562,6 +564,7 @@ func (st *Storage) GetActivityKey(k string) (Activity, bool) {
|
||||
|
||||
// SetActivityKey stores value v in key k.
|
||||
func (st *Storage) SetActivityKey(k string, v Activity) {
|
||||
v.ID = k
|
||||
err := st.db.Upsert(k, v)
|
||||
if err != nil {
|
||||
// fmt.Printf("Failed to set custom content: %v\n", err)
|
||||
|
Loading…
Reference in New Issue
Block a user