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