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