]>
Commit | Line | Data |
---|---|---|
a6dc0bad MT |
1 | #!/usr/bin/python |
2 | ||
c5ddbd67 | 3 | import configparser |
11347e46 | 4 | import io |
7b05edde | 5 | import location |
776e98e6 | 6 | import logging |
59468469 MT |
7 | import ssl |
8 | import tempfile | |
23f84bbc | 9 | import tornado.httpclient |
11347e46 MT |
10 | |
11 | from . import accounts | |
d6c41da2 | 12 | from . import asterisk |
28e09035 | 13 | from . import analytics |
05e8c602 | 14 | from . import blog |
26ccb61a | 15 | from . import bugzilla |
f0a8b392 | 16 | from . import cache |
d73bba54 | 17 | from . import campaigns |
11347e46 | 18 | from . import database |
11347e46 | 19 | from . import fireinfo |
34999287 | 20 | from . import httpclient |
11347e46 | 21 | from . import iuse |
97e15cf6 | 22 | from . import lists |
d6df53bf | 23 | from . import messages |
11347e46 MT |
24 | from . import mirrors |
25 | from . import netboot | |
26 | from . import nopaste | |
372ef119 | 27 | from . import ratelimit |
11347e46 | 28 | from . import releases |
440aba92 | 29 | from . import resolver |
11347e46 | 30 | from . import settings |
66d4b1c1 | 31 | from . import toots |
440aba92 | 32 | from . import util |
181d08f3 | 33 | from . import wiki |
2c361abc | 34 | from . import zeiterfassung |
d6df53bf | 35 | from .decorators import * |
2c361abc | 36 | |
11347e46 | 37 | DEFAULT_CONFIG = io.StringIO(""" |
9ed02e3b MT |
38 | [global] |
39 | debug = false | |
776e98e6 | 40 | environment = testing |
9ed02e3b MT |
41 | |
42 | data_dir = | |
43 | static_dir = %(data_dir)s/static | |
44 | templates_dir = %(data_dir)s/templates | |
45 | """) | |
46 | ||
776e98e6 MT |
47 | # Setup logging |
48 | log = logging.getLogger(__name__) | |
49 | ||
a6dc0bad | 50 | class Backend(object): |
34999287 MT |
51 | version = 0 |
52 | ||
2cd9af74 | 53 | def __init__(self, configfile, debug=False): |
9068dba1 MT |
54 | # Read configuration file. |
55 | self.config = self.read_config(configfile) | |
9ed02e3b MT |
56 | |
57 | # Enable debug logging if configured | |
58 | self.debug = debug or self.config.getboolean("global", "debug") | |
9068dba1 MT |
59 | |
60 | # Setup database. | |
61 | self.setup_database() | |
a6dc0bad | 62 | |
23f84bbc | 63 | # Create HTTPClient |
34999287 MT |
64 | self.http_client = httpclient.HTTPClient(self) |
65 | ||
f0a8b392 MT |
66 | # Initialize the cache |
67 | self.cache = cache.Cache(self) | |
68 | ||
4f043f79 | 69 | # Initialize settings first |
9068dba1 | 70 | self.settings = settings.Settings(self) |
9068dba1 MT |
71 | |
72 | # Initialize backend modules. | |
a6dc0bad | 73 | self.accounts = accounts.Accounts(self) |
28e09035 | 74 | self.analytics = analytics.Analytics(self) |
26ccb61a | 75 | self.bugzilla = bugzilla.Bugzilla(self) |
66862195 | 76 | self.fireinfo = fireinfo.Fireinfo(self) |
9068dba1 MT |
77 | self.iuse = iuse.IUse(self) |
78 | self.mirrors = mirrors.Mirrors(self) | |
79 | self.netboot = netboot.NetBoot(self) | |
66862195 | 80 | self.nopaste = nopaste.Nopaste(self) |
9068dba1 | 81 | self.releases = releases.Releases(self) |
9068dba1 | 82 | |
0a6875dc | 83 | self.blog = blog.Blog(self) |
181d08f3 | 84 | self.wiki = wiki.Wiki(self) |
2c361abc MT |
85 | self.zeiterfassung = zeiterfassung.ZeiterfassungClient(self) |
86 | ||
9068dba1 MT |
87 | def read_config(self, configfile): |
88 | cp = configparser.ConfigParser() | |
9ed02e3b MT |
89 | |
90 | # Initialize configuration with some sensible defaults | |
91 | cp.readfp(DEFAULT_CONFIG) | |
92 | ||
93 | # Parse file | |
9068dba1 MT |
94 | cp.read(configfile) |
95 | ||
96 | return cp | |
97 | ||
776e98e6 MT |
98 | @property |
99 | def environment(self): | |
100 | """ | |
101 | Returns whether this is running in "production" or "testing" | |
102 | """ | |
103 | return self.config.get("global", "environment") | |
104 | ||
9068dba1 MT |
105 | def setup_database(self): |
106 | """ | |
107 | Sets up the database connection. | |
108 | """ | |
109 | credentials = { | |
110 | "host" : self.config.get("database", "server"), | |
111 | "database" : self.config.get("database", "database"), | |
112 | "user" : self.config.get("database", "username"), | |
113 | "password" : self.config.get("database", "password"), | |
114 | } | |
115 | ||
3082f0e9 | 116 | self.db = database.Connection(self, **credentials) |
c5ddbd67 | 117 | |
59468469 MT |
118 | @lazy_property |
119 | def ssl_context(self): | |
120 | # Create SSL context | |
121 | context = ssl.create_default_context() | |
122 | ||
123 | # Fetch client certificate | |
124 | certificate = self.settings.get("client-certificate", None) | |
125 | key = self.settings.get("client-key", None) | |
126 | ||
127 | # Apply client certificate | |
128 | if certificate and key: | |
129 | with tempfile.NamedTemporaryFile(mode="w") as f_cert: | |
130 | f_cert.write(certificate) | |
131 | f_cert.flush() | |
132 | ||
133 | with tempfile.NamedTemporaryFile(mode="w") as f_key: | |
134 | f_key.write(key) | |
135 | f_key.flush() | |
136 | ||
137 | context.load_cert_chain(f_cert.name, f_key.name) | |
138 | ||
139 | return context | |
140 | ||
141 | async def load_certificate(self, certfile, keyfile): | |
142 | with self.db.transaction(): | |
143 | # Load certificate | |
144 | with open(certfile) as f: | |
145 | self.settings.set("client-certificate", f.read()) | |
146 | ||
147 | # Load key file | |
148 | with open(keyfile) as f: | |
149 | self.settings.set("client-key", f.read()) | |
150 | ||
9fdf4fb7 | 151 | async def run_task(self, task, *args, **kwargs): |
c5ddbd67 | 152 | tasks = { |
26ccb61a | 153 | "accounts:delete" : self.accounts._delete, |
aee57270 MT |
154 | "announce-blog-posts" : self.blog.announce, |
155 | "check-mirrors" : self.mirrors.check_all, | |
aee57270 | 156 | "cleanup" : self.cleanup, |
5bfc6729 | 157 | "get-all-emails" : self.accounts.get_all_emails, |
aee57270 | 158 | "launch-campaigns" : self.campaigns.launch_manually, |
59468469 | 159 | "load-certificate" : self.load_certificate, |
aee57270 MT |
160 | "run-campaigns" : self.campaigns.run, |
161 | "scan-files" : self.releases.scan_files, | |
162 | "send-message" : self.messages.send_cli, | |
163 | "send-all-messages" : self.messages.queue.send_all, | |
aee57270 | 164 | "test-ldap" : self.accounts.test_ldap, |
66d4b1c1 | 165 | "toot" : self.toots.toot, |
aee57270 | 166 | "update-blog-feeds" : self.blog.update_feeds, |
c5ddbd67 MT |
167 | } |
168 | ||
169 | # Get the task from the list of all tasks | |
170 | func = tasks.get(task, None) | |
171 | if not func: | |
172 | raise ValueError("Unknown task: %s" % task) | |
173 | ||
776e98e6 MT |
174 | # Check if we are running in production |
175 | if not self.environment == "production": | |
176 | log.warning("Refusing to run task '%s' in '%s' environment" % (task, self.environment)) | |
177 | return | |
178 | ||
c5ddbd67 | 179 | # Run the task |
9fdf4fb7 | 180 | r = await func(*args, **kwargs) |
c5ddbd67 MT |
181 | |
182 | # If any error code has been returned, | |
183 | # we will end the program | |
184 | if r: | |
185 | raise SystemExit(r) | |
d6df53bf | 186 | |
19f8de1b MT |
187 | @lazy_property |
188 | def asterisk(self): | |
189 | return asterisk.Asterisk(self) | |
190 | ||
d73bba54 MT |
191 | @lazy_property |
192 | def campaigns(self): | |
193 | return campaigns.Campaigns(self) | |
194 | ||
d8b04c72 MT |
195 | @lazy_property |
196 | def groups(self): | |
197 | return accounts.Groups(self) | |
198 | ||
97e15cf6 MT |
199 | @lazy_property |
200 | def lists(self): | |
201 | return lists.Lists(self) | |
202 | ||
d6df53bf MT |
203 | @lazy_property |
204 | def messages(self): | |
205 | return messages.Messages(self) | |
611adbfb | 206 | |
7b05edde MT |
207 | @lazy_property |
208 | def location(self): | |
209 | return location.Database("/var/lib/location/database.db") | |
210 | ||
e929ed92 MT |
211 | def get_country_name(self, country_code): |
212 | country = self.location.get_country(country_code) | |
213 | ||
214 | if country: | |
215 | return country.name | |
216 | ||
372ef119 MT |
217 | @lazy_property |
218 | def ratelimiter(self): | |
219 | return ratelimit.RateLimiter(self) | |
220 | ||
440aba92 MT |
221 | @lazy_property |
222 | def resolver(self): | |
223 | return resolver.Resolver(tries=2, timeout=2, domains=[]) | |
224 | ||
611adbfb | 225 | @lazy_property |
66d4b1c1 MT |
226 | def toots(self): |
227 | return toots.Toots(self) | |
8e69850a | 228 | |
9fdf4fb7 | 229 | async def cleanup(self): |
8e69850a MT |
230 | # Cleanup message queue |
231 | with self.db.transaction(): | |
232 | self.messages.queue.cleanup() | |
233 | ||
234 | # Cleanup in accounts | |
235 | with self.db.transaction(): | |
236 | self.accounts.cleanup() | |
063fd092 MT |
237 | |
238 | # Cleanup nopasts | |
239 | with self.db.transaction(): | |
240 | self.nopaste.cleanup() |