diff --git a/engine/cache/cache.go b/engine/cache/cache.go index b42137c41..e335d090d 100644 --- a/engine/cache/cache.go +++ b/engine/cache/cache.go @@ -5,18 +5,133 @@ package cache import ( + "errors" + "sync" + "time" + + assetdb "github.com/owasp-amass/asset-db" + "github.com/owasp-amass/asset-db/repository" + "github.com/owasp-amass/asset-db/repository/sqlrepo" "github.com/owasp-amass/asset-db/types" oam "github.com/owasp-amass/open-asset-model" ) -type Cache interface { - GetAsset(a oam.Asset) (*types.Asset, bool) - GetAssetsByType(t oam.AssetType) ([]*types.Asset, bool) - SetAsset(a *types.Asset) - GetRelations(r *types.Relation) ([]*types.Relation, bool) - GetRelationsByType(rtype string) ([]*types.Relation, bool) - GetIncomingRelations(asset *types.Asset, relationTypes ...string) ([]*types.Relation, bool) - GetOutgoingRelations(asset *types.Asset, relationTypes ...string) ([]*types.Relation, bool) - SetRelation(r *types.Relation) - Close() +type Cache struct { + sync.Mutex + cache repository.Repository + db repository.Repository +} + +func New(database repository.Repository) (repository.Repository, error) { + if c := assetdb.New(sqlrepo.SQLiteMemory, ""); c != nil { + return &Cache{ + cache: c, + db: database, + }, nil + } + return nil, errors.New("failed to create the cache repository") +} + +// Close implements the Repository interface. +func (c *Cache) Close() error { + c.Lock() + defer c.Unlock() + + if c.cache != nil { + if err := c.cache.Close(); err != nil { + return err + } + } + + return nil +} + +// GetDBType implements the Repository interface. +func (c *Cache) GetDBType() string { + return c.db.GetDBType() +} + +// CreateEntity implements the Repository interface. +func (c *Cache) CreateEntity(asset oam.Asset) (*types.Entity, error) { + +} + +// UpdateEntityLastSeen implements the Repository interface. +func (c *Cache) UpdateEntityLastSeen(id string) error { + +} + +// DeleteEntity implements the Repository interface. +func (c *Cache) DeleteEntity(id string) error { + +} + +// DeleteEdge implements the Repository interface. +func (c *Cache) DeleteEdge(id string) error { + +} + +// FindEntityById implements the Repository interface. +func (c *Cache) FindEntityById(id string) (*types.Entity, error) { + +} + +// FindEntityByContent implements the Repository interface. +func (c *Cache) FindEntityByContent(asset oam.Asset, since time.Time) ([]*types.Entity, error) { + +} + +// FindEntitiesByType implements the Repository interface. +func (c *Cache) FindEntitiesByType(atype oam.AssetType, since time.Time) ([]*types.Entity, error) { + +} + +// FindEntitiesByScope implements the Repository interface. +func (c *Cache) FindEntitiesByScope(constraints []oam.Asset, since time.Time) ([]*types.Entity, error) { + +} + +// Link implements the Repository interface. +func (c *Cache) Link(edge *types.Edge) (*types.Edge, error) { + +} + +// IncomingEdges implements the Repository interface. +func (c *Cache) IncomingEdges(entity *types.Entity, since time.Time, labels ...string) ([]*types.Edge, error) { + +} + +// OutgoingEdges implements the Repository interface. +func (c *Cache) OutgoingEdges(entity *types.Entity, since time.Time, labels ...string) ([]*types.Edge, error) { + +} + +// CreateEntityTag implements the Repository interface. +func (c *Cache) CreateEntityTag(entity *types.Entity, property oam.Property) (*types.EntityTag, error) { + +} + +// GetEntityTags implements the Repository interface. +func (c *Cache) GetEntityTags(entity *types.Entity, since time.Time, names ...string) ([]*types.EntityTag, error) { + +} + +// DeleteEntityTag implements the Repository interface. +func (c *Cache) DeleteEntityTag(id string) error { + +} + +// CreateEdgeTag implements the Repository interface. +func (c *Cache) CreateEdgeTag(edge *types.Edge, property oam.Property) (*types.EdgeTag, error) { + +} + +// GetEdgeTags implements the Repository interface. +func (c *Cache) GetEdgeTags(edge *types.Edge, since time.Time, names ...string) ([]*types.EdgeTag, error) { + +} + +// DeleteEdgeTag implements the Repository interface. +func (c *Cache) DeleteEdgeTag(id string) error { + } diff --git a/engine/cache/oam_cache.go b/engine/cache/oam_cache.go deleted file mode 100644 index d8e6394f0..000000000 --- a/engine/cache/oam_cache.go +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright © by Jeff Foley 2017-2024. All rights reserved. -// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. -// SPDX-License-Identifier: Apache-2.0 - -package cache - -import ( - "sync" - - "github.com/owasp-amass/asset-db/types" - oam "github.com/owasp-amass/open-asset-model" -) - -type relations struct { - all []*types.Relation - froms map[string][]*types.Relation - tos map[string][]*types.Relation -} - -type OAMCache struct { - sync.Mutex - cache Cache - assets map[string]map[string]*types.Asset - relations map[string]*relations -} - -func NewOAMCache(c Cache) Cache { - return &OAMCache{ - cache: c, - assets: make(map[string]map[string]*types.Asset), - relations: make(map[string]*relations), - } -} - -func (c *OAMCache) Close() { - c.Lock() - defer c.Unlock() - - if c.cache != nil { - c.cache.Close() - } - - for k := range c.assets { - clear(c.assets[k]) - } - clear(c.assets) - clear(c.relations) -} - -func (c *OAMCache) GetAsset(a oam.Asset) (*types.Asset, bool) { - key := a.Key() - if key == "" { - return nil, false - } - - c.Lock() - t := string(a.AssetType()) - if m, found := c.assets[t]; found { - if v, found := m[key]; found { - c.Unlock() - return v, true - } - } - c.Unlock() - - if c.cache != nil { - if v, hit := c.cache.GetAsset(a); v != nil && hit { - c.SetAsset(v) - return v, false - } - } - return nil, false -} - -func (c *OAMCache) GetAssetsByType(t oam.AssetType) ([]*types.Asset, bool) { - c.Lock() - defer c.Unlock() - - var results []*types.Asset - if set, found := c.assets[string(t)]; found { - for _, v := range set { - results = append(results, v) - } - } - - if len(results) == 0 { - return nil, false - } - return results, true -} - -func (c *OAMCache) SetAsset(a *types.Asset) { - key := a.Asset.Key() - if key == "" { - return - } - - c.Lock() - defer c.Unlock() - - t := string(a.Asset.AssetType()) - if _, found := c.assets[t]; !found { - c.assets[t] = make(map[string]*types.Asset) - } - c.assets[t][key] = a -} - -func (c *OAMCache) GetRelations(r *types.Relation) ([]*types.Relation, bool) { - c.Lock() - if c.relations[r.Type] == nil || (r.FromAsset == nil && r.ToAsset == nil) { - c.Unlock() - return nil, false - } - - var relations []*types.Relation - if r.FromAsset != nil && r.ToAsset == nil && len(c.relations[r.Type].froms) > 0 { - if rels, found := c.relations[r.Type].froms[r.FromAsset.ID]; found && len(rels) > 0 { - relations = append(relations, rels...) - } - } else if r.FromAsset == nil && r.ToAsset != nil && len(c.relations[r.Type].tos) > 0 { - if rels, found := c.relations[r.Type].tos[r.ToAsset.ID]; found && len(rels) > 0 { - relations = append(relations, rels...) - } - } else { - for _, rel := range c.relations[r.Type].all { - if r.FromAsset == rel.FromAsset && r.ToAsset == rel.ToAsset { - relations = append(relations, rel) - } - } - } - c.Unlock() - - if len(relations) > 0 { - return relations, true - } - - if c.cache != nil { - if rels, hit := c.cache.GetRelations(r); hit && len(rels) > 0 { - for _, relation := range rels { - c.SetRelation(relation) - } - return rels, false - } - } - return nil, false -} - -func (c *OAMCache) GetRelationsByType(rtype string) ([]*types.Relation, bool) { - c.Lock() - defer c.Unlock() - - if r := c.relations[rtype]; r != nil && len(r.all) > 0 { - return r.all, true - } - return nil, false -} - -func (c *OAMCache) GetIncomingRelations(asset *types.Asset, relationTypes ...string) ([]*types.Relation, bool) { - var results []*types.Relation - if asset == nil { - return results, false - } - - c.Lock() - defer c.Unlock() - - if len(relationTypes) == 0 { - for k := range c.relations { - if r, found := c.relations[k]; found && r != nil { - if rels, found := r.tos[asset.ID]; found && len(rels) > 0 { - results = append(results, rels...) - } - } - } - } else { - for _, rel := range relationTypes { - if r, found := c.relations[rel]; found && r != nil { - if rels, found := r.tos[asset.ID]; found && len(rels) > 0 { - results = append(results, rels...) - } - } - } - } - - var hit bool - if len(results) > 0 { - hit = true - } - return results, hit -} - -func (c *OAMCache) GetOutgoingRelations(asset *types.Asset, relationTypes ...string) ([]*types.Relation, bool) { - var results []*types.Relation - if asset == nil { - return results, false - } - - c.Lock() - defer c.Unlock() - - if len(relationTypes) == 0 { - for k := range c.relations { - if r, found := c.relations[k]; found && r != nil { - if rels, found := r.froms[asset.ID]; found && len(rels) > 0 { - results = append(results, rels...) - } - } - } - } else { - for _, rel := range relationTypes { - if r, found := c.relations[rel]; found && r != nil { - if rels, found := r.froms[asset.ID]; found && len(rels) > 0 { - results = append(results, rels...) - } - } - } - } - - var hit bool - if len(results) > 0 { - hit = true - } - return results, hit -} - -func (c *OAMCache) SetRelation(r *types.Relation) { - c.Lock() - defer c.Unlock() - - if _, found := c.relations[r.Type]; !found { - c.relations[r.Type] = &relations{ - froms: make(map[string][]*types.Relation), - tos: make(map[string][]*types.Relation), - } - } - - tokey := r.ToAsset.ID - fromkey := r.FromAsset.ID - // check for duplicate entries - if _, found := c.relations[r.Type].froms[fromkey]; found { - for _, rel := range c.relations[r.Type].froms[fromkey] { - if rel.ToAsset.ID == tokey { - return - } - } - } - - c.relations[r.Type].all = append(c.relations[r.Type].all, r) - c.relations[r.Type].tos[tokey] = append(c.relations[r.Type].tos[tokey], r) - c.relations[r.Type].froms[fromkey] = append(c.relations[r.Type].froms[fromkey], r) -} diff --git a/go.mod b/go.mod index 6d473b5f7..88a015a90 100644 --- a/go.mod +++ b/go.mod @@ -25,8 +25,8 @@ require ( github.com/miekg/dns v1.1.62 github.com/nyaruka/phonenumbers v1.4.1 github.com/openrdap/rdap v0.9.1 - github.com/owasp-amass/asset-db v0.9.0 - github.com/owasp-amass/open-asset-model v0.9.1 + github.com/owasp-amass/asset-db v0.10.1 + github.com/owasp-amass/open-asset-model v0.12.0 github.com/owasp-amass/resolve v0.8.1 github.com/rubenv/sql-migrate v1.7.0 github.com/samber/slog-common v0.17.1