summaryrefslogtreecommitdiff
path: root/internal/catalog
diff options
context:
space:
mode:
Diffstat (limited to 'internal/catalog')
-rw-r--r--internal/catalog/catalog.go38
1 files changed, 35 insertions, 3 deletions
diff --git a/internal/catalog/catalog.go b/internal/catalog/catalog.go
index 7966d9a..09a6fba 100644
--- a/internal/catalog/catalog.go
+++ b/internal/catalog/catalog.go
@@ -15,8 +15,9 @@ type Catalog struct {
}
type snapshot struct {
- models map[string]domain.Model
- list []domain.Model
+ models map[string]domain.Model
+ aliases map[string]string
+ list []domain.Model
}
func New(cfg config.Config) *Catalog {
@@ -61,15 +62,19 @@ func NewModels(models []domain.Model) *Catalog {
func (c *Catalog) Replace(source []domain.Model) {
models := make(map[string]domain.Model, len(source))
+ aliases := make(map[string]string)
list := make([]domain.Model, 0, len(source))
for _, sourceModel := range source {
model := sourceModel
model.Routes = append([]domain.Route(nil), sourceModel.Routes...)
models[model.ID] = model
+ for _, alias := range model.Aliases {
+ aliases[alias] = model.ID
+ }
list = append(list, model)
}
sort.Slice(list, func(i, j int) bool { return list[i].ID < list[j].ID })
- c.state.Store(&snapshot{models: models, list: list})
+ c.state.Store(&snapshot{models: models, aliases: aliases, list: list})
}
func (c *Catalog) Model(id string) (domain.Model, error) {
@@ -79,11 +84,38 @@ func (c *Catalog) Model(id string) (domain.Model, error) {
}
model, ok := current.models[id]
if !ok {
+ if canonical, aliasOK := current.aliases[id]; aliasOK {
+ model, ok = current.models[canonical]
+ }
+ }
+ if !ok {
return domain.Model{}, fmt.Errorf("model %q not found", id)
}
return model, nil
}
+func (c *Catalog) ModelForPrincipal(id string, principal domain.Principal) (domain.Model, error) {
+ model, err := c.Model(id)
+ if err != nil {
+ return domain.Model{}, err
+ }
+ if !model.Allows(principal) {
+ return domain.Model{}, fmt.Errorf("model %q not allowed", id)
+ }
+ return model, nil
+}
+
+func (c *Catalog) ModelsFor(protocol domain.Protocol, principal domain.Principal) []domain.Model {
+ models := c.Models(protocol)
+ result := models[:0]
+ for _, model := range models {
+ if model.Allows(principal) {
+ result = append(result, model)
+ }
+ }
+ return result
+}
+
func (c *Catalog) Models(protocol domain.Protocol) []domain.Model {
current := c.state.Load()
if current == nil {