-
Notifications
You must be signed in to change notification settings - Fork 1
/
blockstore.go
107 lines (87 loc) · 2.85 KB
/
blockstore.go
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package auth
import (
"context"
"errors"
blocks "github.com/ipfs/go-block-format"
cid "github.com/ipfs/go-cid"
blockstore "github.com/peergos/go-ipfs-blockstore"
peer "github.com/libp2p/go-libp2p-core/peer"
)
var ErrUnauthorised = errors.New("Unauthorised")
type AuthBlockstore interface {
DeleteBlock(cid.Cid) error
Has(cid.Cid) (bool, error)
Get(cid.Cid, peer.ID, string) (blocks.Block, error)
BloomAdd(cid.Cid) error
// GetSize returns the CIDs mapped BlockSize
GetSize(cid.Cid) (int, error)
// Put puts a given block to the underlying datastore
Put(AuthBlock) error
// PutMany puts a slice of blocks at the same time using batching
// capabilities of the underlying datastore whenever possible.
PutMany([]AuthBlock) error
// AllKeysChan returns a channel from which
// the CIDs in the Blockstore can be read. It should respect
// the given context, closing the channel if it becomes Done.
AllKeysChan(ctx context.Context) (<-chan cid.Cid, error)
// HashOnRead specifies if every read block should be
// rehashed to make sure it matches its CID.
HashOnRead(enabled bool)
}
type AuthedBlockstore struct {
source blockstore.Blockstore
allow func(cid.Cid, []byte, peer.ID, string) bool
AuthBlockstore
}
func NewAuthBlockstore(bstore blockstore.Blockstore, allow func(cid.Cid, []byte, peer.ID, string) bool) AuthBlockstore {
return &AuthedBlockstore{source: bstore, allow: allow}
}
func (bs *AuthedBlockstore) Get(c cid.Cid, remote peer.ID, auth string) (blocks.Block, error) {
local, err := bs.source.Has(c)
if err != nil {
return nil, err
}
if !local {
return nil, blockstore.ErrNotFound
}
block, err := bs.source.Get(c)
if err != nil {
return nil, ErrUnauthorised
}
if bs.allow(c, block.RawData(), remote, auth) {
return block, nil
}
return nil, ErrUnauthorised
}
func (bs *AuthedBlockstore) DeleteBlock(c cid.Cid) error {
return bs.source.DeleteBlock(c)
}
func (bs *AuthedBlockstore) BloomAdd(c cid.Cid) error {
return bs.source.BloomAdd(c)
}
func (bs *AuthedBlockstore) Has(c cid.Cid) (bool, error) {
codec := c.Type()
if codec != cid.Raw && codec != cid.DagCBOR {
return false, nil
}
return bs.source.Has(c)
}
func (bs *AuthedBlockstore) GetSize(c cid.Cid) (int, error) {
return bs.source.GetSize(c)
}
func (bs *AuthedBlockstore) Put(b AuthBlock) error {
return bs.source.Put(b.(AuthBlockImpl).block)
}
func (bs *AuthedBlockstore) PutMany(authblocks []AuthBlock) error {
unwrapped := make([]blocks.Block, len(authblocks))
for i, b := range authblocks {
unwrapped[i] = b.(AuthBlockImpl).block
}
return bs.source.PutMany(unwrapped)
}
func (bs *AuthedBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
return bs.source.AllKeysChan(ctx)
}
func (bs *AuthedBlockstore) HashOnRead(enabled bool) {
bs.source.HashOnRead(enabled)
}