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