diff --git a/go.mod b/go.mod index 30b0871..13ec3f4 100644 --- a/go.mod +++ b/go.mod @@ -44,6 +44,7 @@ require ( github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect + github.com/robfig/cron v1.2.0 github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect diff --git a/go.sum b/go.sum index 46d1161..d493ed1 100644 --- a/go.sum +++ b/go.sum @@ -87,6 +87,8 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= diff --git a/models/booking/booking_mongo_accessor.go b/models/booking/booking_mongo_accessor.go index f189e60..28c7f45 100644 --- a/models/booking/booking_mongo_accessor.go +++ b/models/booking/booking_mongo_accessor.go @@ -30,27 +30,27 @@ func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCal /* * Nothing special here, just the basic CRUD operations */ -func (wfa *bookingMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { - return wfa.GenericDeleteOne(id, wfa) +func (a *bookingMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { + return utils.GenericDeleteOne(id, a) } -func (wfa *bookingMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { - return wfa.GenericUpdateOne(set, id, wfa, &Booking{}) +func (a *bookingMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { + return utils.GenericUpdateOne(set, id, a, &Booking{}) } -func (wfa *bookingMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) +func (a *bookingMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { + return utils.GenericStoreOne(data, a) } -func (wfa *bookingMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) +func (a *bookingMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { + return utils.GenericStoreOne(data, a) } func (a *bookingMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { return utils.GenericLoadOne[*Booking](id, func(d utils.DBObject) (utils.DBObject, int, error) { if d.(*Booking).State == workflow_execution.SCHEDULED && time.Now().UTC().After(*d.(*Booking).ExecDate) { d.(*Booking).State = workflow_execution.FORGOTTEN - a.GenericRawUpdateOne(d, id, a) + utils.GenericRawUpdateOne(d, id, a) } return d, 200, nil }, a) @@ -68,7 +68,7 @@ func (a *bookingMongoAccessor) getExec() func(utils.DBObject) utils.ShallowDBObj return func(d utils.DBObject) utils.ShallowDBObject { if d.(*Booking).State == workflow_execution.SCHEDULED && time.Now().UTC().After(*d.(*Booking).ExecDate) { d.(*Booking).State = workflow_execution.FORGOTTEN - a.GenericRawUpdateOne(d, d.GetID(), a) + utils.GenericRawUpdateOne(d, d.GetID(), a) } return d } diff --git a/models/collaborative_area/collaborative_area.go b/models/collaborative_area/collaborative_area.go index 7317e78..ec03d15 100644 --- a/models/collaborative_area/collaborative_area.go +++ b/models/collaborative_area/collaborative_area.go @@ -4,6 +4,7 @@ import ( "slices" "time" + "cloud.o-forge.io/core/oc-lib/config" "cloud.o-forge.io/core/oc-lib/models/collaborative_area/rules/rule" "cloud.o-forge.io/core/oc-lib/models/peer" "cloud.o-forge.io/core/oc-lib/models/utils" @@ -42,6 +43,32 @@ type CollaborativeArea struct { SharedPeers []*peer.Peer `json:"shared_peers,omitempty" bson:"-"` // SharedPeers is the shared peers of the workspace } +func (ao *CollaborativeArea) Clear(peerID string) { + ao.CreatorID = peerID + if config.GetConfig().Whitelist { + ao.AllowedPeersGroup[peerID] = []string{"*"} + } else { + ao.AllowedPeersGroup[peerID] = []string{} + } + // then reset the shared fields + if ao.Workspaces == nil { + ao.Workspaces = []string{} + } + if ao.Workflows == nil { + ao.Workflows = []string{} + } + if ao.Rules == nil { + ao.Rules = []string{} + } + if ao.CollaborativeAreaRule == nil { + ao.CollaborativeAreaRule = &CollaborativeAreaRule{ + ShareMode: "private", + ExploitedBy: "collaborators only", + } + } + ao.CollaborativeAreaRule.CreatedAt = time.Now().UTC() +} + func (ao *CollaborativeArea) VerifyAuth(peerID string, groups []string) bool { if ao.AllowedPeersGroup != nil && len(ao.AllowedPeersGroup) > 0 { if grps, ok := ao.AllowedPeersGroup[peerID]; ok { diff --git a/models/collaborative_area/collaborative_area_mongo_accessor.go b/models/collaborative_area/collaborative_area_mongo_accessor.go index f41677f..6fdaebf 100644 --- a/models/collaborative_area/collaborative_area_mongo_accessor.go +++ b/models/collaborative_area/collaborative_area_mongo_accessor.go @@ -4,15 +4,13 @@ import ( "errors" "fmt" "slices" - "time" - "cloud.o-forge.io/core/oc-lib/config" "cloud.o-forge.io/core/oc-lib/dbs" - "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/logs" "cloud.o-forge.io/core/oc-lib/models/collaborative_area/rules/rule" "cloud.o-forge.io/core/oc-lib/models/peer" "cloud.o-forge.io/core/oc-lib/models/utils" + "cloud.o-forge.io/core/oc-lib/models/workflow" w "cloud.o-forge.io/core/oc-lib/models/workflow" "cloud.o-forge.io/core/oc-lib/models/workspace" "cloud.o-forge.io/core/oc-lib/tools" @@ -45,35 +43,120 @@ func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCal } // DeleteOne deletes a collaborative area from the database, given its ID, it automatically share to peers if the workspace is shared -func (wfa *collaborativeAreaMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { - set, code, err := wfa.LoadOne(id) +func (a *collaborativeAreaMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { + set, code, err := a.LoadOne(id) if code != 200 { return nil, code, err } - wfa.deleteToPeer(set.(*CollaborativeArea)) - wfa.sharedWorkflow(&CollaborativeArea{}, id) // create all shared workflows - wfa.sharedWorkspace(&CollaborativeArea{}, id) // create all collaborative areas - return wfa.GenericDeleteOne(id, wfa) // then add on yours + a.deleteToPeer(set.(*CollaborativeArea)) + a.sharedWorkflow(&CollaborativeArea{}, id) // create all shared workflows + a.sharedWorkspace(&CollaborativeArea{}, id) // create all collaborative areas + return utils.GenericDeleteOne(id, a) // then add on yours +} + +// UpdateOne updates a collaborative area in the database, given its ID and the new data, it automatically share to peers if the workspace is shared +func (a *collaborativeAreaMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { + res, code, err := utils.GenericUpdateOne(set.(*CollaborativeArea).Trim(), id, a, &CollaborativeArea{}) + // a.deleteToPeer(res.(*CollaborativeArea)) // delete the collaborative area on the peer + a.sharedWorkflow(res.(*CollaborativeArea), id) // replace all shared workflows + a.sharedWorkspace(res.(*CollaborativeArea), id) // replace all collaborative areas (not shared worspace obj but workspace one) + // a.sendToPeer(res.(*CollaborativeArea)) // send the collaborative area (collaborative area object) to the peers + return res, code, err +} + +// StoreOne stores a collaborative area in the database, it automatically share to peers if the workspace is shared +func (a *collaborativeAreaMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { + _, id := (&peer.Peer{}).IsMySelf() // get the local peer + data.(*CollaborativeArea).Clear(id) // set the creator + // retrieve or proper peer + dd, code, err := a.peerAccessor.Search(nil, "0") + if code != 200 || len(dd) == 0 { + return nil, code, errors.New("Could not retrieve the peer" + err.Error()) + } + data.(*CollaborativeArea).CollaborativeAreaRule.Creator = dd[0].GetID() + d, code, err := utils.GenericStoreOne(data.(*CollaborativeArea).Trim(), a) + if code == 200 { + a.sharedWorkflow(d.(*CollaborativeArea), d.GetID()) // create all shared workflows + a.sharedWorkspace(d.(*CollaborativeArea), d.GetID()) // create all collaborative areas + a.sendToPeer(d.(*CollaborativeArea)) // send the collaborative area (collaborative area object) to the peers + } + return data, code, err +} + +// CopyOne copies a CollaborativeArea in the database +func (a *collaborativeAreaMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { + return a.StoreOne(data) +} + +func filterEnrich[T utils.ShallowDBObject](arr []string, a utils.Accessor) []T { + var new []T + res, code, _ := a.Search(&dbs.Filters{ + Or: map[string][]dbs.Filter{ + "abstractobject.id": {{Operator: dbs.IN.String(), Value: arr}}, + }, + }, "") + if code == 200 { + for _, r := range res { + new = append(new, r.(T)) + } + } + return new +} + +// enrich is a function that enriches the CollaborativeArea with the shared objects +func (a *collaborativeAreaMongoAccessor) enrich(sharedWorkspace *CollaborativeArea) *CollaborativeArea { + sharedWorkspace.SharedWorkspaces = append(sharedWorkspace.SharedWorkspaces, + filterEnrich[*workspace.Workspace](sharedWorkspace.Workspaces, a.workspaceAccessor)...) + sharedWorkspace.SharedWorkflows = append(sharedWorkspace.SharedWorkflows, + filterEnrich[*workflow.Workflow](sharedWorkspace.Workflows, a.workflowAccessor)...) + peerskey := []string{} + for k := range sharedWorkspace.AllowedPeersGroup { + peerskey = append(peerskey, k) + } + sharedWorkspace.SharedPeers = append(sharedWorkspace.SharedPeers, + filterEnrich[*peer.Peer](peerskey, a.peerAccessor)...) + sharedWorkspace.SharedRules = append(sharedWorkspace.SharedRules, + filterEnrich[*rule.Rule](sharedWorkspace.Rules, a.ruleAccessor)...) + return sharedWorkspace +} + +func (a *collaborativeAreaMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { + return utils.GenericLoadOne[*CollaborativeArea](id, func(d utils.DBObject) (utils.DBObject, int, error) { + return a.enrich(d.(*CollaborativeArea)), 200, nil + }, a) +} + +func (a *collaborativeAreaMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { + return utils.GenericLoadAll[*CollaborativeArea](func(d utils.DBObject) utils.ShallowDBObject { + return a.enrich(d.(*CollaborativeArea)) + }, a) +} + +func (a *collaborativeAreaMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { + return utils.GenericSearch[*CollaborativeArea](filters, search, (&CollaborativeArea{}).GetObjectFilters(search), + func(d utils.DBObject) utils.ShallowDBObject { + return a.enrich(d.(*CollaborativeArea)) + }, a) } /* sharedWorkspace is a function that shares the collaborative area to the peers */ -func (wfa *collaborativeAreaMongoAccessor) sharedWorkspace(shared *CollaborativeArea, id string) { - eldest, code, _ := wfa.LoadOne(id) // get the eldest +func (a *collaborativeAreaMongoAccessor) sharedWorkspace(shared *CollaborativeArea, id string) { + eldest, code, _ := a.LoadOne(id) // get the eldest if code == 200 { eld := eldest.(*CollaborativeArea) if eld.Workspaces != nil { // update all your workspaces in the eldest by replacing shared ref by an empty string for _, v := range eld.Workspaces { - wfa.workspaceAccessor.UpdateOne(&workspace.Workspace{Shared: ""}, v) - if wfa.Caller != nil || wfa.Caller.URLS == nil || wfa.Caller.URLS[tools.WORKSPACE] == nil { + a.workspaceAccessor.UpdateOne(&workspace.Workspace{Shared: ""}, v) + if a.Caller != nil || a.Caller.URLS == nil || a.Caller.URLS[tools.WORKSPACE] == nil { continue } paccess := (&peer.Peer{}) // send to all peers for k := range shared.AllowedPeersGroup { // delete the collaborative area on the peer - b, err := paccess.LaunchPeerExecution(k, v, tools.WORKSPACE, tools.DELETE, nil, wfa.Caller) + b, err := paccess.LaunchPeerExecution(k, v, tools.WORKSPACE, tools.DELETE, nil, a.Caller) if err != nil && b == nil { - wfa.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) + a.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) } } } @@ -81,8 +164,8 @@ func (wfa *collaborativeAreaMongoAccessor) sharedWorkspace(shared *Collaborative } if shared.Workspaces != nil { for _, v := range shared.Workspaces { // update all the collaborative areas - workspace, code, _ := wfa.workspaceAccessor.UpdateOne(&workspace.Workspace{Shared: shared.UUID}, v) // add the shared ref to workspace - if wfa.Caller != nil || wfa.Caller.URLS == nil || wfa.Caller.URLS[tools.WORKSPACE] == nil { + workspace, code, _ := a.workspaceAccessor.UpdateOne(&workspace.Workspace{Shared: shared.UUID}, v) // add the shared ref to workspace + if a.Caller != nil || a.Caller.URLS == nil || a.Caller.URLS[tools.WORKSPACE] == nil { continue } for k := range shared.AllowedPeersGroup { @@ -92,9 +175,9 @@ func (wfa *collaborativeAreaMongoAccessor) sharedWorkspace(shared *Collaborative paccess := (&peer.Peer{}) // send to all peers, add the collaborative area on the peer s := workspace.Serialize(workspace) s["name"] = fmt.Sprintf("%v", s["name"]) + "_" + k - b, err := paccess.LaunchPeerExecution(k, v, tools.WORKSPACE, tools.POST, s, wfa.Caller) + b, err := paccess.LaunchPeerExecution(k, v, tools.WORKSPACE, tools.POST, s, a.Caller) if err != nil && b == nil { - wfa.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) + a.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) } } } @@ -104,13 +187,13 @@ func (wfa *collaborativeAreaMongoAccessor) sharedWorkspace(shared *Collaborative } // sharedWorkflow is a function that shares the shared workflow to the peers -func (wfa *collaborativeAreaMongoAccessor) sharedWorkflow(shared *CollaborativeArea, id string) { - eldest, code, _ := wfa.LoadOne(id) // get the eldest +func (a *collaborativeAreaMongoAccessor) sharedWorkflow(shared *CollaborativeArea, id string) { + eldest, code, _ := a.LoadOne(id) // get the eldest if code == 200 { eld := eldest.(*CollaborativeArea) if eld.Workflows != nil { for _, v := range eld.Workflows { - data, code, _ := wfa.workflowAccessor.LoadOne(v) + data, code, _ := a.workflowAccessor.LoadOne(v) if code == 200 { s := data.(*w.Workflow) new := []string{} @@ -121,15 +204,15 @@ func (wfa *collaborativeAreaMongoAccessor) sharedWorkflow(shared *CollaborativeA } // kick the shared reference in your old shared workflow n := &w.Workflow{} n.Shared = new - wfa.workflowAccessor.UpdateOne(n, v) - if wfa.Caller != nil || wfa.Caller.URLS == nil || wfa.Caller.URLS[tools.WORKFLOW] == nil { + a.workflowAccessor.UpdateOne(n, v) + if a.Caller != nil || a.Caller.URLS == nil || a.Caller.URLS[tools.WORKFLOW] == nil { continue } paccess := (&peer.Peer{}) // send to all peers for k := range shared.AllowedPeersGroup { // delete the shared workflow on the peer - b, err := paccess.LaunchPeerExecution(k, v, tools.WORKFLOW, tools.DELETE, nil, wfa.Caller) + b, err := paccess.LaunchPeerExecution(k, v, tools.WORKFLOW, tools.DELETE, nil, a.Caller) if err != nil && b == nil { - wfa.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) + a.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) } } } @@ -138,13 +221,13 @@ func (wfa *collaborativeAreaMongoAccessor) sharedWorkflow(shared *CollaborativeA } if shared.Workflows != nil { // update all the shared workflows for _, v := range shared.Workflows { - data, code, _ := wfa.workflowAccessor.LoadOne(v) + data, code, _ := a.workflowAccessor.LoadOne(v) if code == 200 { s := data.(*w.Workflow) if !slices.Contains(s.Shared, id) { s.Shared = append(s.Shared, id) - workflow, code, _ := wfa.workflowAccessor.UpdateOne(s, v) - if wfa.Caller != nil || wfa.Caller.URLS == nil || wfa.Caller.URLS[tools.WORKFLOW] == nil { + workflow, code, _ := a.workflowAccessor.UpdateOne(s, v) + if a.Caller != nil || a.Caller.URLS == nil || a.Caller.URLS[tools.WORKFLOW] == nil { continue } paccess := (&peer.Peer{}) @@ -152,9 +235,9 @@ func (wfa *collaborativeAreaMongoAccessor) sharedWorkflow(shared *CollaborativeA if code == 200 { s := workflow.Serialize(workflow) // add the shared workflow on the peer s["name"] = fmt.Sprintf("%v", s["name"]) + "_" + k - b, err := paccess.LaunchPeerExecution(k, shared.UUID, tools.WORKFLOW, tools.POST, s, wfa.Caller) + b, err := paccess.LaunchPeerExecution(k, shared.UUID, tools.WORKFLOW, tools.POST, s, a.Caller) if err != nil && b == nil { - wfa.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) + a.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) } } } @@ -167,207 +250,29 @@ func (wfa *collaborativeAreaMongoAccessor) sharedWorkflow(shared *CollaborativeA } // sharedWorkspace is a function that shares the collaborative area to the peers -func (wfa *collaborativeAreaMongoAccessor) deleteToPeer(shared *CollaborativeArea) { - if wfa.Caller == nil || wfa.Caller.URLS == nil || wfa.Caller.URLS[tools.COLLABORATIVE_AREA] == nil || wfa.Caller.Disabled { - return - } - paccess := (&peer.Peer{}) - for k, _ := range shared.AllowedPeersGroup { - if ok, _ := (&peer.Peer{AbstractObject: utils.AbstractObject{UUID: k}}).IsMySelf(); ok { - continue - } - b, err := paccess.LaunchPeerExecution(k, shared.UUID, tools.COLLABORATIVE_AREA, tools.DELETE, nil, wfa.Caller) - if err != nil && b == nil { - wfa.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) - } - } +func (a *collaborativeAreaMongoAccessor) deleteToPeer(shared *CollaborativeArea) { + a.contactPeer(shared, tools.POST) } // sharedWorkspace is a function that shares the collaborative area to the peers -func (wfa *collaborativeAreaMongoAccessor) sendToPeer(shared *CollaborativeArea) { - if wfa.Caller == nil || wfa.Caller.URLS == nil || wfa.Caller.URLS[tools.COLLABORATIVE_AREA] == nil || wfa.Caller.Disabled { +func (a *collaborativeAreaMongoAccessor) sendToPeer(shared *CollaborativeArea) { + a.contactPeer(shared, tools.POST) +} + +func (a *collaborativeAreaMongoAccessor) contactPeer(shared *CollaborativeArea, meth tools.METHOD) { + if a.Caller == nil || a.Caller.URLS == nil || a.Caller.URLS[tools.COLLABORATIVE_AREA] == nil || a.Caller.Disabled { return } paccess := (&peer.Peer{}) for k := range shared.AllowedPeersGroup { - if ok, _ := (&peer.Peer{AbstractObject: utils.AbstractObject{UUID: k}}).IsMySelf(); ok || shared.IsSent { + if ok, _ := (&peer.Peer{AbstractObject: utils.AbstractObject{UUID: k}}).IsMySelf(); ok || (shared.IsSent && meth == tools.POST) || (!shared.IsSent && meth != tools.POST) { continue } - shared.IsSent = true - b, err := paccess.LaunchPeerExecution(k, k, tools.COLLABORATIVE_AREA, tools.POST, shared.Serialize(shared), wfa.Caller) + shared.IsSent = meth == tools.POST + b, err := paccess.LaunchPeerExecution(k, k, tools.COLLABORATIVE_AREA, meth, shared.Serialize(shared), a.Caller) if err != nil && b == nil { - wfa.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) + a.Logger.Error().Msg("Could not send to peer " + k + ". Error: " + err.Error()) } } } - -// UpdateOne updates a collaborative area in the database, given its ID and the new data, it automatically share to peers if the workspace is shared -func (wfa *collaborativeAreaMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { - res, code, err := wfa.GenericUpdateOne(set.(*CollaborativeArea).Trim(), id, wfa, &CollaborativeArea{}) - // wfa.deleteToPeer(res.(*CollaborativeArea)) // delete the collaborative area on the peer - wfa.sharedWorkflow(res.(*CollaborativeArea), id) // replace all shared workflows - wfa.sharedWorkspace(res.(*CollaborativeArea), id) // replace all collaborative areas (not shared worspace obj but workspace one) - // wfa.sendToPeer(res.(*CollaborativeArea)) // send the collaborative area (collaborative area object) to the peers - return res, code, err -} - -// StoreOne stores a collaborative area in the database, it automatically share to peers if the workspace is shared -func (wfa *collaborativeAreaMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { - _, id := (&peer.Peer{}).IsMySelf() // get the local peer - data.(*CollaborativeArea).CreatorID = id // set the creator id - // add the creator id to the peers - if config.GetConfig().Whitelist { - data.(*CollaborativeArea).AllowedPeersGroup[id] = []string{"*"} - } else { - data.(*CollaborativeArea).AllowedPeersGroup[id] = []string{} - } - // then reset the shared fields - if data.(*CollaborativeArea).Workspaces == nil { - data.(*CollaborativeArea).Workspaces = []string{} - } - if data.(*CollaborativeArea).Workflows == nil { - data.(*CollaborativeArea).Workflows = []string{} - } - if data.(*CollaborativeArea).Rules == nil { - data.(*CollaborativeArea).Rules = []string{} - } - if data.(*CollaborativeArea).CollaborativeAreaRule == nil { - data.(*CollaborativeArea).CollaborativeAreaRule = &CollaborativeAreaRule{ - ShareMode: "private", - ExploitedBy: "collaborators only", - } - } - data.(*CollaborativeArea).CollaborativeAreaRule.CreatedAt = time.Now().UTC() - // retrieve or proper peer - dd, code, err := wfa.peerAccessor.Search(nil, "0") - if code != 200 || len(dd) == 0 { - return nil, code, errors.New("Could not retrieve the peer" + err.Error()) - } - data.(*CollaborativeArea).CollaborativeAreaRule.Creator = dd[0].GetID() - d, code, err := wfa.GenericStoreOne(data.(*CollaborativeArea).Trim(), wfa) - if code == 200 { - wfa.sharedWorkflow(d.(*CollaborativeArea), d.GetID()) // create all shared workflows - wfa.sharedWorkspace(d.(*CollaborativeArea), d.GetID()) // create all collaborative areas - wfa.sendToPeer(d.(*CollaborativeArea)) // send the collaborative area (collaborative area object) to the peers - } - return data, code, err -} - -// CopyOne copies a CollaborativeArea in the database -func (wfa *collaborativeAreaMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.StoreOne(data) -} - -// enrich is a function that enriches the CollaborativeArea with the shared objects -func (wfa *collaborativeAreaMongoAccessor) enrich(sharedWorkspace *CollaborativeArea) *CollaborativeArea { - res, code, _ := wfa.workspaceAccessor.Search(&dbs.Filters{ - Or: map[string][]dbs.Filter{ - "abstractobject.id": {{Operator: dbs.IN.String(), Value: sharedWorkspace.Workspaces}}, - }, - }, "") - if code == 200 { - for _, r := range res { - sharedWorkspace.SharedWorkspaces = append(sharedWorkspace.SharedWorkspaces, r.(*workspace.Workspace)) - } - } - res, code, _ = wfa.workflowAccessor.Search(&dbs.Filters{ - Or: map[string][]dbs.Filter{ - "abstractobject.id": {{Operator: dbs.IN.String(), Value: sharedWorkspace.Workflows}}, - }, - }, "") - if code == 200 { - for _, r := range res { - sharedWorkspace.SharedWorkflows = append(sharedWorkspace.SharedWorkflows, r.(*w.Workflow)) - } - } - peerskey := []string{} - for k := range sharedWorkspace.AllowedPeersGroup { - peerskey = append(peerskey, k) - } - res, code, _ = wfa.peerAccessor.Search(&dbs.Filters{ - Or: map[string][]dbs.Filter{ - "abstractobject.id": {{Operator: dbs.IN.String(), Value: peerskey}}, - }, - }, "") - if code == 200 { - for _, r := range res { - sharedWorkspace.SharedPeers = append(sharedWorkspace.SharedPeers, r.(*peer.Peer)) - } - } - res, code, _ = wfa.ruleAccessor.Search(&dbs.Filters{ - Or: map[string][]dbs.Filter{ - "abstractobject.id": {{Operator: dbs.IN.String(), Value: sharedWorkspace.Rules}}, - }, - }, "") - if code == 200 { - for _, r := range res { - sharedWorkspace.SharedRules = append(sharedWorkspace.SharedRules, r.(*rule.Rule)) - } - } - return sharedWorkspace -} - -// LoadOne loads a collaborative area from the database, given its ID and enrich it -func (wfa *collaborativeAreaMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { - var sharedWorkspace CollaborativeArea - res_mongo, code, err := mongo.MONGOService.LoadOne(id, wfa.GetType().String()) - if err != nil { - wfa.Logger.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return nil, code, err - } - res_mongo.Decode(&sharedWorkspace) - if !sharedWorkspace.VerifyAuth(wfa.PeerID, wfa.Groups) { - return nil, 403, errors.New("You are not allowed to access this collaborative area") - } - return wfa.enrich(&sharedWorkspace), 200, nil // enrich the collaborative area -} - -// LoadAll loads all the collaborative areas from the database and enrich them -func (wfa collaborativeAreaMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { - objs := []utils.ShallowDBObject{} - res_mongo, code, err := mongo.MONGOService.LoadAll(wfa.GetType().String()) - if err != nil { - wfa.Logger.Error().Msg("Could not retrieve any from db. Error: " + err.Error()) - return nil, code, err - } - var results []CollaborativeArea - if err = res_mongo.All(mongo.MngoCtx, &results); err != nil { - return nil, 404, err - } - for _, r := range results { - if !r.VerifyAuth(wfa.PeerID, wfa.Groups) { - continue - } - objs = append(objs, wfa.enrich(&r)) // enrich the collaborative area - } - return objs, 200, nil -} - -// Search searches for collaborative areas in the database, given some filters OR a search string -func (wfa *collaborativeAreaMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { - objs := []utils.ShallowDBObject{} - if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { - filters = &dbs.Filters{ - Or: map[string][]dbs.Filter{ // search by name only by default can be override - "abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}}, - }, - } - } - res_mongo, code, err := mongo.MONGOService.Search(filters, wfa.GetType().String()) - if err != nil { - wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) - return nil, code, err - } - var results []CollaborativeArea - if err = res_mongo.All(mongo.MngoCtx, &results); err != nil { - return nil, 404, err - } - for _, r := range results { - if !r.VerifyAuth(wfa.PeerID, wfa.Groups) { - continue - } - objs = append(objs, wfa.enrich(&r)) // enrich the collaborative area - } - return objs, 200, nil -} diff --git a/models/collaborative_area/rules/rule/rule_mongo_accessor.go b/models/collaborative_area/rules/rule/rule_mongo_accessor.go index 764a5e9..632715d 100644 --- a/models/collaborative_area/rules/rule/rule_mongo_accessor.go +++ b/models/collaborative_area/rules/rule/rule_mongo_accessor.go @@ -26,30 +26,30 @@ func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCal } // GetType returns the type of the rule -func (wfa *ruleMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { - return wfa.GenericDeleteOne(id, wfa) +func (a *ruleMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { + return utils.GenericDeleteOne(id, a) } // UpdateOne updates a rule in the database -func (wfa *ruleMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { - return wfa.GenericUpdateOne(set.(*Rule), id, wfa, &Rule{}) +func (a *ruleMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { + return utils.GenericUpdateOne(set.(*Rule), id, a, &Rule{}) } // StoreOne stores a rule in the database -func (wfa *ruleMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data.(*Rule), wfa) +func (a *ruleMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { + return utils.GenericStoreOne(data.(*Rule), a) } -func (wfa *ruleMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) +func (a *ruleMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { + return utils.GenericStoreOne(data, a) } // LoadOne loads a rule from the database -func (wfa *ruleMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { +func (a *ruleMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { var rule Rule - res_mongo, code, err := mongo.MONGOService.LoadOne(id, wfa.GetType().String()) + res_mongo, code, err := mongo.MONGOService.LoadOne(id, a.GetType().String()) if err != nil { - wfa.Logger.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) + a.Logger.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) return nil, code, err } res_mongo.Decode(&rule) @@ -57,11 +57,11 @@ func (wfa *ruleMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { } // LoadAll loads all rules from the database -func (wfa ruleMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { +func (a ruleMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - res_mongo, code, err := mongo.MONGOService.LoadAll(wfa.GetType().String()) + res_mongo, code, err := mongo.MONGOService.LoadAll(a.GetType().String()) if err != nil { - wfa.Logger.Error().Msg("Could not retrieve any from db. Error: " + err.Error()) + a.Logger.Error().Msg("Could not retrieve any from db. Error: " + err.Error()) return nil, code, err } var results []Rule @@ -75,7 +75,7 @@ func (wfa ruleMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { } // Search searches for rules in the database, given some filters OR a search string -func (wfa *ruleMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { +func (a *ruleMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { filters = &dbs.Filters{ @@ -84,9 +84,9 @@ func (wfa *ruleMongoAccessor) Search(filters *dbs.Filters, search string) ([]uti }, } } - res_mongo, code, err := mongo.MONGOService.Search(filters, wfa.GetType().String()) + res_mongo, code, err := mongo.MONGOService.Search(filters, a.GetType().String()) if err != nil { - wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) + a.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err } var results []Rule diff --git a/models/collaborative_area/shallow_collaborative_area/shallow_collaborative_area_mongo_accessor.go b/models/collaborative_area/shallow_collaborative_area/shallow_collaborative_area_mongo_accessor.go index 3535d55..3748cba 100644 --- a/models/collaborative_area/shallow_collaborative_area/shallow_collaborative_area_mongo_accessor.go +++ b/models/collaborative_area/shallow_collaborative_area/shallow_collaborative_area_mongo_accessor.go @@ -24,15 +24,15 @@ func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCal } func (a *shallowSharedWorkspaceMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { - return a.GenericDeleteOne(id, a) + return utils.GenericDeleteOne(id, a) } func (a *shallowSharedWorkspaceMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { - return a.GenericUpdateOne(set.(*ShallowCollaborativeArea), id, a, &ShallowCollaborativeArea{}) + return utils.GenericUpdateOne(set.(*ShallowCollaborativeArea), id, a, &ShallowCollaborativeArea{}) } func (a *shallowSharedWorkspaceMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { - return a.GenericStoreOne(data.(*ShallowCollaborativeArea), a) + return utils.GenericStoreOne(data.(*ShallowCollaborativeArea), a) } func (a *shallowSharedWorkspaceMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { diff --git a/models/peer/peer_mongo_accessor.go b/models/peer/peer_mongo_accessor.go index 3f2baf0..5c693ec 100644 --- a/models/peer/peer_mongo_accessor.go +++ b/models/peer/peer_mongo_accessor.go @@ -40,19 +40,19 @@ func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCal */ func (wfa *peerMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { - return wfa.GenericDeleteOne(id, wfa) + return utils.GenericDeleteOne(id, wfa) } func (wfa *peerMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { - return wfa.GenericUpdateOne(set.(*Peer), id, wfa, &Peer{}) + return utils.GenericUpdateOne(set.(*Peer), id, wfa, &Peer{}) } func (wfa *peerMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data.(*Peer), wfa) + return utils.GenericStoreOne(data.(*Peer), wfa) } func (wfa *peerMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) + return utils.GenericStoreOne(data, wfa) } func (dca *peerMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { diff --git a/models/resources/resource_accessor.go b/models/resources/resource_accessor.go index 4d504a6..1b06fd2 100644 --- a/models/resources/resource_accessor.go +++ b/models/resources/resource_accessor.go @@ -33,17 +33,17 @@ func New[T ResourceInterface](t tools.DataType, peerID string, groups []string, */ func (dca *resourceMongoAccessor[T]) DeleteOne(id string) (utils.DBObject, int, error) { - return dca.GenericDeleteOne(id, dca) + return utils.GenericDeleteOne(id, dca) } func (dca *resourceMongoAccessor[T]) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { set.(T).SetResourceModel(nil) - return dca.GenericUpdateOne(set.(T).Trim(), id, dca, dca.generateData()) // TODO CHANGE + return utils.GenericUpdateOne(set.(T).Trim(), id, dca, dca.generateData()) // TODO CHANGE } func (dca *resourceMongoAccessor[T]) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { data.(T).SetResourceModel(nil) - return dca.GenericStoreOne(data.(T).Trim(), dca) + return utils.GenericStoreOne(data.(T).Trim(), dca) } func (dca *resourceMongoAccessor[T]) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { diff --git a/models/resources/resource_model/resource_model.go b/models/resources/resource_model/resource_model.go index f993c42..001d4d4 100644 --- a/models/resources/resource_model/resource_model.go +++ b/models/resources/resource_model/resource_model.go @@ -38,6 +38,10 @@ type AbstractResource struct { Currency string `json:"currency,omitempty" bson:"currency,omitempty"` // Currency is the currency of the price } +func (ao *AbstractResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { + return nil +} + func (abs *AbstractResource) SetResourceModel(model *ResourceModel) { abs.ResourceModel = model } diff --git a/models/resources/resource_model/resource_model_mongo_accessor.go b/models/resources/resource_model/resource_model_mongo_accessor.go index bfa9110..a64e9ff 100644 --- a/models/resources/resource_model/resource_model_mongo_accessor.go +++ b/models/resources/resource_model/resource_model_mongo_accessor.go @@ -25,19 +25,19 @@ func New() *ResourceModelMongoAccessor { } func (wfa *ResourceModelMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { - return wfa.GenericDeleteOne(id, wfa) + return utils.GenericDeleteOne(id, wfa) } func (wfa *ResourceModelMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { - return wfa.GenericUpdateOne(set, id, wfa, &ResourceModel{}) + return utils.GenericUpdateOne(set, id, wfa, &ResourceModel{}) } func (wfa *ResourceModelMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) + return utils.GenericStoreOne(data, wfa) } func (wfa *ResourceModelMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) + return utils.GenericStoreOne(data, wfa) } func (a *ResourceModelMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { diff --git a/models/utils/abstracts.go b/models/utils/abstracts.go index 0ec35b0..bf43a4d 100644 --- a/models/utils/abstracts.go +++ b/models/utils/abstracts.go @@ -30,11 +30,10 @@ type AbstractObject struct { LastPeerWriter string `json:"last_peer_writer" bson:"last_peer_writer"` } -func (ao *AbstractObject) GetObjectFilters(search string) *dbs.Filters { - return &dbs.Filters{ - Or: map[string][]dbs.Filter{ // filter by name if no filters are provided - "abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}}, - }} +func (r *AbstractObject) GenerateID() { + if r.UUID == "" { + r.UUID = uuid.New().String() + } } // GetID implements ShallowDBObject. @@ -52,15 +51,17 @@ func (ao *AbstractObject) UpToDate() { // ao.LastPeerWriter, _ = static.GetMyLocalJsonPeer() } -// GetAccessor returns the accessor of the object (abstract) -func (dma *AbstractObject) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) Accessor { - return nil -} - func (ao *AbstractObject) VerifyAuth(peerID string, groups []string) bool { return true } +func (ao *AbstractObject) GetObjectFilters(search string) *dbs.Filters { + return &dbs.Filters{ + Or: map[string][]dbs.Filter{ // filter by name if no filters are provided + "abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}}, + }} +} + func (dma *AbstractObject) Deserialize(j map[string]interface{}, obj DBObject) DBObject { b, err := json.Marshal(j) if err != nil { @@ -80,12 +81,6 @@ func (dma *AbstractObject) Serialize(obj DBObject) map[string]interface{} { return m } -func (r *AbstractObject) GenerateID() { - if r.UUID == "" { - r.UUID = uuid.New().String() - } -} - type AbstractAccessor struct { Logger zerolog.Logger // Logger is the logger of the accessor, it's a specilized logger for the accessor Type tools.DataType // Type is the data type of the accessor @@ -96,6 +91,16 @@ type AbstractAccessor struct { ResourceModelAccessor Accessor } +func (dma *AbstractAccessor) GetPeerID() string { + return dma.PeerID +} +func (dma *AbstractAccessor) GetGroups() []string { + return dma.Groups +} +func (dma *AbstractAccessor) GetLogger() *zerolog.Logger { + return &dma.Logger +} + func (dma *AbstractAccessor) VerifyAuth() string { return "" } @@ -109,7 +114,7 @@ func (dma *AbstractAccessor) GetCaller() *tools.HTTPCaller { } // GenericLoadOne loads one object from the database (generic) -func (wfa *AbstractAccessor) GenericStoreOne(data DBObject, accessor Accessor) (DBObject, int, error) { +func GenericStoreOne(data DBObject, a Accessor) (DBObject, int, error) { data.GenerateID() f := dbs.Filters{ Or: map[string][]dbs.Filter{ @@ -123,31 +128,31 @@ func (wfa *AbstractAccessor) GenericStoreOne(data DBObject, accessor Accessor) ( }}, }, } - if cursor, _, _ := accessor.Search(&f, ""); len(cursor) > 0 { - return nil, 409, errors.New(accessor.GetType().String() + " with name " + data.GetName() + " already exists") + if cursor, _, _ := a.Search(&f, ""); len(cursor) > 0 { + return nil, 409, errors.New(a.GetType().String() + " with name " + data.GetName() + " already exists") } err := validate.Struct(data) if err != nil { return nil, 422, err } - id, code, err := mongo.MONGOService.StoreOne(data, data.GetID(), wfa.GetType().String()) + id, code, err := mongo.MONGOService.StoreOne(data, data.GetID(), a.GetType().String()) if err != nil { - wfa.Logger.Error().Msg("Could not store " + data.GetName() + " to db. Error: " + err.Error()) + a.GetLogger().Error().Msg("Could not store " + data.GetName() + " to db. Error: " + err.Error()) return nil, code, err } - return accessor.LoadOne(id) + return a.LoadOne(id) } // GenericLoadOne loads one object from the database (generic) -func (dma *AbstractAccessor) GenericDeleteOne(id string, accessor Accessor) (DBObject, int, error) { - res, code, err := accessor.LoadOne(id) +func GenericDeleteOne(id string, a Accessor) (DBObject, int, error) { + res, code, err := a.LoadOne(id) if err != nil { - dma.Logger.Error().Msg("Could not retrieve " + id + " to db. Error: " + err.Error()) + a.GetLogger().Error().Msg("Could not retrieve " + id + " to db. Error: " + err.Error()) return nil, code, err } - _, code, err = mongo.MONGOService.DeleteOne(id, accessor.GetType().String()) + _, code, err = mongo.MONGOService.DeleteOne(id, a.GetType().String()) if err != nil { - dma.Logger.Error().Msg("Could not delete " + id + " to db. Error: " + err.Error()) + a.GetLogger().Error().Msg("Could not delete " + id + " to db. Error: " + err.Error()) return nil, code, err } return res, 200, nil @@ -155,8 +160,8 @@ func (dma *AbstractAccessor) GenericDeleteOne(id string, accessor Accessor) (DBO // GenericLoadOne loads one object from the database (generic) // json expected in entry is a flatted object no need to respect the inheritance hierarchy -func (dma *AbstractAccessor) GenericUpdateOne(set DBObject, id string, accessor Accessor, new DBObject) (DBObject, int, error) { - r, c, err := accessor.LoadOne(id) +func GenericUpdateOne(set DBObject, id string, a Accessor, new DBObject) (DBObject, int, error) { + r, c, err := a.LoadOne(id) if err != nil { return nil, c, err } @@ -166,40 +171,40 @@ func (dma *AbstractAccessor) GenericUpdateOne(set DBObject, id string, accessor for k, v := range change { // apply the changes, with a flatten method loaded[k] = v } - id, code, err := mongo.MONGOService.UpdateOne(new.Deserialize(loaded, new), id, accessor.GetType().String()) + id, code, err := mongo.MONGOService.UpdateOne(new.Deserialize(loaded, new), id, a.GetType().String()) if err != nil { - dma.Logger.Error().Msg("Could not update " + id + " to db. Error: " + err.Error()) + a.GetLogger().Error().Msg("Could not update " + id + " to db. Error: " + err.Error()) return nil, code, err } - return accessor.LoadOne(id) + return a.LoadOne(id) } -func GenericLoadOne[T DBObject](id string, f func(DBObject) (DBObject, int, error), wfa Accessor) (DBObject, int, error) { +func GenericLoadOne[T DBObject](id string, f func(DBObject) (DBObject, int, error), a Accessor) (DBObject, int, error) { var data T - res_mongo, code, err := mongo.MONGOService.LoadOne(id, wfa.GetType().String()) - if !data.VerifyAuth(wfa.GetPeerID(), wfa.GetGroups()) { + res_mongo, code, err := mongo.MONGOService.LoadOne(id, a.GetType().String()) + if !data.VerifyAuth(a.GetPeerID(), a.GetGroups()) { return nil, 403, errors.New("You are not allowed to access this collaborative area") } if err != nil { - wfa.GetLogger().Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) + a.GetLogger().Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) return nil, code, err } res_mongo.Decode(&data) return f(data) } -func genericLoadAll[T DBObject](res *mgb.Cursor, code int, err error, f func(DBObject) ShallowDBObject, wfa Accessor) ([]ShallowDBObject, int, error) { +func genericLoadAll[T DBObject](res *mgb.Cursor, code int, err error, f func(DBObject) ShallowDBObject, a Accessor) ([]ShallowDBObject, int, error) { objs := []ShallowDBObject{} results := []T{} if err != nil { - wfa.GetLogger().Error().Msg("Could not retrieve any from db. Error: " + err.Error()) + a.GetLogger().Error().Msg("Could not retrieve any from db. Error: " + err.Error()) return nil, code, err } if err = res.All(mongo.MngoCtx, &results); err != nil { return nil, 404, err } for _, r := range results { - if !r.VerifyAuth(wfa.GetPeerID(), wfa.GetGroups()) { + if !r.VerifyAuth(a.GetPeerID(), a.GetGroups()) { continue } fmt.Println("results", len(results), f(r)) @@ -224,21 +229,11 @@ func GenericSearch[T DBObject](filters *dbs.Filters, search string, defaultFilte // GenericLoadOne loads one object from the database (generic) // json expected in entry is a flatted object no need to respect the inheritance hierarchy -func (dma *AbstractAccessor) GenericRawUpdateOne(set DBObject, id string, accessor Accessor) (DBObject, int, error) { - id, code, err := mongo.MONGOService.UpdateOne(set, id, accessor.GetType().String()) +func GenericRawUpdateOne(set DBObject, id string, a Accessor) (DBObject, int, error) { + id, code, err := mongo.MONGOService.UpdateOne(set, id, a.GetType().String()) if err != nil { - dma.Logger.Error().Msg("Could not update " + id + " to db. Error: " + err.Error()) + a.GetLogger().Error().Msg("Could not update " + id + " to db. Error: " + err.Error()) return nil, code, err } - return accessor.LoadOne(id) -} - -func (dma *AbstractAccessor) GetPeerID() string { - return dma.PeerID -} -func (dma *AbstractAccessor) GetGroups() []string { - return dma.Groups -} -func (dma *AbstractAccessor) GetLogger() *zerolog.Logger { - return &dma.Logger + return a.LoadOne(id) } diff --git a/models/workflow/workflow_mongo_accessor.go b/models/workflow/workflow_mongo_accessor.go index f7a6eb8..3fe1b30 100644 --- a/models/workflow/workflow_mongo_accessor.go +++ b/models/workflow/workflow_mongo_accessor.go @@ -13,12 +13,11 @@ import ( "cloud.o-forge.io/core/oc-lib/models/collaborative_area/shallow_collaborative_area" "cloud.o-forge.io/core/oc-lib/models/peer" "cloud.o-forge.io/core/oc-lib/models/resources" - "cloud.o-forge.io/core/oc-lib/models/resources/compute" "cloud.o-forge.io/core/oc-lib/models/utils" "cloud.o-forge.io/core/oc-lib/models/workflow_execution" "cloud.o-forge.io/core/oc-lib/models/workspace" "cloud.o-forge.io/core/oc-lib/tools" - cron "github.com/robfig/cron/v3" + cron "github.com/robfig/cron" ) type workflowMongoAccessor struct { @@ -33,7 +32,7 @@ type workflowMongoAccessor struct { // New creates a new instance of the workflowMongoAccessor func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *workflowMongoAccessor { return &workflowMongoAccessor{ - computeResourceAccessor: (&compute.ComputeResource{}).GetAccessor(peerID, groups, nil), + computeResourceAccessor: (&resources.ComputeResource{}).GetAccessor(peerID, groups, nil), collaborativeAreaAccessor: (&shallow_collaborative_area.ShallowCollaborativeArea{}).GetAccessor(peerID, groups, nil), executionAccessor: (&workflow_execution.WorkflowExecution{}).GetAccessor(peerID, groups, nil), workspaceAccessor: (&workspace.Workspace{}).GetAccessor(peerID, groups, nil), @@ -55,7 +54,7 @@ func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCal * getExecutions is a function that returns the executions of a workflow * it returns an array of workflow_execution.WorkflowExecution */ -func (wfa *workflowMongoAccessor) getExecutions(id string, data *Workflow) ([]*workflow_execution.WorkflowExecution, error) { +func (a *workflowMongoAccessor) getExecutions(id string, data *Workflow) ([]*workflow_execution.WorkflowExecution, error) { workflows_execution := []*workflow_execution.WorkflowExecution{} if data.Schedule != nil { // only set execution on a scheduled workflow if data.Schedule.Start == nil { // if no start date, return an error @@ -110,14 +109,14 @@ func (wfa *workflowMongoAccessor) getExecutions(id string, data *Workflow) ([]*w } // DeleteOne deletes a workflow from the database, delete depending executions and bookings -func (wfa *workflowMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { - wfa.execution(id, &Workflow{ +func (a *workflowMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { + a.execution(id, &Workflow{ AbstractWorkflow: AbstractWorkflow{ScheduleActive: false}, }, true) // delete the executions - res, code, err := wfa.GenericDeleteOne(id, wfa) + res, code, err := utils.GenericDeleteOne(id, a) if res != nil && code == 200 { - wfa.execute(res.(*Workflow), true, false) // up to date the workspace for the workflow - wfa.share(res.(*Workflow), true, wfa.Caller) + a.execute(res.(*Workflow), true, false) // up to date the workspace for the workflow + a.share(res.(*Workflow), true, a.Caller) } return res, code, err } @@ -127,15 +126,15 @@ func (wfa *workflowMongoAccessor) DeleteOne(id string) (utils.DBObject, int, err * it takes the workflow id, the real data and the executions * it returns an error if the booking fails */ -func (wfa *workflowMongoAccessor) book(id string, realData *Workflow, execs []*workflow_execution.WorkflowExecution) error { - if wfa.Caller == nil || wfa.Caller.URLS == nil || wfa.Caller.URLS[tools.BOOKING] == nil { +func (a *workflowMongoAccessor) book(id string, realData *Workflow, execs []*workflow_execution.WorkflowExecution) error { + if a.Caller == nil || a.Caller.URLS == nil || a.Caller.URLS[tools.BOOKING] == nil { return errors.New("no caller defined") } - methods := wfa.Caller.URLS[tools.BOOKING] + methods := a.Caller.URLS[tools.BOOKING] if _, ok := methods[tools.POST]; !ok { return errors.New("no path found") } - res, code, _ := wfa.LoadOne(id) + res, code, _ := a.LoadOne(id) if code != 200 { return errors.New("could not load workflow") } @@ -152,7 +151,7 @@ func (wfa *workflowMongoAccessor) book(id string, realData *Workflow, execs []*w continue } // if the compute is already found, skip it isDCFound = append(isDCFound, dc_id) - dc, code, _ := wfa.computeResourceAccessor.LoadOne(dc_id) + dc, code, _ := a.computeResourceAccessor.LoadOne(dc_id) if code != 200 { continue } @@ -167,7 +166,7 @@ func (wfa *workflowMongoAccessor) book(id string, realData *Workflow, execs []*w WorkflowID: id, // set the workflow id "WHO" ResourceID: dc_id, // set the compute id "WHERE" Executions: execs, // set the executions to book "WHAT" - }).Serialize(), wfa.Caller) + }).Serialize(), a.Caller) if err != nil { fmt.Println("BOOKING", err) return err @@ -181,12 +180,12 @@ func (wfa *workflowMongoAccessor) book(id string, realData *Workflow, execs []*w /* * share is a function that shares a workflow to the peers if the workflow is shared */ -func (wfa *workflowMongoAccessor) share(realData *Workflow, delete bool, caller *tools.HTTPCaller) { +func (a *workflowMongoAccessor) share(realData *Workflow, delete bool, caller *tools.HTTPCaller) { if realData == nil || realData.Shared == nil || len(realData.Shared) == 0 || caller == nil || caller.Disabled { // no shared no sharing return } for _, sharedID := range realData.Shared { // loop through the shared ids - res, code, _ := wfa.collaborativeAreaAccessor.LoadOne(sharedID) + res, code, _ := a.collaborativeAreaAccessor.LoadOne(sharedID) if code != 200 { continue } @@ -207,7 +206,7 @@ func (wfa *workflowMongoAccessor) share(realData *Workflow, delete bool, caller } } if err != nil { - wfa.Logger.Error().Msg(err.Error()) + a.Logger.Error().Msg(err.Error()) } } } @@ -215,34 +214,34 @@ func (wfa *workflowMongoAccessor) share(realData *Workflow, delete bool, caller /* * execution is a create or delete function for the workflow executions depending on the schedule of the workflow */ -func (wfa *workflowMongoAccessor) execution(id string, realData *Workflow, delete bool) (int, error) { +func (a *workflowMongoAccessor) execution(id string, realData *Workflow, delete bool) (int, error) { nats := tools.NewNATSCaller() // create a new nats caller because executions are sent to the nats for daemons mongo.MONGOService.DeleteMultiple(map[string]interface{}{ "state": 1, // only delete the scheduled executions only scheduled if executions are in progress or ended, they should not be deleted for registration "workflow_id": id, }, tools.WORKFLOW_EXECUTION.String()) - err := wfa.book(id, realData, []*workflow_execution.WorkflowExecution{}) // delete the booking of the workflow on the peers + err := a.book(id, realData, []*workflow_execution.WorkflowExecution{}) // delete the booking of the workflow on the peers fmt.Println("DELETE BOOKING", err) nats.SetNATSPub(tools.WORKFLOW.String(), tools.REMOVE, realData) // send the deletion to the nats if err != nil { return 409, err } - execs, err := wfa.getExecutions(id, realData) // get the executions of the workflow + execs, err := a.getExecutions(id, realData) // get the executions of the workflow if err != nil { return 422, err } if !realData.ScheduleActive || delete { // if the schedule is not active, delete the executions execs = []*workflow_execution.WorkflowExecution{} } - err = wfa.book(id, realData, execs) // book the workflow on the peers + err = a.book(id, realData, execs) // book the workflow on the peers fmt.Println("BOOKING", err) if err != nil { return 409, err // if the booking fails, return an error for integrity between peers } fmt.Println("BOOKING", delete) for _, obj := range execs { - _, code, err := wfa.executionAccessor.StoreOne(obj) + _, code, err := a.executionAccessor.StoreOne(obj) fmt.Println("EXEC", code, err) if code != 200 { return code, err @@ -253,21 +252,21 @@ func (wfa *workflowMongoAccessor) execution(id string, realData *Workflow, delet } // UpdateOne updates a workflow in the database -func (wfa *workflowMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { - res, code, err := wfa.LoadOne(id) +func (a *workflowMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { + res, code, err := a.LoadOne(id) if code != 200 { return nil, 409, err } // avoid the update if the schedule is the same avoid := set.(*Workflow).Schedule == nil || (res.(*Workflow).Schedule != nil && res.(*Workflow).ScheduleActive == set.(*Workflow).ScheduleActive && res.(*Workflow).Schedule.Start == set.(*Workflow).Schedule.Start && res.(*Workflow).Schedule.End == set.(*Workflow).Schedule.End && res.(*Workflow).Schedule.Cron == set.(*Workflow).Schedule.Cron) - res, code, err = wfa.GenericUpdateOne(set, id, wfa, &Workflow{}) + res, code, err = utils.GenericUpdateOne(set, id, a, &Workflow{}) if code != 200 { return nil, code, err } workflow := res.(*Workflow) if !avoid { // if the schedule is not avoided, update the executions - if code, err := wfa.execution(id, workflow, false); code != 200 { + if code, err := a.execution(id, workflow, false); code != 200 { return nil, code, errors.New("could not update the executions : " + err.Error()) } } @@ -276,16 +275,16 @@ func (wfa *workflowMongoAccessor) UpdateOne(set utils.DBObject, id string) (util now := time.Now().UTC() if (workflow.Schedule.End != nil && now.After(*workflow.Schedule.End)) || (workflow.Schedule.End == nil && workflow.Schedule.Start != nil && now.After(*workflow.Schedule.Start)) { // if the start date is passed, then you can book workflow.ScheduleActive = false - wfa.GenericRawUpdateOne(workflow, id, wfa) + utils.GenericRawUpdateOne(workflow, id, a) } // if the start date is passed, update the executions } - wfa.execute(workflow, false, false) // update the workspace for the workflow - wfa.share(workflow, false, wfa.Caller) // share the update to the peers + a.execute(workflow, false, false) // update the workspace for the workflow + a.share(workflow, false, a.Caller) // share the update to the peers return res, code, nil } // StoreOne stores a workflow in the database -func (wfa *workflowMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { +func (a *workflowMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { d := data.(*Workflow) if d.ScheduleActive && d.Schedule != nil { // if the workflow is scheduled, update the executions now := time.Now().UTC() @@ -293,44 +292,44 @@ func (wfa *workflowMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, d.ScheduleActive = false } // if the start date is passed, update the executions } - res, code, err := wfa.GenericStoreOne(d, wfa) + res, code, err := utils.GenericStoreOne(d, a) if err != nil || code != 200 { return nil, code, err } workflow := res.(*Workflow) - wfa.share(workflow, false, wfa.Caller) // share the creation to the peers + a.share(workflow, false, a.Caller) // share the creation to the peers //store the executions - if code, err := wfa.execution(res.GetID(), workflow, false); err != nil { + if code, err := a.execution(res.GetID(), workflow, false); err != nil { return nil, code, err } - wfa.execute(workflow, false, false) // store the workspace for the workflow + a.execute(workflow, false, false) // store the workspace for the workflow return res, code, nil } // CopyOne copies a workflow in the database -func (wfa *workflowMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) +func (a *workflowMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { + return utils.GenericStoreOne(data, a) } // execute is a function that executes a workflow // it stores the workflow resources in a specific workspace to never have a conflict in UI and logic -func (wfa *workflowMongoAccessor) execute(workflow *Workflow, delete bool, active bool) { +func (a *workflowMongoAccessor) execute(workflow *Workflow, delete bool, active bool) { filters := &dbs.Filters{ Or: map[string][]dbs.Filter{ // filter by standard workspace name attached to a workflow "abstractobject.name": {{Operator: dbs.LIKE.String(), Value: workflow.Name + "_workspace"}}, }, } - resource, _, err := wfa.workspaceAccessor.Search(filters, "") + resource, _, err := a.workspaceAccessor.Search(filters, "") if delete { // if delete is set to true, delete the workspace for _, r := range resource { - wfa.workspaceAccessor.DeleteOne(r.GetID()) + a.workspaceAccessor.DeleteOne(r.GetID()) } return } if err == nil && len(resource) > 0 { // if the workspace already exists, update it - wfa.workspaceAccessor.UpdateOne(&workspace.Workspace{ + a.workspaceAccessor.UpdateOne(&workspace.Workspace{ Active: active, ResourceSet: resources.ResourceSet{ Datas: workflow.Datas, @@ -341,7 +340,7 @@ func (wfa *workflowMongoAccessor) execute(workflow *Workflow, delete bool, activ }, }, resource[0].GetID()) } else { // if the workspace does not exist, create it - wfa.workspaceAccessor.StoreOne(&workspace.Workspace{ + a.workspaceAccessor.StoreOne(&workspace.Workspace{ Active: active, AbstractObject: utils.AbstractObject{Name: workflow.Name + "_workspace"}, ResourceSet: resources.ResourceSet{ @@ -362,7 +361,7 @@ func (a *workflowMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) now := time.Now().UTC() if (w.Schedule.End != nil && now.After(*w.Schedule.End)) || (w.Schedule.End == nil && w.Schedule.Start != nil && now.After(*w.Schedule.Start)) { // if the start date is passed, then you can book w.ScheduleActive = false - a.GenericRawUpdateOne(d, id, a) + utils.GenericRawUpdateOne(d, id, a) } // if the start date is passed, update the executions } a.execute(w, false, true) // if no workspace is attached to the workflow, create it diff --git a/models/workflow_execution/workflow_execution_mongo_accessor.go b/models/workflow_execution/workflow_execution_mongo_accessor.go index d58b6e3..79d7af2 100644 --- a/models/workflow_execution/workflow_execution_mongo_accessor.go +++ b/models/workflow_execution/workflow_execution_mongo_accessor.go @@ -26,26 +26,26 @@ func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCal } func (wfa *workflowExecutionMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { - return wfa.GenericDeleteOne(id, wfa) + return utils.GenericDeleteOne(id, wfa) } func (wfa *workflowExecutionMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { - return wfa.GenericUpdateOne(set, id, wfa, &WorkflowExecution{}) + return utils.GenericUpdateOne(set, id, wfa, &WorkflowExecution{}) } func (wfa *workflowExecutionMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) + return utils.GenericStoreOne(data, wfa) } func (wfa *workflowExecutionMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) + return utils.GenericStoreOne(data, wfa) } func (a *workflowExecutionMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { return utils.GenericLoadOne[*WorkflowExecution](id, func(d utils.DBObject) (utils.DBObject, int, error) { if d.(*WorkflowExecution).State == SCHEDULED && time.Now().UTC().After(*d.(*WorkflowExecution).ExecDate) { d.(*WorkflowExecution).State = FORGOTTEN - a.GenericRawUpdateOne(d, id, a) + utils.GenericRawUpdateOne(d, id, a) } return d, 200, nil }, a) @@ -63,7 +63,7 @@ func (a *workflowExecutionMongoAccessor) getExec() func(utils.DBObject) utils.Sh return func(d utils.DBObject) utils.ShallowDBObject { if d.(*WorkflowExecution).State == SCHEDULED && time.Now().UTC().After(*d.(*WorkflowExecution).ExecDate) { d.(*WorkflowExecution).State = FORGOTTEN - a.GenericRawUpdateOne(d, d.GetID(), a) + utils.GenericRawUpdateOne(d, d.GetID(), a) } return d } diff --git a/models/workspace/workspace_mongo_accessor.go b/models/workspace/workspace_mongo_accessor.go index 2176b96..4a3c6b0 100644 --- a/models/workspace/workspace_mongo_accessor.go +++ b/models/workspace/workspace_mongo_accessor.go @@ -32,56 +32,56 @@ func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCal // DeleteOne deletes a workspace from the database, given its ID, it automatically share to peers if the workspace is shared // it checks if a workspace with the same name already exists -func (wfa *workspaceMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { - res, code, err := wfa.GenericDeleteOne(id, wfa) +func (a *workspaceMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { + res, code, err := utils.GenericDeleteOne(id, a) if code == 200 && res != nil { - wfa.share(res.(*Workspace), tools.DELETE, wfa.Caller) // Share the deletion to the peers + a.share(res.(*Workspace), tools.DELETE, a.Caller) // Share the deletion to the peers } return res, code, err } // UpdateOne updates a workspace in the database, given its ID, it automatically share to peers if the workspace is shared -func (wfa *workspaceMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { +func (a *workspaceMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { d := set.(*Workspace) // Get the workspace from the set d.Clear() if d.Active { // If the workspace is active, deactivate all the other workspaces - res, _, err := wfa.LoadAll() + res, _, err := a.LoadAll() if err == nil { for _, r := range res { if r.GetID() != id { r.(*Workspace).Active = false - wfa.UpdateOne(r.(*Workspace), r.GetID()) + a.UpdateOne(r.(*Workspace), r.GetID()) } } } } - res, code, err := wfa.GenericUpdateOne(set, id, wfa, &Workspace{}) + res, code, err := utils.GenericUpdateOne(set, id, a, &Workspace{}) if code == 200 && res != nil { - wfa.share(res.(*Workspace), tools.PUT, wfa.Caller) + a.share(res.(*Workspace), tools.PUT, a.Caller) } return res, code, err } // StoreOne stores a workspace in the database, it checks if a workspace with the same name already exists -func (wfa *workspaceMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { +func (a *workspaceMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { filters := &dbs.Filters{ Or: map[string][]dbs.Filter{ "abstractobject.name": {{Operator: dbs.LIKE.String(), Value: data.GetName() + "_workspace"}}, }, } - res, _, err := wfa.Search(filters, "") // Search for the workspace - if err == nil && len(res) > 0 { // If the workspace already exists, return an error + res, _, err := a.Search(filters, "") // Search for the workspace + if err == nil && len(res) > 0 { // If the workspace already exists, return an error return nil, 409, errors.New("A workspace with the same name already exists") } // reset the resources d := data.(*Workspace) d.Clear() - return wfa.GenericStoreOne(d, wfa) + return utils.GenericStoreOne(d, a) } // CopyOne copies a workspace in the database -func (wfa *workspaceMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { - return wfa.GenericStoreOne(data, wfa) +func (a *workspaceMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { + return utils.GenericStoreOne(data, a) } func (a *workspaceMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { @@ -91,30 +91,30 @@ func (a *workspaceMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) }, a) } -func (wfa *workspaceMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { +func (a *workspaceMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { return utils.GenericLoadAll[*Workspace](func(d utils.DBObject) utils.ShallowDBObject { - d.(*Workspace).Fill(wfa.PeerID, wfa.Groups) + d.(*Workspace).Fill(a.PeerID, a.Groups) return d - }, wfa) + }, a) } -func (wfa *workspaceMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { +func (a *workspaceMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { return utils.GenericSearch[*Workspace](filters, search, (&Workspace{}).GetObjectFilters(search), func(d utils.DBObject) utils.ShallowDBObject { - d.(*Workspace).Fill(wfa.PeerID, wfa.Groups) + d.(*Workspace).Fill(a.PeerID, a.Groups) return d - }, wfa) + }, a) } /* This function is used to share the workspace with the peers */ -func (wfa *workspaceMongoAccessor) share(realData *Workspace, method tools.METHOD, caller *tools.HTTPCaller) { +func (a *workspaceMongoAccessor) share(realData *Workspace, method tools.METHOD, caller *tools.HTTPCaller) { fmt.Println("Sharing workspace", realData, caller) if realData == nil || realData.Shared == "" || caller == nil || caller.Disabled { return } shallow := &shallow_collaborative_area.ShallowCollaborativeArea{} - access := (shallow).GetAccessor(wfa.PeerID, wfa.Groups, nil) + access := (shallow).GetAccessor(a.PeerID, a.Groups, nil) res, code, _ := access.LoadOne(realData.Shared) if code != 200 { return @@ -135,6 +135,6 @@ func (wfa *workspaceMongoAccessor) share(realData *Workspace, method tools.METHO } } if err != nil { - wfa.Logger.Error().Msg(err.Error()) + a.Logger.Error().Msg(err.Error()) } }