safing-portmaster/profile/index/indexer.go
2018-12-07 21:28:45 +01:00

103 lines
2.1 KiB
Go

package index
import (
"github.com/Safing/portbase/database"
"github.com/Safing/portbase/database/query"
"github.com/Safing/portbase/database/record"
"github.com/Safing/portbase/log"
"github.com/Safing/portbase/modules"
"github.com/Safing/portmaster/profile"
)
// FIXME: listen for profile changes and update the index
var (
indexDB = database.NewInterface(&database.Options{
Local: true, // we want to access crownjewel records
AlwaysMakeCrownjewel: true, // never sync the index
})
indexSub *database.Subscription
shutdownIndexer = make(chan struct{})
)
func init() {
modules.Register("profile:index", nil, start, stop, "profile", "database")
}
func start() (err error) {
indexSub, err = indexDB.Subscribe(query.New("core:profiles/user/"))
if err != nil {
return err
}
return nil
}
func stop() error {
close(shutdownIndexer)
indexSub.Cancel()
return nil
}
func indexer() {
for {
select {
case <-shutdownIndexer:
return
case r := <-indexSub.Feed:
if r == nil {
return
}
prof := ensureProfile(r)
if prof != nil {
for _, fp := range prof.Fingerprints {
if fp.MatchesOS() && fp.Type == "full_path" {
// get Profile and ensure identifier is set
pi, err := Get("full_path", fp.Value)
if err != nil {
if err == database.ErrNotFound {
pi = NewIndex(id)
} else {
log.Errorf("profile/index: could not save updated profile index: %s", err)
}
}
if pi.AddUserProfile(prof.ID) {
err := pi.Save()
if err != nil {
log.Errorf("profile/index: could not save updated profile index: %s", err)
}
}
}
}
}
}
}
}
func ensureProfile(r record.Record) *profile.Profile {
// unwrap
if r.IsWrapped() {
// only allocate a new struct, if we need it
new := &profile.Profile{}
err := record.Unwrap(r, new)
if err != nil {
log.Errorf("profile/index: could not unwrap Profile: %s", err)
return nil
}
return new
}
// or adjust type
new, ok := r.(*profile.Profile)
if !ok {
log.Errorf("profile/index: record not of type *Profile, but %T", r)
return nil
}
return new
}