]> git.ipfire.org Git - ipfire.org.git/blame - src/web/__init__.py
passwd: Ask for old password first and then the new ones
[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
feb02477 13
11347e46 14from .handlers import *
81675874 15
08df6527 16from . import auth
12e5de7e 17from . import blog
e77cd04c 18from . import download
f5b01fc2 19from . import location
5613b94b 20from . import newsletter
03706893 21from . import people
df6180a5 22from . import ui_modules
12e5de7e 23
81675874 24class Application(tornado.web.Application):
3e7c6ccd
MT
25 def __init__(self, config, **kwargs):
26 # Initialize backend
a95c2f97 27 self.backend = ipfire.Backend(config)
a6dc0bad 28
9ed02e3b
MT
29 settings = {
30 # Do not compress responses
31 "gzip" : False,
32
33 # Enable XSRF cookies
34 "xsrf_cookies" : True,
35
36 # Login
37 "login_url" : "/login",
38
39 # Setup directory structure
40 "static_path" : self.backend.config.get("global", "static_dir"),
41 "template_path" : self.backend.config.get("global", "templates_dir"),
42
43 # UI Modules
44 "ui_methods" : {
e96e445b
MT
45 "format_month_name" : self.format_month_name,
46 "format_phone_number" : self.format_phone_number,
47 "format_phone_number_to_e164" : self.format_phone_number_to_e164,
48 "format_phone_number_location" : self.format_phone_number_location,
49 "grouper" : grouper,
cc3b928d 50 },
9ed02e3b 51 "ui_modules" : {
f5b01fc2 52 # Blog
7e64f6a3
MT
53 "BlogHistoryNavigation": blog.HistoryNavigationModule,
54 "BlogList" : blog.ListModule,
f91dfcc7 55 "BlogPost" : blog.PostModule,
8a897d25 56 "BlogPosts" : blog.PostsModule,
f91dfcc7 57
f5b01fc2 58 # Location
df6180a5 59 "Map" : ui_modules.MapModule,
f5b01fc2 60
917434b8 61 # Talk
dbb0c109
MT
62 "AccountsList" : people.AccountsListModule,
63 "CDR" : people.CDRModule,
64 "Channels" : people.ChannelsModule,
65 "Registrations" : people.RegistrationsModule,
917434b8 66
f91dfcc7 67 # Old modules
df6180a5
MT
68 "LanguageName" : ui_modules.LanguageNameModule,
69
70 "MirrorItem" : ui_modules.MirrorItemModule,
71 "MirrorsTable" : ui_modules.MirrorsTableModule,
72 "NetBootMenuConfig" : ui_modules.NetBootMenuConfigModule,
73 "NetBootMenuHeader" : ui_modules.NetBootMenuHeaderModule,
74 "NetBootMenuSeparator" : ui_modules.NetBootMenuSeparatorModule,
75 "ProgressBar" : ui_modules.ProgressBarModule,
df6180a5
MT
76 "FireinfoDeviceTable" : ui_modules.FireinfoDeviceTableModule,
77 "FireinfoDeviceAndGroupsTable" : ui_modules.FireinfoDeviceAndGroupsTableModule,
78 "FireinfoGeoTable" : ui_modules.FireinfoGeoTableModule,
81675874 79 },
3403dc5e
MT
80
81 # Call this when a page wasn't found
82 "default_handler_class" : NotFoundHandler,
9ed02e3b 83 }
9068dba1 84 settings.update(kwargs)
5cf160e0 85
ae0228e1
MT
86 tornado.web.Application.__init__(self, **settings)
87
66862195 88 authentication_handlers = [
08df6527
MT
89 (r"/login", auth.LoginHandler),
90 (r"/logout", auth.LogoutHandler),
66862195
MT
91 ]
92
d4dc517c 93 self.add_handlers(r"(dev|www)\.ipfire\.(at|org)", [
940227cb
MT
94 # Entry site that lead the user to index
95 (r"/", IndexHandler),
940227cb 96
81675874 97 # Download sites
60b0917c 98 (r"/downloads", tornado.web.RedirectHandler, { "url" : "/download" }),
e77cd04c
MT
99 (r"/download", download.IndexHandler),
100 (r"/download/([0-9a-z\-\.]+)", download.ReleaseHandler),
940227cb 101
e64ce07e
MT
102 # Donate
103 (r"/donate", DonateHandler),
104 (r"/donation", tornado.web.RedirectHandler, { "url" : "/donate" }),
8d48f4ef 105
5613b94b
MT
106 # Newsletter
107 (r"/newsletter/subscribe", newsletter.SubscribeHandler),
108
de683d7c 109 # RSS feed
f0714277 110 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
7f9dbcc0
MT
111
112 # Redirect news articles to blog
113 (r"/news/(.*)", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/posts/{1}" }),
de683d7c 114
45592df5 115 # Static Pages
84151dbf 116 (r"/chat", StaticHandler, { "template" : "chat.html" }),
45592df5 117 (r"/features", StaticHandler, { "template" : "features.html" }),
45592df5 118 (r"/legal", StaticHandler, { "template" : "legal.html" }),
00026d8b 119 (r"/support", StaticHandler, { "template" : "support.html" }),
45592df5 120
14cd4fa8
MT
121 # Handle old pages that have moved elsewhere
122 (r"/imprint", tornado.web.RedirectHandler, { "url" : "/legal" }),
3808b871 123 (r"/(de|en)/(.*)", LangCompatHandler),
37ed7c3c
MT
124
125 # Export arbitrary error pages
126 (r"/error/([45][0-9]{2})", ErrorHandler),
940227cb
MT
127 ])
128
12e5de7e
MT
129 # blog.ipfire.org
130 self.add_handlers(r"blog(\.dev)?\.ipfire\.org", [
8a897d25 131 (r"/", blog.IndexHandler),
cfc0823a 132 (r"/authors/(\w+)", blog.AuthorHandler),
541c952b 133 (r"/compose", blog.ComposeHandler),
0b342a05 134 (r"/drafts", blog.DraftsHandler),
d17a2624
MT
135 (r"/post/([0-9a-z\-\._]+)", blog.PostHandler),
136 (r"/post/([0-9a-z\-\._]+)/edit", blog.EditHandler),
137 (r"/post/([0-9a-z\-\._]+)/publish", blog.PublishHandler),
e6b18dce 138 (r"/search", blog.SearchHandler),
8d7487d2 139 (r"/tags/([0-9a-z\-\.]+)", blog.TagHandler),
7e64f6a3 140 (r"/years/([0-9]+)", blog.YearHandler),
f0714277
MT
141
142 # RSS Feed
143 (r"/feed.xml", blog.FeedHandler),
08df6527 144 ] + authentication_handlers)
12e5de7e 145
940227cb 146 # downloads.ipfire.org
80594ae3 147 self.add_handlers(r"downloads?(\.dev)?\.ipfire\.org", [
ed8116c7
MT
148 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/" }),
149 (r"/(.*)", download.FileHandler),
54af860e 150 ])
940227cb
MT
151
152 # mirrors.ipfire.org
8fceca0a 153 self.add_handlers(r"mirrors(\.dev)?\.ipfire\.org", [
940227cb 154 (r"/", MirrorIndexHandler),
9068dba1 155 (r"/mirror/(.*)", MirrorItemHandler),
3808b871 156 ])
940227cb 157
d0d074e0 158 # planet.ipfire.org
7cad1818 159 self.add_handlers(r"planet(\.dev)?\.ipfire\.org", [
3d4ce901
MT
160 (r"/", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/" }),
161 (r"/post/([A-Za-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/posts/{1}" }),
162 (r"/user/([a-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/authors/{1}" }),
bcc3ed4d
MT
163
164 # RSS
f0714277 165 (r"/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
3d4ce901 166 (r"/user/([a-z0-9_-]+)/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/authors/{1}.rss" }),
f0714277 167 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
3808b871 168 ])
d0d074e0 169
66862195 170 # fireinfo.ipfire.org
8fceca0a 171 self.add_handlers(r"fireinfo(\.dev)?\.ipfire\.org", [
66862195
MT
172 (r"/", FireinfoIndexHandler),
173 (r"/device/driver/(.*)", FireinfoDeviceDriverDetail),
174 (r"/device/vendors", FireinfoDeviceVendorsHandler),
175 (r"/device/(pci|usb)/([0-9a-f]{4})", FireinfoDeviceVendorHandler),
176 (r"/device/(pci|usb)/([0-9a-f]{4})/([0-9a-f]{4})", FireinfoDeviceModelHandler),
177
178 # Show profiles
179 (r"/profile/random", FireinfoRandomProfileHandler),
180 (r"/profile/([a-z0-9]{40})", FireinfoProfileDetailHandler),
91a446f0 181
30852a9e 182 # Send profiles.
66862195
MT
183 (r"/send/([a-z0-9]+)", FireinfoProfileSendHandler),
184
185 # Stats handlers
186 (r"/statistics", FireinfoStatsHandler),
187 (r"/statistics/processors", FireinfoStatsProcessorsHandler),
188 (r"/statistics/processors/(arm|x86)", FireinfoStatsProcessorDetailHandler),
189 (r"/statistics/geo-locations", FireinfoStatsGeoHandler),
190 (r"/statistics/languages", FireinfoStatsLanguagesHandler),
191 (r"/statistics/memory", FireinfoStatsMemoryHandler),
192 (r"/statistics/networking", FireinfoStatsNetworkingHandler),
193 (r"/statistics/releases", FireinfoStatsReleasesHandler),
194 (r"/statistics/virtualization", FireinfoStatsVirtualHandler),
195
196 # Compat handlers
197 (r"/stats", tornado.web.RedirectHandler, { "url" : "/statistics" }),
198 (r"/stats/cpus", tornado.web.RedirectHandler, { "url" : "/statistics/processors" }),
199 (r"/stats/geo", tornado.web.RedirectHandler, { "url" : "/statistics/geo-locations" }),
200 (r"/stats/network", tornado.web.RedirectHandler, { "url" : "/statistics/networking" }),
201 (r"/stats/oses", tornado.web.RedirectHandler, { "url" : "/statistics/releases" }),
202 (r"/stats/virtual", tornado.web.RedirectHandler, { "url" : "/statistics/virtualization" }),
203 (r"/vendor/(pci|usb)/([0-9a-f]{4})", FireinfoDeviceVendorCompatHandler),
204 (r"/model/(pci|usb)/([0-9a-f]{4})/([0-9a-f]{4})", FireinfoDeviceModelCompatHandler),
3808b871 205 ])
5cf160e0 206
c37ec602 207 # i-use.ipfire.org
8fceca0a 208 self.add_handlers(r"i-use(\.dev)?\.ipfire\.org", [
c37ec602
MT
209 (r"/profile/([a-f0-9]{40})/([0-9]+).png", IUseImage),
210 ])
211
8e2e1261
MT
212 # boot.ipfire.org
213 BOOT_STATIC_PATH = os.path.join(self.settings["static_path"], "netboot")
8fceca0a 214 self.add_handlers(r"boot(\.dev)?\.ipfire\.org", [
ba43a892 215 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download" }),
8e2e1261
MT
216
217 # Configurations
37b5c0cf 218 (r"/premenu.cfg", PremenuCfgHandler),
8e2e1261
MT
219 (r"/menu.gpxe", MenuGPXEHandler),
220 (r"/menu.cfg", MenuCfgHandler),
8e2e1261
MT
221
222 # Static files
37b5c0cf 223 (r"/(boot\.png|pxelinux\.0|menu\.c32|vesamenu\.c32)",
8e2e1261
MT
224 tornado.web.StaticFileHandler, { "path" : BOOT_STATIC_PATH }),
225 ])
226
60024cc8 227 # nopaste.ipfire.org
8fceca0a 228 self.add_handlers(r"nopaste(\.dev)?\.ipfire\.org", [
66862195
MT
229 (r"/", NopasteCreateHandler),
230 (r"/raw/(.*)", NopasteRawHandler),
231 (r"/view/(.*)", NopasteViewHandler),
3808b871 232 ] + authentication_handlers)
60024cc8 233
f5b01fc2
MT
234 # location.ipfire.org
235 self.add_handlers(r"location(\.dev)?\.ipfire\.org", [
236 (r"/", location.IndexHandler),
237 (r"/lookup/(.+)", location.LookupHandler),
238 ])
239
9068dba1 240 # geoip.ipfire.org
8fceca0a 241 self.add_handlers(r"geoip(\.dev)?\.ipfire\.org", [
f5b01fc2 242 (r"/", tornado.web.RedirectHandler, { "url" : "https://location.ipfire.org/" }),
3808b871 243 ])
9068dba1 244
66862195
MT
245 # talk.ipfire.org
246 self.add_handlers(r"talk(\.dev)?\.ipfire\.org", [
786e9ca8
MT
247 (r"/", tornado.web.RedirectHandler, { "url" : "https://people.ipfire.org/" }),
248 ])
66862195 249
03706893
MT
250 # people.ipfire.org
251 self.add_handlers(r"people(\.dev)?\.ipfire\.org", [
786e9ca8
MT
252 (r"/", people.IndexHandler),
253 (r"/search", people.SearchHandler),
254 (r"/users", people.UsersHandler),
255 (r"/users/(\w+)", people.UserHandler),
03706893 256 (r"/users/(\w+)\.jpg", people.AvatarHandler),
bdaf6b46 257 (r"/users/(\w+)/calls(?:/(\d{4}-\d{2}-\d{2}))?", people.CallsHandler),
e96e445b 258 (r"/users/(\w+)/edit", people.UserEditHandler),
3ea97943 259 (r"/users/(\w+)/passwd", people.UserPasswdHandler),
786e9ca8
MT
260 (r"/users/(\w+)/registrations", people.RegistrationsHandler),
261 ] + authentication_handlers)
2cd9af74 262
ae0228e1 263 # ipfire.org
45592df5 264 self.add_handlers(r"ipfire\.org", [
ba43a892 265 (r".*", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org" })
5cf160e0 266 ])
3add293a 267
feb02477
MT
268 logging.info("Successfully initialied application")
269
cc3b928d
MT
270 def format_month_name(self, handler, month):
271 _ = handler.locale.translate
272
273 if month == 1:
274 return _("January")
275 elif month == 2:
276 return _("February")
277 elif month == 3:
278 return _("March")
279 elif month == 4:
280 return _("April")
281 elif month == 5:
282 return _("May")
283 elif month == 6:
284 return _("June")
285 elif month == 7:
286 return _("July")
287 elif month == 8:
288 return _("August")
289 elif month == 9:
290 return _("September")
291 elif month == 10:
292 return _("October")
293 elif month == 11:
294 return _("November")
295 elif month == 12:
296 return _("December")
297
298 return month
401827c2 299
e96e445b
MT
300 def format_phone_number(self, handler, number):
301 if not isinstance(number, phonenumbers.PhoneNumber):
302 try:
01e73b0e 303 number = phonenumbers.parse(number, None)
e96e445b
MT
304 except phonenumbers.phonenumberutil.NumberParseException:
305 return number
c01ad253
MT
306
307 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
308
e96e445b
MT
309 def format_phone_number_to_e164(self, handler, number):
310 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.E164)
311
312 def format_phone_number_location(self, handler, number):
313 s = [
314 phonenumbers.geocoder.description_for_number(number, handler.locale.code),
315 phonenumbers.region_code_for_number(number),
316 ]
317
318 return ", ".join((e for e in s if e))
319
401827c2
MT
320
321def grouper(handler, iterator, n):
322 """
323 Returns groups of n from the iterator
324 """
325 i = iter(iterator)
326
327 while True:
328 ret = list(itertools.islice(i, 0, n))
329 if not ret:
330 break
331
332 yield ret