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