"src/_zkapauthorizer/_storage_client.py" did not exist on "7898595eac3e7c55c7ce1f28bfd4013f01bd24a7"
Newer
Older
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
108
109
110
111
112
113
114
115
116
117
118
119
120
# Copyright 2019 PrivateStorage.io, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This module implements models (in the MVC sense) for the client side of
the storage plugin.
"""
from os import (
makedirs,
)
from errno import (
EEXIST,
)
from json import (
loads,
dumps,
)
import attr
# XXX
from allmydata.node import (
_Config,
MissingConfigEntry,
)
class StoreAddError(Exception):
def __init__(self, reason):
self.reason = reason
class StoreDirectoryError(Exception):
def __init__(self, reason):
self.reason = reason
@attr.s(frozen=True)
class PaymentReferenceStore(object):
"""
This class implements persistence for payment references.
:ivar _Config node_config: The Tahoe-LAFS node configuration object for
the node that owns the persisted payment preferences.
"""
_CONFIG_DIR = u"privatestorageio-satauthz-v1"
node_config = attr.ib(type=_Config)
def _config_key(self, prn):
return u"{}/{}.prn+json".format(self._CONFIG_DIR, prn)
def _read_pr_json(self, prn):
private_config_item = self._config_key(prn)
try:
return self.node_config.get_private_config(private_config_item)
except MissingConfigEntry:
raise KeyError(prn)
def _write_pr_json(self, prn, pr_json):
private_config_item = self._config_key(prn)
# XXX Need an API to be able to avoid touching the filesystem directly
# here.
container = self.node_config.get_private_path(self._CONFIG_DIR)
try:
makedirs(container)
except EnvironmentError as e:
if EEXIST != e.errno:
raise StoreDirectoryError(e)
try:
self.node_config.write_private_config(private_config_item, pr_json)
except Exception as e:
raise StoreAddError(e)
def get(self, prn):
payment_reference_json = self._read_pr_json(prn)
return PaymentReference.from_json(payment_reference_json)
def add(self, prn):
# XXX Not *exactly* atomic is it? Probably want a
# write_private_config_if_not_exists or something.
try:
self._read_pr_json(prn)
except KeyError:
self._write_pr_json(prn, PaymentReference(prn).to_json())
@attr.s
class PaymentReference(object):
number = attr.ib()
@classmethod
def from_json(cls, json):
values = loads(json)
version = values.pop(u"version")
return getattr(cls, "from_json_v{}".format(version))(values)
@classmethod
def from_json_v1(cls, values):
return cls(**values)
def to_json(self):
return dumps(self.to_json_v1())
def to_json_v1(self):
result = attr.asdict(self)
result[u"version"] = 1
return result