]> git.ipfire.org Git - ipfire.org.git/blame - src/web/__init__.py
asterisk: Create a unified method to fetch objects
[ipfire.org.git] / src / web / __init__.py
CommitLineData
81675874 1#/usr/bin/python
2
feb02477 3import logging
81675874 4import os.path
c01ad253 5import phonenumbers
e96e445b 6import phonenumbers.geocoder
81675874 7import tornado.locale
a49b5422 8import tornado.options
81675874 9import tornado.web
10
a95c2f97 11import ipfire
574a88c7 12import ipfire.countries
440aba92 13from .. import util
feb02477 14
11347e46 15from .handlers import *
81675874 16
08df6527 17from . import auth
12e5de7e 18from . import blog
f301d952 19from . import boot
1958a22b 20from . import docs
c7bcb9ca 21from . import donate
aec63a26 22from . import downloads
96c9bb79 23from . import fireinfo
699a0911 24from . import iuse
f5b01fc2 25from . import location
a41085fb 26from . import nopaste
03706893 27from . import people
df6180a5 28from . import ui_modules
b01a1ee3 29from . import users
4235ba55 30from . import voip
181d08f3 31from . import wiki
12e5de7e 32
81675874 33class Application(tornado.web.Application):
3e7c6ccd
MT
34 def __init__(self, config, **kwargs):
35 # Initialize backend
a95c2f97 36 self.backend = ipfire.Backend(config)
a6dc0bad 37
9ed02e3b
MT
38 settings = {
39 # Do not compress responses
40 "gzip" : False,
41
42 # Enable XSRF cookies
43 "xsrf_cookies" : True,
44
45 # Login
46 "login_url" : "/login",
47
48 # Setup directory structure
49 "static_path" : self.backend.config.get("global", "static_dir"),
50 "template_path" : self.backend.config.get("global", "templates_dir"),
51
eabe6b8d 52 # UI Methods
9ed02e3b 53 "ui_methods" : {
574a88c7 54 "format_country_name" : self.format_country_name,
6eddfb50 55 "format_language_name" : self.format_language_name,
e96e445b
MT
56 "format_month_name" : self.format_month_name,
57 "format_phone_number" : self.format_phone_number,
58 "format_phone_number_to_e164" : self.format_phone_number_to_e164,
59 "format_phone_number_location" : self.format_phone_number_location,
cc3b928d 60 },
eabe6b8d
MT
61
62 # UI Modules
9ed02e3b 63 "ui_modules" : {
f5b01fc2 64 # Blog
7e64f6a3
MT
65 "BlogHistoryNavigation": blog.HistoryNavigationModule,
66 "BlogList" : blog.ListModule,
f91dfcc7
MT
67 "BlogPost" : blog.PostModule,
68
93feb275
MT
69 # Boot
70 "BootMenuConfig" : boot.MenuConfigModule,
71 "BootMenuHeader" : boot.MenuHeaderModule,
72 "BootMenuSeparator" : boot.MenuSeparatorModule,
73
cf59466c
MT
74 # Docs
75 "DocsHeader" : docs.HeaderModule,
76
eabe6b8d 77 # People
b5e2077f 78 "Password" : people.PasswordModule,
917434b8 79
e1814f16
MT
80 # Nopaste
81 "Code" : nopaste.CodeModule,
82
23f0179e 83 # Fireinfo
96c9bb79 84 "FireinfoDeviceTable" : fireinfo.DeviceTableModule,
eabe6b8d
MT
85 "FireinfoDeviceAndGroupsTable"
86 : fireinfo.DeviceAndGroupsTableModule,
87
beb13102
MT
88 # Users
89 "UsersList" : users.ListModule,
90
4235ba55 91 # VoIP
00465786
MT
92 "VoIPOutboundRegistrations" :
93 voip.OutboundRegistrationsModule,
8e93325b 94 "VoIPQueues" : voip.QueuesModule,
4235ba55
MT
95 "VoIPRegistrations" : voip.RegistrationsModule,
96
6ac7e934 97 # Wiki
c21ffadb 98 "WikiDiff" : wiki.WikiDiffModule,
f9db574a 99 "WikiList" : wiki.WikiListModule,
6ac7e934 100
eabe6b8d 101 # Misc
6563eb49 102 "ChristmasBanner" : ui_modules.ChristmasBannerModule,
1c4522dc 103 "Markdown" : ui_modules.MarkdownModule,
eabe6b8d
MT
104 "Map" : ui_modules.MapModule,
105 "ProgressBar" : ui_modules.ProgressBarModule,
81675874 106 },
3403dc5e
MT
107
108 # Call this when a page wasn't found
b22bc8e8 109 "default_handler_class" : base.NotFoundHandler,
9ed02e3b 110 }
9068dba1 111 settings.update(kwargs)
5cf160e0 112
ae0228e1
MT
113 tornado.web.Application.__init__(self, **settings)
114
66862195 115 authentication_handlers = [
08df6527
MT
116 (r"/login", auth.LoginHandler),
117 (r"/logout", auth.LogoutHandler),
66862195
MT
118 ]
119
c85f80e2 120 self.add_handlers(r"(www\.)?([a-z]+\.dev\.)?ipfire\.org", [
940227cb
MT
121 # Entry site that lead the user to index
122 (r"/", IndexHandler),
940227cb 123
8505c8cd
MT
124 # Authentication
125 (r"/login", auth.LoginHandler),
126 (r"/logout", auth.LogoutHandler),
127 (r"/register", auth.RegisterHandler),
128
34472923
MT
129 # Blog
130 (r"/blog", blog.IndexHandler),
131 (r"/blog/authors/(\w+)", blog.AuthorHandler),
132 (r"/blog/compose", blog.ComposeHandler),
133 (r"/blog/drafts", blog.DraftsHandler),
134 (r"/blog/feed.xml", blog.FeedHandler),
135 (r"/blog/search", blog.SearchHandler),
136 (r"/blog/tags/([0-9a-z\-\.]+)", blog.TagHandler),
feb245e0 137 (r"/blog/years/([0-9]{4})", blog.YearHandler),
34472923
MT
138 (r"/blog/([0-9a-z\-\._]+)", blog.PostHandler),
139 (r"/blog/([0-9a-z\-\._]+)/delete", blog.DeleteHandler),
140 (r"/blog/([0-9a-z\-\._]+)/edit", blog.EditHandler),
141 (r"/blog/([0-9a-z\-\._]+)/publish", blog.PublishHandler),
142
1958a22b 143 # Docs
4a1bfdd5 144 (r"/docs((?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))$", docs.FileHandler),
1958a22b
MT
145 (r"/docs([A-Za-z0-9\-_\/]+)?", docs.PageHandler),
146
aec63a26
MT
147 # Downloads
148 (r"/downloads", downloads.IndexHandler),
149 (r"/downloads/mirrors", downloads.MirrorsHandler),
150 (r"/downloads/thank-you", downloads.ThankYouHandler),
151 (r"/downloads/([0-9a-z\-\.]+)", downloads.ReleaseHandler),
152
e64ce07e 153 # Donate
c7bcb9ca
MT
154 (r"/donate", donate.DonateHandler),
155 (r"/donate/thank-you", donate.ThankYouHandler),
156 (r"/donate/error", donate.ErrorHandler),
8d48f4ef 157
8066a1e7
MT
158 # Password Reset
159 (r"/password\-reset", auth.PasswordResetInitiationHandler),
160 (r"/password\-reset/([a-z_][a-z0-9_-]{0,31})/(\w+)", auth.PasswordResetHandler),
161
2fe1d960
MT
162 # Single-Sign-On for Discourse
163 (r"/sso/discourse", auth.SSODiscourse),
164
f2c38da0
MT
165 # User Groups
166 (r"/users/groups", users.GroupIndexHandler),
167 (r"/users/groups/([a-z_][a-z0-9_-]{0,31})", users.GroupShowHandler),
168
b01a1ee3 169 # Users
beb13102 170 (r"/users", users.IndexHandler),
53b2117f
MT
171 (r"/users/([a-z_][a-z0-9_-]{0,31})", users.ShowHandler),
172 (r"/users/([a-z_][a-z0-9_-]{0,31})\.jpg", users.AvatarHandler),
1cd4d7d3 173 (r"/users/([a-z_][a-z0-9_-]{0,31})/delete", users.DeleteHandler),
3c986f14 174 (r"/users/([a-z_][a-z0-9_-]{0,31})/edit", users.EditHandler),
e4d2f51f 175 (r"/users/([a-z_][a-z0-9_-]{0,31})/passwd", users.PasswdHandler),
b01a1ee3 176
4235ba55
MT
177 # VoIP
178 (r"/voip", voip.IndexHandler),
179
45592df5 180 # Static Pages
8ea3eaa2 181 (r"/about", StaticHandler, { "template" : "about.html" }),
45592df5 182 (r"/legal", StaticHandler, { "template" : "legal.html" }),
d2000918 183 (r"/help", StaticHandler, { "template" : "help.html" }),
45592df5 184
14cd4fa8 185 # Handle old pages that have moved elsewhere
7fa7d38d
MT
186 (r"/donation", tornado.web.RedirectHandler, { "url" : "/donate" }),
187 (r"/download", tornado.web.RedirectHandler, { "url" : "/downloads" }),
188 (r"/download/([0-9a-z\-\.]+)", tornado.web.RedirectHandler, { "url" : "/downloads/{0}" }),
85c977e2 189 (r"/features", tornado.web.RedirectHandler, { "url" : "/about" }),
14cd4fa8 190 (r"/imprint", tornado.web.RedirectHandler, { "url" : "/legal" }),
7fa7d38d
MT
191 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "/blog/feed.xml" }),
192 (r"/news/(.*)", tornado.web.RedirectHandler, { "url" : "/blog/{0}" }),
d2000918 193 (r"/support", tornado.web.RedirectHandler, { "url" : "/help"}),
7fa7d38d 194 (r"/(de|en)/(.*)", tornado.web.RedirectHandler, { "url" : "/{0}"}),
37ed7c3c
MT
195
196 # Export arbitrary error pages
b22bc8e8 197 (r"/error/([45][0-9]{2})", base.ErrorHandler),
0ed3ea5c
MT
198
199 # Serve any static files
200 (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
940227cb
MT
201 ])
202
34472923 203 # blog.ipfire.org - LEGACY REDIRECTION
c85f80e2 204 self.add_handlers(r"blog\.([a-z]+\.dev\.)?ipfire\.org", [
34472923
MT
205 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog" }),
206 (r"/authors/(\w+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/authors/{0}" }),
207 (r"/post/([0-9a-z\-\._]+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/{0}" }),
208 (r"/tags/([0-9a-z\-\.]+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/tags/{0}" }),
f0714277
MT
209
210 # RSS Feed
34472923
MT
211 (r"/feed.xml", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/feed.xml" }),
212 ])
12e5de7e 213
940227cb 214 # downloads.ipfire.org
c85f80e2 215 self.add_handlers(r"downloads\.([a-z]+\.dev\.)?ipfire\.org", [
82d4e789 216 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download" }),
450972a3 217 (r"/release/(.*)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download/{0}" }),
aec63a26 218 (r"/(.*)", downloads.FileHandler),
54af860e 219 ])
940227cb
MT
220
221 # mirrors.ipfire.org
c85f80e2 222 self.add_handlers(r"mirrors\.([a-z]+\.dev\.)?ipfire\.org", [
278b3118
MT
223 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download/mirrors" }),
224 (r"/mirrors/(.*)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download/mirrors/{0}" }),
3808b871 225 ])
940227cb 226
d0d074e0 227 # planet.ipfire.org
c85f80e2 228 self.add_handlers(r"planet\.([a-z]+\.dev\.)?ipfire\.org", [
3d4ce901 229 (r"/", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/" }),
7fa7d38d
MT
230 (r"/post/([A-Za-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/{0}" }),
231 (r"/user/([a-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/authors/{0}" }),
bcc3ed4d
MT
232
233 # RSS
f0714277 234 (r"/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
d76ec66e 235 (r"/user/([a-z0-9_-]+)/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
f0714277 236 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
3808b871 237 ])
d0d074e0 238
66862195 239 # fireinfo.ipfire.org
c85f80e2 240 self.add_handlers(r"fireinfo\.([a-z]+\.dev\.)?ipfire\.org", [
96c9bb79 241 (r"/", fireinfo.IndexHandler),
8ab37e0b 242
dc96f754
MT
243 # Admin
244 (r"/admin", fireinfo.AdminIndexHandler),
245
8ab37e0b
MT
246 # Vendors
247 (r"/vendors", fireinfo.VendorsHandler),
248 (r"/vendors/(pci|usb)/([0-9a-f]{4})", fireinfo.VendorHandler),
66862195 249
1e3b2aad 250 # Driver
0cd21a36 251 (r"/drivers/(.*)", fireinfo.DriverDetail),
1e3b2aad 252
66862195 253 # Show profiles
96c9bb79 254 (r"/profile/random", fireinfo.RandomProfileHandler),
b84b407f 255 (r"/profile/([a-z0-9]{40})", fireinfo.ProfileHandler),
91a446f0 256
ed2e3c1f 257 # Stats
19518d6e 258 (r"/processors", fireinfo.ProcessorsHandler),
ed2e3c1f
MT
259 (r"/releases", fireinfo.ReleasesHandler),
260
19518d6e 261 # Send profiles
96c9bb79 262 (r"/send/([a-z0-9]+)", fireinfo.ProfileSendHandler),
0ed3ea5c
MT
263
264 # Serve any static files
265 (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
dc96f754 266 ] + authentication_handlers)
5cf160e0 267
c37ec602 268 # i-use.ipfire.org
c85f80e2 269 self.add_handlers(r"i-use\.([a-z]+\.dev\.)?ipfire\.org", [
e2f2865d 270 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/" }),
395c1ac0 271 (r"/profile/([a-f0-9]{40})/([0-9]+).png", iuse.ImageHandler),
c37ec602
MT
272 ])
273
8e2e1261
MT
274 # boot.ipfire.org
275 BOOT_STATIC_PATH = os.path.join(self.settings["static_path"], "netboot")
c85f80e2 276 self.add_handlers(r"boot\.([a-z]+\.dev\.)?ipfire\.org", [
f301d952 277 (r"/", tornado.web.RedirectHandler, { "url" : "https://wiki.ipfire.org/installation/pxe" }),
8e2e1261
MT
278
279 # Configurations
f301d952
MT
280 (r"/premenu.cfg", boot.PremenuCfgHandler),
281 (r"/menu.gpxe", boot.MenuGPXEHandler),
282 (r"/menu.cfg", boot.MenuCfgHandler),
8e2e1261
MT
283
284 # Static files
37b5c0cf 285 (r"/(boot\.png|pxelinux\.0|menu\.c32|vesamenu\.c32)",
8e2e1261
MT
286 tornado.web.StaticFileHandler, { "path" : BOOT_STATIC_PATH }),
287 ])
288
60024cc8 289 # nopaste.ipfire.org
c85f80e2 290 self.add_handlers(r"nopaste\.([a-z]+\.dev\.)?ipfire\.org", [
a41085fb
MT
291 (r"/", nopaste.CreateHandler),
292 (r"/raw/(.*)", nopaste.RawHandler),
293 (r"/view/(.*)", nopaste.ViewHandler),
0ed3ea5c
MT
294
295 # Serve any static files
296 (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
3808b871 297 ] + authentication_handlers)
60024cc8 298
f5b01fc2 299 # location.ipfire.org
c85f80e2 300 self.add_handlers(r"location\.([a-z]+\.dev\.)?ipfire\.org", [
f5b01fc2 301 (r"/", location.IndexHandler),
9c83876f 302 (r"/download", StaticHandler, { "template" : "../location/download.html" }),
55eea098 303 (r"/how\-to\-use", StaticHandler, { "template" : "../location/how-to-use.html" }),
2517822e 304 (r"/lookup/(.+)/blacklists", location.BlacklistsHandler),
f5b01fc2 305 (r"/lookup/(.+)", location.LookupHandler),
0ed3ea5c
MT
306
307 # Serve any static files
308 (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
f5b01fc2
MT
309 ])
310
9068dba1 311 # geoip.ipfire.org
c85f80e2 312 self.add_handlers(r"geoip\.([a-z]+\.dev\.)?ipfire\.org", [
f5b01fc2 313 (r"/", tornado.web.RedirectHandler, { "url" : "https://location.ipfire.org/" }),
3808b871 314 ])
9068dba1 315
66862195 316 # talk.ipfire.org
c85f80e2 317 self.add_handlers(r"talk\.([a-z]+\.dev\.)?ipfire\.org", [
786e9ca8
MT
318 (r"/", tornado.web.RedirectHandler, { "url" : "https://people.ipfire.org/" }),
319 ])
66862195 320
03706893 321 # people.ipfire.org
c85f80e2 322 self.add_handlers(r"people\.([a-z]+\.dev\.)?ipfire\.org", [
786e9ca8 323 (r"/", people.IndexHandler),
2c65e17c 324 (r"/activate/([a-z_][a-z0-9_-]{0,31})/(\w+)", auth.ActivateHandler),
f32dd17f 325 (r"/register", auth.RegisterHandler),
2dac7110 326
92c4b559
MT
327 # Promotional Consent Stuff
328 (r"/subscribe", people.SubscribeHandler),
329 (r"/unsubscribe", people.UnsubscribeHandler),
330
0ed3ea5c
MT
331 # Serve any static files
332 (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
333
689effd0 334 # API
66181c96 335 (r"/api/check/email", auth.APICheckEmail),
689effd0 336 (r"/api/check/uid", auth.APICheckUID),
786e9ca8 337 ] + authentication_handlers)
2cd9af74 338
181d08f3 339 # wiki.ipfire.org
c85f80e2 340 self.add_handlers(r"wiki\.([a-z]+\.dev\.)?ipfire\.org",
181d08f3
MT
341 authentication_handlers + [
342
f2cfd873 343 # Actions
b26c705a 344 (r"((?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))/_delete", wiki.ActionDeleteHandler),
40cb87a4 345 (r"([A-Za-z0-9\-_\/]+)?/_edit", wiki.ActionEditHandler),
2901b734 346 (r"([A-Za-z0-9\-_\/]+)?/_render", wiki.ActionRenderHandler),
9db2e89f 347 (r"([A-Za-z0-9\-_\/]+)?/_(watch|unwatch)", wiki.ActionWatchHandler),
d4c68c5c 348 (r"/actions/restore", wiki.ActionRestoreHandler),
f2cfd873
MT
349 (r"/actions/upload", wiki.ActionUploadHandler),
350
f9db574a
MT
351 # Handlers
352 (r"/recent\-changes", wiki.RecentChangesHandler),
181d08f3 353 (r"/search", wiki.SearchHandler),
86368c12 354 (r"/tree", wiki.TreeHandler),
2f23c558 355 (r"/watchlist", wiki.WatchlistHandler),
f9db574a 356
f2cfd873 357 # Media
3b33319e 358 (r"([A-Za-z0-9\-_\/]+)?/_files", wiki.FilesHandler),
f2cfd873 359
0ed3ea5c
MT
360 # Serve any static files
361 (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
362
f9db574a 363 # Render pages
181d08f3
MT
364 (r"([A-Za-z0-9\-_\/]+)?", wiki.PageHandler),
365 ])
366
ae0228e1 367 # ipfire.org
e65b9a6d 368 self.add_handlers(r"(.*)ipfire\.org", [
ba43a892 369 (r".*", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org" })
5cf160e0 370 ])
3add293a 371
feb02477
MT
372 logging.info("Successfully initialied application")
373
574a88c7 374 def format_country_name(self, handler, country_code):
e929ed92 375 return self.backend.get_country_name(country_code)
574a88c7 376
6eddfb50
MT
377 def format_language_name(self, handler, language):
378 _ = handler.locale.translate
379
380 if language == "de":
381 return _("German")
382 elif language == "en":
383 return _("English")
384 elif language == "es":
385 return _("Spanish")
386 elif language == "fr":
387 return _("French")
388 elif language == "it":
389 return _("Italian")
390 elif language == "nl":
391 return _("Dutch")
392 elif language == "pl":
393 return _("Polish")
394 elif language == "pt":
395 return _("Portuguese")
396 elif language == "ru":
397 return _("Russian")
398 elif language == "tr":
399 return _("Turkish")
400
401 return language
402
cc3b928d
MT
403 def format_month_name(self, handler, month):
404 _ = handler.locale.translate
405
406 if month == 1:
407 return _("January")
408 elif month == 2:
409 return _("February")
410 elif month == 3:
411 return _("March")
412 elif month == 4:
413 return _("April")
414 elif month == 5:
415 return _("May")
416 elif month == 6:
417 return _("June")
418 elif month == 7:
419 return _("July")
420 elif month == 8:
421 return _("August")
422 elif month == 9:
423 return _("September")
424 elif month == 10:
425 return _("October")
426 elif month == 11:
427 return _("November")
428 elif month == 12:
429 return _("December")
430
431 return month
401827c2 432
e96e445b
MT
433 def format_phone_number(self, handler, number):
434 if not isinstance(number, phonenumbers.PhoneNumber):
435 try:
01e73b0e 436 number = phonenumbers.parse(number, None)
e96e445b
MT
437 except phonenumbers.phonenumberutil.NumberParseException:
438 return number
c01ad253
MT
439
440 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
441
e96e445b
MT
442 def format_phone_number_to_e164(self, handler, number):
443 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.E164)
444
445 def format_phone_number_location(self, handler, number):
446 s = [
447 phonenumbers.geocoder.description_for_number(number, handler.locale.code),
448 phonenumbers.region_code_for_number(number),
449 ]
450
451 return ", ".join((e for e in s if e))