From f703f2d1ab4a274f0c4ed30e64b7f2d9799c967b Mon Sep 17 00:00:00 2001 From: Preston Baxter Date: Thu, 16 Nov 2023 19:43:34 -0600 Subject: [PATCH] B: implement audit trail saving --- service/controllers/pco_webhook.go | 49 ++++++++++++++++++++++-------- ui/db/db.go | 30 +++++++++++++++++- ui/db/models/audit.go | 3 +- 3 files changed, 68 insertions(+), 14 deletions(-) diff --git a/service/controllers/pco_webhook.go b/service/controllers/pco_webhook.go index 7d82638..4444ed6 100644 --- a/service/controllers/pco_webhook.go +++ b/service/controllers/pco_webhook.go @@ -12,18 +12,18 @@ import ( "git.preston-baxter.com/Preston_PLB/capstone/webhook-service/vendors/pco" "git.preston-baxter.com/Preston_PLB/capstone/webhook-service/vendors/pco/services" "git.preston-baxter.com/Preston_PLB/capstone/webhook-service/vendors/pco/webhooks" + yt_helpers "git.preston-baxter.com/Preston_PLB/capstone/webhook-service/vendors/youtube" "github.com/gin-gonic/gin" "github.com/google/jsonapi" "go.mongodb.org/mongo-driver/bson/primitive" "golang.org/x/oauth2" "google.golang.org/api/option" "google.golang.org/api/youtube/v3" - yt_helpers "git.preston-baxter.com/Preston_PLB/capstone/webhook-service/vendors/youtube" ) var ( eventRegexKeys = map[string]string{"plan": `^services\.v2\.events\.plan\..*`} - actionFuncMap = map[string]actionFunc{"youtube.livestream": ScheduleLiveStreamFromWebhook} + actionFuncMap = map[string]actionFunc{"youtube.livestream": ScheduleBroadcastFromWebhook} ) type actionFunc func(*gin.Context, *webhooks.EventDelivery) error @@ -72,7 +72,6 @@ func ConsumePcoWebhook(c *gin.Context) { return } - //perform actions //loop through all actions a user has for _, mapping := range actionMappings { @@ -186,29 +185,55 @@ func ScheduleBroadcastFromWebhook(c *gin.Context, body *webhooks.EventDelivery) return err } + //Save audit point + eventRecievedAudit := &models.EventRecieved{ + UserId: uid, + VendorName: models.PCO_VENDOR_NAME, + Type: body.Name, + } + if err := mongo.SaveModel(eventRecievedAudit); err != nil { + log.WithError(err).WithField("EventRecieved", eventRecievedAudit).Error("Failed to save audit event. Logging here and resuming") + } + //create the broadcast //TODO: handle update //TODO: handle delete + var broadcast *youtube.LiveBroadcast switch body.Name { case "services.v2.events.plan.created": - return scheduleNewBroadcastFromWebhook(c, payload, ytClient, pcoClient) + broadcast, err = scheduleNewBroadcastFromWebhook(c, payload, ytClient, pcoClient) default: return fmt.Errorf("Unkown event error: %s", body.Name) } -} -func scheduleNewBroadcastFromWebhook(c *gin.Context, plan *services.Plan, ytClient *youtube.Service, pcoClient *pco.PcoApiClient) error { - times, err := pcoClient.GetPlanTimes(plan.ServiceType.Id, plan.Id) - if err != nil { - log.WithError(err).Error("Failed to get plan times") - return err + //build audit trail after action was taken + broadcastModel := &models.YoutubeBroadcast{ + UserId: uid, + Details: broadcast, } - broadcast, err := yt_helpers.InsertBroadcast(ytClient, plan.Title, times.StartsAt, yt_helpers.STATUS_PRIVATE) + actionTaken := &models.ActionTaken{ + UserId: uid, + TriggeringEvent: eventRecievedAudit.MongoId(), + Result: []primitive.ObjectID{broadcastModel.MongoId()}, + VendorName: models.YOUTUBE_VENDOR_NAME, + } + + //save audit trail + err = mongo.SaveModels(broadcastModel, actionTaken) if err != nil { - log.WithError(err).Error("Failed to schedule broadcast") + log.WithError(err).Error("Failed to unmarshall body") return err } return nil } + +func scheduleNewBroadcastFromWebhook(c *gin.Context, plan *services.Plan, ytClient *youtube.Service, pcoClient *pco.PcoApiClient) (*youtube.LiveBroadcast, error) { + times, err := pcoClient.GetPlanTimes(plan.ServiceType.Id, plan.Id) + if err != nil { + return nil, err + } + + return yt_helpers.InsertBroadcast(ytClient, plan.Title, times.StartsAt, yt_helpers.STATUS_PRIVATE) +} diff --git a/ui/db/db.go b/ui/db/db.go index 32abd66..0bcf923 100644 --- a/ui/db/db.go +++ b/ui/db/db.go @@ -47,7 +47,35 @@ func (db *DB) SaveModel(m Model) error { } if res.MatchedCount == 0 && res.ModifiedCount == 0 && res.UpsertedCount == 0 { - return errors.New("Failed to update vendor account properly") + return errors.New("Failed to save model properly") + } + + return nil +} + +func (db *DB) SaveModels(m ...Model) error { + conf := config.Config() + + writeEntry := make([]mongo.WriteModel, len(m)) + + for index, model := range m { + entry := mongo.NewUpdateOneModel() + entry.SetFilter(bson.M{"_id": model.MongoId}) + entry.SetUpsert(true) + entry.SetUpdate(bson.M{"$set": model}) + model.UpdateObjectInfo() + + writeEntry[index] = entry + } + + opts := options.BulkWrite() + res, err := db.client.Database(conf.Mongo.EntDb).Collection(conf.Mongo.EntCol).BulkWrite(context.Background(), writeEntry, opts) + if err != nil { + return err + } + + if res.MatchedCount == 0 && res.ModifiedCount == 0 && res.UpsertedCount == 0 { + return errors.New("Failed to save models properly") } return nil diff --git a/ui/db/models/audit.go b/ui/db/models/audit.go index f352346..3f97c9b 100644 --- a/ui/db/models/audit.go +++ b/ui/db/models/audit.go @@ -15,8 +15,9 @@ const ( type EventRecieved struct { *CommonFields `bson:"obj_info"` Id primitive.ObjectID `bson:"_id,omitempty"` - UserId primitive.ObjectID `bson:"user_id,omitempty"` //what user is this associated too + UserId primitive.ObjectID `bson:"user_id,omitempty"` //what user is this associated too VendorName string `bson:"vendor_name,omitempty"` //Vendor name of who sent us the event + Type string `bson:"type,omitempty"` //type of event } func (obj *EventRecieved) MongoId() primitive.ObjectID {