package bm import ( "context" "time" "git.golem15.com/golem15/summercms/modules/lighthouse" "git.golem15.com/jakub/sm-bm-plugin/classes" "git.golem15.com/jakub/sm-bm-plugin/controllers/api" "gorm.io/gorm" ) // registerMaterialsRealtime registers the authorizer of the materials // namespace: channel materials:{id} carries the live revision heads-up of // one material (D-20) and is open only to whoever may manage it. func (p *Plugin) registerMaterialsRealtime(svc *lighthouse.Service) error { return svc.Registry().Register(classes.MaterialsNamespace, lighthouse.AuthorizerFunc(p.authorizeMaterial)) } // authorizeMaterial allows a subscribe to materials:{id} only when the // material is visible to the user and they may manage it (jz.bm.access_materials // and its author, or any such user while it has no author). It checks the // current state on every subscribe. The deny reasons are for the logs. func (p *Plugin) authorizeMaterial(ctx context.Context, userID uint, channel string) lighthouse.Result { id, ok := classes.MaterialChannelID(channel) if !ok { return lighthouse.Denied("malformed material channel") } db := p.database() if db == nil { return lighthouse.Denied("database unavailable") } allowed, err := p.canWatchMaterial(ctx, db, userID, id) if err != nil { return lighthouse.Denied("material lookup failed") } if !allowed { return lighthouse.Denied("not the material's manager") } return lighthouse.Allowed(nil) } // canWatchMaterial runs the watchMaterial seam, or api.CanWatchMaterial at // the current time by default. func (p *Plugin) canWatchMaterial(ctx context.Context, db *gorm.DB, userID, id uint) (bool, error) { if p.watchMaterial != nil { return p.watchMaterial(ctx, db, userID, id) } return api.CanWatchMaterial(ctx, db, time.Now(), userID, id) }