7 from __future__
import annotations
11 from os.path
import dirname, exists, join
12 from typing
import Dict, cast, Optional
14 JsonDict = Dict[str, object]
16 TIME_FORMAT =
"%Y-%m-%d %H:%M:%S"
21 Static configuration provided at startup
25 contributors_file: str,
26 start_time_utc: float,
27 contribution_interval: float,
31 email_server: Optional[str] =
None,
32 email_address: Optional[str] =
None,
33 email_password_file: Optional[str] =
None):
34 if not contributors_file:
35 raise Exception(
"no contributors file specified")
36 if start_time_utc == 0.0:
37 raise Exception(
"invalid start time")
38 if (email_server
or email_address
or email_password_file)
and \
39 (
not (email_server
and email_address
and email_password_file)):
41 "must all or none of email server, address and password file " +
43 if email_password_file
and not exists(email_password_file):
44 raise Exception(f
"no email password file: {email_password_file}")
46 self.contributors_file: str = contributors_file
47 self.start_time_utc: float = float(start_time_utc)
48 self.contribution_interval: float = float(contribution_interval)
49 self.email_server: Optional[str] = email_server
50 self.email_address: Optional[str] = email_address
51 self.email_password_file: Optional[str] = email_password_file
52 self.tls_key: str = tls_key
53 self.tls_certificate: str = tls_certificate
59 Populate contributors field, and other fields with sensible defaults
60 for a configuration template. All fields are expected to be
64 contributors_file=
"contributors.json",
65 start_time_utc=time.time() + 6 * 60 * 60,
66 contribution_interval=24 * 60 * 60,
68 tls_certificate=
"cert.pem",
70 email_server=
"smtp.mymail.com:465",
71 email_address=
"mpc_coordinator@mymail.com",
72 email_password_file=
"password.txt")
79 For the case where ana administrator has a list of contributors (e.g.
80 from an online form) and keys and wants to import it into a
81 server_config.json file. This function writes the contributors
82 correctly, and places dummy data / descriptions in other fields,
83 prefixed with '_', for the admin to fill in later.
89 return Configuration._from_json_dict(json.loads(config_json))
91 def _to_json_dict(self) -> JsonDict:
92 start_time = time.gmtime(self.start_time_utc)
94 "contributors_file": self.contributors_file,
95 "start_time_utc": time.strftime(TIME_FORMAT, start_time),
96 "contribution_interval":
str(self.contribution_interval),
97 "email_server": self.email_server,
98 "email_address": self.email_address,
99 "email_password_file": self.email_password_file,
100 "tls_key": self.tls_key,
101 "tls_certificate": self.tls_certificate,
105 def _to_json_template_dict(self) -> JsonDict:
106 start_time = time.gmtime(self.start_time_utc)
108 "contributors_file": self.contributors_file,
110 "This is a generated template. Populate the fields below, " +
111 "removing _REQUIRED_ and _OPTIONAL_ prefixes as necessary.",
112 "_REQUIRED_start_time_utc": time.strftime(TIME_FORMAT, start_time),
113 "_REQUIRED_contribution_interval":
str(self.contribution_interval),
114 "_OPTIONAL_email_server": self.email_server,
115 "_OPTIONAL_email_address": self.email_address,
116 "_OPTIONAL_email_password_file": self.email_password_file,
117 "_REQUIRED_tls_key": self.tls_key,
118 "_REQUIRED_tls_certificate": self.tls_certificate,
119 "_REQUIRED_port": self.
port,
125 config_path: Optional[str] =
None) -> Configuration:
126 start_time = time.strptime(
127 cast(str, json_dict[
"start_time_utc"]),
129 email_password_file = cast(
130 str, json_dict.get(
"email_password_file",
None))
131 if email_password_file
and config_path:
132 email_password_file = join(dirname(config_path), email_password_file)
134 cast(str, json_dict[
"contributors_file"]),
135 calendar.timegm(start_time),
136 float(cast(str, json_dict[
"contribution_interval"])),
137 email_server=cast(str, json_dict.get(
"email_server",
None)),
138 email_address=cast(str, json_dict.get(
"email_address",
None)),
139 email_password_file=email_password_file,
140 tls_key=cast(str, json_dict[
"tls_key"]),
141 tls_certificate=cast(str, json_dict[
"tls_certificate"]),
142 port=
int(cast(int, json_dict[
"port"])))