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