aboutsummaryrefslogtreecommitdiff
path: root/types/namespace_pool.go
blob: 1e9e8f67b9878125c6ad79684618cc58a9bee30b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package types

import (
	"fmt"
)

// NamespacePool is a pool of namespaces that contain complete verification keys
type NamespacePool struct {
	pool map[[NamespaceFingerprintSize]byte]*Namespace
	list []*Namespace
	// If we need to update this structure without a restart => add mutex.
}

// NewNameSpacePool creates a new namespace pool from a list of namespaces.  An
// error is returned if there are duplicate namespaces or namespaces without a
// complete verification key.  The latter is determined by namespaceWithKey().
func NewNamespacePool(namespaces []*Namespace) (*NamespacePool, error) {
	np := &NamespacePool{
		pool: make(map[[NamespaceFingerprintSize]byte]*Namespace),
		list: make([]*Namespace, 0),
	}
	for _, namespace := range namespaces {
		if !namespaceWithKey(namespace.Format) {
			return nil, fmt.Errorf("need verification key in namespace pool: %v", namespace.Format)
		}
		fpr, err := namespace.Fingerprint()
		if err != nil {
			return nil, fmt.Errorf("need fingerprint in namespace pool: %v", err)
		}
		if _, ok := np.pool[*fpr]; ok {
			return nil, fmt.Errorf("duplicate namespace: %v", namespace.String())
		}
		np.pool[*fpr] = namespace
		np.list = append(np.list, namespace)
	}
	return np, nil
}

// Find checks if namespace is a member of the namespace pool.
func (np *NamespacePool) Find(namespace *Namespace) (*Namespace, bool) {
	fpr, err := namespace.Fingerprint()
	if err != nil {
		return nil, false
	}
	if _, ok := np.pool[*fpr]; !ok {
		return nil, false
	}
	// If the passed namespace is a key fingerprint the actual key needs to be
	// attached before returning.  Not applicable for Ed25519.  Docdoc later.
	return namespace, true
}

// List returns a copied list of namespaces that is used by this pool.
func (np *NamespacePool) List() []*Namespace {
	namespaces := make([]*Namespace, len(np.list))
	copy(namespaces, np.list)
	return namespaces
}

// namespaceWithKey returns true if a namespace format contains a complete
// verification key.  I.e., some formats might have a key fingerprint instead.
func namespaceWithKey(format NamespaceFormat) bool {
	switch format {
	case NamespaceFormatEd25519V1:
		return true
	default:
		return false
	}
}