]> git.ipfire.org Git - ipfire.org.git/blame - src/web/__init__.py
people: Show last successful/failed authentication attempts
[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
MT
98 # Misc
99 "Map" : ui_modules.MapModule,
100 "ProgressBar" : ui_modules.ProgressBarModule,
81675874 101 },
3403dc5e
MT
102
103 # Call this when a page wasn't found
b22bc8e8 104 "default_handler_class" : base.NotFoundHandler,
9ed02e3b 105 }
9068dba1 106 settings.update(kwargs)
5cf160e0 107
ae0228e1
MT
108 tornado.web.Application.__init__(self, **settings)
109
66862195 110 authentication_handlers = [
08df6527
MT
111 (r"/login", auth.LoginHandler),
112 (r"/logout", auth.LogoutHandler),
66862195
MT
113 ]
114
399506a8 115 self.add_handlers(r"(dev|www)\.ipfire\.org", [
940227cb
MT
116 # Entry site that lead the user to index
117 (r"/", IndexHandler),
940227cb 118
81675874 119 # Download sites
60b0917c 120 (r"/downloads", tornado.web.RedirectHandler, { "url" : "/download" }),
e77cd04c
MT
121 (r"/download", download.IndexHandler),
122 (r"/download/([0-9a-z\-\.]+)", download.ReleaseHandler),
940227cb 123
e64ce07e 124 # Donate
c7bcb9ca
MT
125 (r"/donate", donate.DonateHandler),
126 (r"/donate/thank-you", donate.ThankYouHandler),
127 (r"/donate/error", donate.ErrorHandler),
e64ce07e 128 (r"/donation", tornado.web.RedirectHandler, { "url" : "/donate" }),
8d48f4ef 129
5613b94b
MT
130 # Newsletter
131 (r"/newsletter/subscribe", newsletter.SubscribeHandler),
132
de683d7c 133 # RSS feed
f0714277 134 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
7f9dbcc0
MT
135
136 # Redirect news articles to blog
d76ec66e 137 (r"/news/(.*)", handlers.NewsHandler),
de683d7c 138
45592df5 139 # Static Pages
84151dbf 140 (r"/chat", StaticHandler, { "template" : "chat.html" }),
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),
d8a15b2e 271 (r"/activate/(\w+)/(\w+)", auth.ActivateHandler),
30aeccdb 272 (r"/conferences", people.ConferencesHandler),
f32dd17f 273 (r"/register", auth.RegisterHandler),
786e9ca8
MT
274 (r"/search", people.SearchHandler),
275 (r"/users", people.UsersHandler),
276 (r"/users/(\w+)", people.UserHandler),
03706893 277 (r"/users/(\w+)\.jpg", people.AvatarHandler),
68ece434 278 (r"/users/(\w+)/calls/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})", people.CallHandler),
bdaf6b46 279 (r"/users/(\w+)/calls(?:/(\d{4}-\d{2}-\d{2}))?", people.CallsHandler),
e96e445b 280 (r"/users/(\w+)/edit", people.UserEditHandler),
3ea97943 281 (r"/users/(\w+)/passwd", people.UserPasswdHandler),
f4672785 282 (r"/users/(\w+)/ssh-keys", people.SSHKeysIndexHandler),
44b75370
MT
283 (r"/users/(\w+)/ssh-keys/(SHA256\:.*)/delete", people.SSHKeysDeleteHandler),
284 (r"/users/(\w+)/ssh-keys/(SHA256\:.*)", people.SSHKeysDownloadHandler),
0d1fb712 285 (r"/users/(\w+)/ssh-keys/upload", people.SSHKeysUploadHandler),
e0daee8f 286 (r"/users/(\w+)/sip", people.SIPHandler),
2dac7110
MT
287
288 # Single-Sign-On for Discourse
289 (r"/sso/discourse", people.SSODiscourse),
786e9ca8 290 ] + authentication_handlers)
2cd9af74 291
181d08f3
MT
292 # wiki.ipfire.org
293 self.add_handlers(r"wiki(\.dev)?\.ipfire\.org",
294 authentication_handlers + [
295
f2cfd873 296 # Actions
b26c705a 297 (r"((?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))/_delete", wiki.ActionDeleteHandler),
40cb87a4 298 (r"([A-Za-z0-9\-_\/]+)?/_edit", wiki.ActionEditHandler),
2901b734 299 (r"([A-Za-z0-9\-_\/]+)?/_render", wiki.ActionRenderHandler),
9db2e89f 300 (r"([A-Za-z0-9\-_\/]+)?/_(watch|unwatch)", wiki.ActionWatchHandler),
d4c68c5c 301 (r"/actions/restore", wiki.ActionRestoreHandler),
f2cfd873
MT
302 (r"/actions/upload", wiki.ActionUploadHandler),
303
f9db574a
MT
304 # Handlers
305 (r"/recent\-changes", wiki.RecentChangesHandler),
181d08f3 306 (r"/search", wiki.SearchHandler),
2f23c558 307 (r"/watchlist", wiki.WatchlistHandler),
f9db574a 308
f2cfd873 309 # Media
3b33319e 310 (r"([A-Za-z0-9\-_\/]+)?/_files", wiki.FilesHandler),
f2cfd873
MT
311 (r"((?!/static)(?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))$", wiki.FileHandler),
312
f9db574a 313 # Render pages
181d08f3
MT
314 (r"([A-Za-z0-9\-_\/]+)?", wiki.PageHandler),
315 ])
316
ae0228e1 317 # ipfire.org
45592df5 318 self.add_handlers(r"ipfire\.org", [
ba43a892 319 (r".*", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org" })
5cf160e0 320 ])
3add293a 321
feb02477
MT
322 logging.info("Successfully initialied application")
323
574a88c7
MT
324 def format_country_name(self, handler, country_code):
325 return ipfire.countries.get_name(country_code)
326
6eddfb50
MT
327 def format_language_name(self, handler, language):
328 _ = handler.locale.translate
329
330 if language == "de":
331 return _("German")
332 elif language == "en":
333 return _("English")
334 elif language == "es":
335 return _("Spanish")
336 elif language == "fr":
337 return _("French")
338 elif language == "it":
339 return _("Italian")
340 elif language == "nl":
341 return _("Dutch")
342 elif language == "pl":
343 return _("Polish")
344 elif language == "pt":
345 return _("Portuguese")
346 elif language == "ru":
347 return _("Russian")
348 elif language == "tr":
349 return _("Turkish")
350
351 return language
352
cc3b928d
MT
353 def format_month_name(self, handler, month):
354 _ = handler.locale.translate
355
356 if month == 1:
357 return _("January")
358 elif month == 2:
359 return _("February")
360 elif month == 3:
361 return _("March")
362 elif month == 4:
363 return _("April")
364 elif month == 5:
365 return _("May")
366 elif month == 6:
367 return _("June")
368 elif month == 7:
369 return _("July")
370 elif month == 8:
371 return _("August")
372 elif month == 9:
373 return _("September")
374 elif month == 10:
375 return _("October")
376 elif month == 11:
377 return _("November")
378 elif month == 12:
379 return _("December")
380
381 return month
401827c2 382
e96e445b
MT
383 def format_phone_number(self, handler, number):
384 if not isinstance(number, phonenumbers.PhoneNumber):
385 try:
01e73b0e 386 number = phonenumbers.parse(number, None)
e96e445b
MT
387 except phonenumbers.phonenumberutil.NumberParseException:
388 return number
c01ad253
MT
389
390 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
391
e96e445b
MT
392 def format_phone_number_to_e164(self, handler, number):
393 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.E164)
394
395 def format_phone_number_location(self, handler, number):
396 s = [
397 phonenumbers.geocoder.description_for_number(number, handler.locale.code),
398 phonenumbers.region_code_for_number(number),
399 ]
400
401 return ", ".join((e for e in s if e))
402
401827c2
MT
403
404def grouper(handler, iterator, n):
405 """
406 Returns groups of n from the iterator
407 """
408 i = iter(iterator)
409
410 while True:
411 ret = list(itertools.islice(i, 0, n))
412 if not ret:
413 break
414
415 yield ret