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 [post] // @Security Bearer // @tags Activity func (app *appContext) GetActivities(gc *gin.Context) { req := GetActivitiesDTO{} gc.BindJSON(&req) query := &badgerhold.Query{} activityTypes := make([]interface{}, len(req.Type)) for i, v := range req.Type { activityTypes[i] = stringToActivityType(v) } if len(activityTypes) != 0 { query = badgerhold.Where("Type").In(activityTypes...) } 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)), LastPage: len(results) != req.Limit, } 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(), } if act.Type == ActivityDeletion || act.Type == ActivityCreation { resp.Activities[i].Username = act.Value resp.Activities[i].Value = "" } else if user, status, err := app.jf.UserByID(act.UserID, false); status == 200 && err == nil { resp.Activities[i].Username = user.Name } if (act.SourceType == ActivityUser || act.SourceType == ActivityAdmin) && act.Source != "" { user, status, err := app.jf.UserByID(act.Source, false) if status == 200 && err == nil { resp.Activities[i].SourceUsername = user.Name } } } gc.JSON(200, resp) } // @Summary Delete the activity with the given ID. No-op if non-existent, always succeeds. // @Produce json // @Param id path string true "ID of activity to delete" // @Success 200 {object} boolResponse // @Router /activity/{id} [delete] // @Security Bearer // @tags Activity func (app *appContext) DeleteActivity(gc *gin.Context) { app.storage.DeleteActivityKey(gc.Param("id")) respondBool(200, true, gc) }