Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 1 | # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style |
| 3 | # license that can be found in the LICENSE file or at |
| 4 | # https://developers.google.com/open-source/licenses/bsd |
| 5 | |
| 6 | """This file sets up all the urls for monorail pages.""" |
| 7 | from __future__ import print_function |
| 8 | from __future__ import division |
| 9 | from __future__ import absolute_import |
| 10 | |
| 11 | import logging |
| 12 | import webapp2 |
| 13 | import settings |
| 14 | |
| 15 | from components import prpc |
| 16 | |
| 17 | from features import autolink |
| 18 | from features import dateaction |
| 19 | from features import banspammer |
| 20 | from features import hotlistcreate |
| 21 | from features import hotlistdetails |
| 22 | from features import hotlistissues |
| 23 | from features import hotlistissuescsv |
| 24 | from features import hotlistpeople |
| 25 | from features import filterrules |
| 26 | from features import pubsub |
| 27 | from features import userhotlists |
| 28 | from features import inboundemail |
| 29 | from features import notify |
| 30 | from features import rerankhotlist |
| 31 | from features import savedqueries |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 32 | |
Adrià Vilanova Martínez | de94280 | 2022-07-15 14:06:55 +0200 | [diff] [blame^] | 33 | from framework import banned, excessiveactivity |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 34 | from framework import clientmon |
| 35 | from framework import csp_report |
| 36 | from framework import deleteusers |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 37 | from framework import trimvisitedpages |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 38 | from framework import reap |
| 39 | from framework import registerpages_helpers |
| 40 | from framework import ts_mon_js |
| 41 | from framework import urls |
| 42 | from framework import warmup |
| 43 | |
| 44 | from project import peopledetail |
| 45 | from project import peoplelist |
| 46 | from project import project_constants |
| 47 | from project import projectadmin |
| 48 | from project import projectadminadvanced |
| 49 | from project import projectexport |
| 50 | from project import projectsummary |
| 51 | from project import projectupdates |
| 52 | from project import redirects |
| 53 | |
| 54 | from search import backendnonviewable |
| 55 | from search import backendsearch |
| 56 | |
| 57 | from services import cachemanager_svc |
| 58 | from services import client_config_svc |
| 59 | |
| 60 | from sitewide import custom_404 |
| 61 | from sitewide import groupadmin |
| 62 | from sitewide import groupcreate |
| 63 | from sitewide import groupdetail |
| 64 | from sitewide import grouplist |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 65 | from sitewide import moved |
| 66 | from sitewide import projectcreate |
| 67 | from sitewide import userprofile |
| 68 | from sitewide import usersettings |
| 69 | from sitewide import userclearbouncing |
| 70 | from sitewide import userupdates |
| 71 | |
| 72 | from tracker import componentcreate |
| 73 | from tracker import componentdetail |
| 74 | from tracker import fieldcreate |
| 75 | from tracker import fielddetail |
| 76 | from tracker import issueadmin |
| 77 | from tracker import issueadvsearch |
| 78 | from tracker import issueattachment |
| 79 | from tracker import issueattachmenttext |
| 80 | from tracker import issuebulkedit |
| 81 | from tracker import webcomponentspage |
| 82 | from tracker import issuedetailezt |
| 83 | from tracker import issueentry |
| 84 | from tracker import issueentryafterlogin |
| 85 | from tracker import issueexport |
| 86 | from tracker import issueimport |
| 87 | from tracker import issueoriginal |
| 88 | from tracker import issuereindex |
| 89 | from tracker import issuetips |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 90 | from tracker import templatecreate |
| 91 | from tracker import templatedetail |
| 92 | from tracker import fltconversion |
| 93 | |
| 94 | from api import api_routes as api_routes_v0 |
| 95 | from api.v3 import api_routes as api_routes_v3 |
| 96 | |
| 97 | |
| 98 | class ServletRegistry(object): |
| 99 | |
| 100 | _PROJECT_NAME_REGEX = project_constants.PROJECT_NAME_PATTERN |
| 101 | _USERNAME_REGEX = r'[-+\w=.%]+(@([-a-z0-9]+\.)*[a-z0-9]+)?' |
| 102 | _HOTLIST_ID_NAME_REGEX = r'\d+|[a-zA-Z][-0-9a-zA-Z\.]*' |
| 103 | |
| 104 | def __init__(self): |
| 105 | self.routes = [] |
| 106 | |
| 107 | def _AddRoute(self, path_regex, servlet_class, method, does_write=False): |
| 108 | """Add a GET or POST handler to our webapp2 route list. |
| 109 | |
| 110 | Args: |
| 111 | path_regex: string with webapp2 URL template regex. |
| 112 | servlet_class: a subclass of class Servlet. |
| 113 | method: string 'GET' or 'POST'. |
| 114 | does_write: True if the servlet could write to the database, we skip |
| 115 | registering such servlets when the site is in read_only mode. GET |
| 116 | handlers never write. Most, but not all, POST handlers do write. |
| 117 | """ |
| 118 | if settings.read_only and does_write: |
| 119 | logging.info('Not registring %r because site is read-only', path_regex) |
| 120 | # TODO(jrobbins): register a helpful error page instead. |
| 121 | else: |
| 122 | self.routes.append( |
| 123 | webapp2.Route(path_regex, handler=servlet_class, methods=[method])) |
| 124 | |
| 125 | def _SetupServlets(self, spec_dict, base='', post_does_write=True): |
| 126 | """Register each of the given servlets.""" |
| 127 | for get_uri, servlet_class in spec_dict.items(): |
| 128 | self._AddRoute(base + get_uri, servlet_class, 'GET') |
| 129 | post_uri = get_uri + ('edit.do' if get_uri.endswith('/') else '.do') |
| 130 | self._AddRoute(base + post_uri, servlet_class, 'POST', |
| 131 | does_write=post_does_write) |
| 132 | |
| 133 | def _SetupProjectServlets(self, spec_dict, post_does_write=True): |
| 134 | """Register each of the given servlets in the project URI space.""" |
| 135 | self._SetupServlets( |
| 136 | spec_dict, base='/p/<project_name:%s>' % self._PROJECT_NAME_REGEX, |
| 137 | post_does_write=post_does_write) |
| 138 | |
| 139 | def _SetupUserServlets(self, spec_dict, post_does_write=True): |
| 140 | """Register each of the given servlets in the user URI space.""" |
| 141 | self._SetupServlets( |
| 142 | spec_dict, base='/u/<viewed_username:%s>' % self._USERNAME_REGEX, |
| 143 | post_does_write=post_does_write) |
| 144 | |
| 145 | def _SetupGroupServlets(self, spec_dict, post_does_write=True): |
| 146 | """Register each of the given servlets in the user group URI space.""" |
| 147 | self._SetupServlets( |
| 148 | spec_dict, base='/g/<viewed_username:%s>' % self._USERNAME_REGEX, |
| 149 | post_does_write=post_does_write) |
| 150 | |
| 151 | def _SetupUserHotlistServlets(self, spec_dict, post_does_write=True): |
| 152 | """ Register given user hotlist servlets in the user URI space.""" |
| 153 | self._SetupServlets( |
| 154 | spec_dict, |
| 155 | base ='/u/<viewed_username:%s>/hotlists/<hotlist_id:%s>' |
| 156 | % (self._USERNAME_REGEX, self._HOTLIST_ID_NAME_REGEX), |
| 157 | post_does_write=post_does_write) |
| 158 | |
| 159 | def Register(self, services): |
| 160 | """Register all the monorail request handlers.""" |
| 161 | self._RegisterFrameworkHandlers() |
| 162 | self._RegisterSitewideHandlers() |
| 163 | self._RegisterProjectHandlers() |
| 164 | self._RegisterIssueHandlers() |
| 165 | self._RegisterWebComponentsHanders() |
| 166 | self._RegisterRedirects() |
| 167 | self._RegisterInboundMail() |
| 168 | |
| 169 | # Register pRPC API routes |
| 170 | prpc_server = prpc.Server( |
| 171 | allowed_origins=client_config_svc.GetAllowedOriginsSet()) |
| 172 | api_routes_v0.RegisterApiHandlers(prpc_server, services) |
| 173 | api_routes_v3.RegisterApiHandlers(prpc_server, services) |
| 174 | self.routes.extend(prpc_server.get_routes()) |
| 175 | |
| 176 | autolink.RegisterAutolink(services) |
| 177 | # Error pages should be the last to register. |
| 178 | self._RegisterErrorPages() |
| 179 | return self.routes |
| 180 | |
| 181 | def _RegisterProjectHandlers(self): |
| 182 | """Register page and form handlers that operate within a project.""" |
| 183 | |
| 184 | self._SetupServlets({ |
| 185 | # Note: the following are at URLS that are not externally accessible. |
| 186 | urls.NOTIFY_RULES_DELETED_TASK: notify.NotifyRulesDeletedTask, |
| 187 | }) |
Adrià Vilanova Martínez | de94280 | 2022-07-15 14:06:55 +0200 | [diff] [blame^] | 188 | self._SetupProjectServlets( |
| 189 | { |
| 190 | urls.ADMIN_INTRO: projectsummary.ProjectSummary, |
| 191 | urls.PEOPLE_LIST: peoplelist.PeopleList, |
| 192 | urls.PEOPLE_DETAIL: peopledetail.PeopleDetail, |
| 193 | urls.UPDATES_LIST: projectupdates.ProjectUpdates, |
| 194 | urls.ADMIN_META: projectadmin.ProjectAdmin, |
| 195 | urls.ADMIN_ADVANCED: projectadminadvanced.ProjectAdminAdvanced, |
| 196 | urls.ADMIN_EXPORT: projectexport.ProjectExport, |
| 197 | urls.ADMIN_EXPORT_JSON: projectexport.ProjectExportJSON, |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 198 | }) |
| 199 | |
| 200 | def _RegisterIssueHandlers(self): |
| 201 | """Register page and form handlers for the issue tracker.""" |
| 202 | self._SetupServlets({ |
| 203 | # Note: the following are at URLs that are not externaly accessible. |
| 204 | urls.BACKEND_SEARCH: backendsearch.BackendSearch, |
| 205 | urls.BACKEND_NONVIEWABLE: backendnonviewable.BackendNonviewable, |
| 206 | urls.RECOMPUTE_DERIVED_FIELDS_TASK: |
| 207 | filterrules.RecomputeDerivedFieldsTask, |
| 208 | urls.REINDEX_QUEUE_CRON: filterrules.ReindexQueueCron, |
| 209 | urls.NOTIFY_ISSUE_CHANGE_TASK: notify.NotifyIssueChangeTask, |
| 210 | urls.NOTIFY_BLOCKING_CHANGE_TASK: notify.NotifyBlockingChangeTask, |
| 211 | urls.NOTIFY_BULK_CHANGE_TASK: notify.NotifyBulkChangeTask, |
| 212 | urls.NOTIFY_APPROVAL_CHANGE_TASK: notify.NotifyApprovalChangeTask, |
| 213 | urls.OUTBOUND_EMAIL_TASK: notify.OutboundEmailTask, |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 214 | urls.DATE_ACTION_CRON: dateaction.DateActionCron, |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 215 | urls.PUBLISH_PUBSUB_ISSUE_CHANGE_TASK: |
| 216 | pubsub.PublishPubsubIssueChangeTask, |
| 217 | urls.ISSUE_DATE_ACTION_TASK: dateaction.IssueDateActionTask, |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 218 | urls.FLT_ISSUE_CONVERSION_TASK: fltconversion.FLTConvertTask, |
| 219 | }) |
| 220 | |
| 221 | self._SetupProjectServlets( |
| 222 | { |
| 223 | urls.ISSUE_APPROVAL: |
| 224 | registerpages_helpers.MakeRedirectInScope( |
| 225 | urls.ISSUE_DETAIL, 'p', keep_qs=True), |
| 226 | urls.ISSUE_LIST: |
| 227 | webcomponentspage.WebComponentsPage, |
| 228 | urls.ISSUE_LIST_NEW_TEMP: |
| 229 | registerpages_helpers.MakeRedirectInScope( |
| 230 | urls.ISSUE_LIST, 'p', keep_qs=True), |
| 231 | urls.ISSUE_REINDEX: |
| 232 | issuereindex.IssueReindex, |
| 233 | urls.ISSUE_DETAIL_FLIPPER_NEXT: |
| 234 | issuedetailezt.FlipperNext, |
| 235 | urls.ISSUE_DETAIL_FLIPPER_PREV: |
| 236 | issuedetailezt.FlipperPrev, |
| 237 | urls.ISSUE_DETAIL_FLIPPER_LIST: |
| 238 | issuedetailezt.FlipperList, |
| 239 | urls.ISSUE_DETAIL_FLIPPER_INDEX: |
| 240 | issuedetailezt.FlipperIndex, |
| 241 | urls.ISSUE_DETAIL_LEGACY: |
| 242 | registerpages_helpers.MakeRedirectInScope( |
| 243 | urls.ISSUE_DETAIL, 'p', keep_qs=True), |
| 244 | urls.ISSUE_WIZARD: |
| 245 | webcomponentspage.WebComponentsPage, |
| 246 | urls.ISSUE_ENTRY: |
| 247 | issueentry.IssueEntry, |
| 248 | urls.ISSUE_ENTRY_NEW: |
| 249 | webcomponentspage.WebComponentsPage, |
| 250 | urls.ISSUE_ENTRY_AFTER_LOGIN: |
| 251 | issueentryafterlogin.IssueEntryAfterLogin, |
| 252 | urls.ISSUE_TIPS: |
| 253 | issuetips.IssueSearchTips, |
| 254 | urls.ISSUE_ATTACHMENT: |
| 255 | issueattachment.AttachmentPage, |
| 256 | urls.ISSUE_ATTACHMENT_TEXT: |
| 257 | issueattachmenttext.AttachmentText, |
| 258 | urls.ISSUE_BULK_EDIT: |
| 259 | issuebulkedit.IssueBulkEdit, |
| 260 | urls.COMPONENT_CREATE: |
| 261 | componentcreate.ComponentCreate, |
| 262 | urls.COMPONENT_DETAIL: |
| 263 | componentdetail.ComponentDetail, |
| 264 | urls.FIELD_CREATE: |
| 265 | fieldcreate.FieldCreate, |
| 266 | urls.FIELD_DETAIL: |
| 267 | fielddetail.FieldDetail, |
| 268 | urls.TEMPLATE_CREATE: |
| 269 | templatecreate.TemplateCreate, |
| 270 | urls.TEMPLATE_DETAIL: |
| 271 | templatedetail.TemplateDetail, |
| 272 | urls.WIKI_LIST: |
| 273 | redirects.WikiRedirect, |
| 274 | urls.WIKI_PAGE: |
| 275 | redirects.WikiRedirect, |
| 276 | urls.SOURCE_PAGE: |
| 277 | redirects.SourceRedirect, |
| 278 | urls.ADMIN_STATUSES: |
| 279 | issueadmin.AdminStatuses, |
| 280 | urls.ADMIN_LABELS: |
| 281 | issueadmin.AdminLabels, |
| 282 | urls.ADMIN_RULES: |
| 283 | issueadmin.AdminRules, |
| 284 | urls.ADMIN_TEMPLATES: |
| 285 | issueadmin.AdminTemplates, |
| 286 | urls.ADMIN_COMPONENTS: |
| 287 | issueadmin.AdminComponents, |
| 288 | urls.ADMIN_VIEWS: |
| 289 | issueadmin.AdminViews, |
| 290 | urls.ISSUE_ORIGINAL: |
| 291 | issueoriginal.IssueOriginal, |
| 292 | urls.ISSUE_EXPORT: |
| 293 | issueexport.IssueExport, |
| 294 | urls.ISSUE_EXPORT_JSON: |
| 295 | issueexport.IssueExportJSON, |
| 296 | urls.ISSUE_IMPORT: |
| 297 | issueimport.IssueImport, |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 298 | }) |
| 299 | |
| 300 | # GETs for /issues/detail are now handled by the web components page. |
| 301 | base = '/p/<project_name:%s>' % self._PROJECT_NAME_REGEX |
| 302 | self._AddRoute(base + urls.ISSUE_DETAIL, |
| 303 | webcomponentspage.WebComponentsPage, 'GET') |
| 304 | |
| 305 | self._SetupUserServlets({ |
| 306 | urls.SAVED_QUERIES: savedqueries.SavedQueries, |
| 307 | urls.HOTLISTS: userhotlists.UserHotlists, |
| 308 | }) |
| 309 | |
| 310 | user_hotlists_redir = registerpages_helpers.MakeRedirectInScope( |
| 311 | urls.HOTLISTS, 'u', keep_qs=True) |
| 312 | self._SetupUserServlets({ |
| 313 | '/hotlists/': user_hotlists_redir, |
| 314 | }) |
| 315 | |
| 316 | # These servlets accept POST, but never write to the database, so they can |
| 317 | # still be used when the site is read-only. |
| 318 | self._SetupProjectServlets({ |
| 319 | urls.ISSUE_ADVSEARCH: issueadvsearch.IssueAdvancedSearch, |
| 320 | }, post_does_write=False) |
| 321 | |
| 322 | list_redir = registerpages_helpers.MakeRedirectInScope( |
| 323 | urls.ISSUE_LIST, 'p', keep_qs=True) |
| 324 | self._SetupProjectServlets({ |
| 325 | '': list_redir, |
| 326 | '/': list_redir, |
| 327 | '/issues': list_redir, |
| 328 | '/issues/': list_redir, |
| 329 | }) |
| 330 | |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 331 | |
| 332 | def _RegisterFrameworkHandlers(self): |
| 333 | """Register page and form handlers for framework functionality.""" |
Adrià Vilanova Martínez | de94280 | 2022-07-15 14:06:55 +0200 | [diff] [blame^] | 334 | self._SetupServlets( |
| 335 | { |
| 336 | urls.CSP_REPORT: |
| 337 | csp_report.CSPReportPage, |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 338 | |
Adrià Vilanova Martínez | de94280 | 2022-07-15 14:06:55 +0200 | [diff] [blame^] | 339 | # These are only shown to users if specific conditions are met. |
| 340 | urls.EXCESSIVE_ACTIVITY: |
| 341 | excessiveactivity.ExcessiveActivity, |
| 342 | urls.BANNED: |
| 343 | banned.Banned, |
| 344 | urls.PROJECT_MOVED: |
| 345 | moved.ProjectMoved, |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 346 | |
Adrià Vilanova Martínez | de94280 | 2022-07-15 14:06:55 +0200 | [diff] [blame^] | 347 | # These are not externally accessible |
| 348 | urls.RAMCACHE_CONSOLIDATE_CRON: |
| 349 | cachemanager_svc.RamCacheConsolidate, |
| 350 | urls.REAP_CRON: |
| 351 | reap.Reap, |
| 352 | urls.LOAD_API_CLIENT_CONFIGS_CRON: |
| 353 | (client_config_svc.LoadApiClientConfigs), |
| 354 | urls.CLIENT_MON: |
| 355 | clientmon.ClientMonitor, |
| 356 | urls.TRIM_VISITED_PAGES_CRON: |
| 357 | trimvisitedpages.TrimVisitedPages, |
| 358 | urls.TS_MON_JS: |
| 359 | ts_mon_js.MonorailTSMonJSHandler, |
| 360 | urls.WARMUP: |
| 361 | warmup.Warmup, |
| 362 | urls.START: |
| 363 | warmup.Start, |
| 364 | urls.STOP: |
| 365 | warmup.Stop |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 366 | }) |
| 367 | |
| 368 | def _RegisterSitewideHandlers(self): |
| 369 | """Register page and form handlers that aren't associated with projects.""" |
| 370 | self._SetupServlets({ |
| 371 | urls.PROJECT_CREATE: projectcreate.ProjectCreate, |
| 372 | # The user settings page is a site-wide servlet, not under /u/. |
| 373 | urls.USER_SETTINGS: usersettings.UserSettings, |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 374 | urls.GROUP_CREATE: groupcreate.GroupCreate, |
| 375 | urls.GROUP_LIST: grouplist.GroupList, |
| 376 | urls.GROUP_DELETE: grouplist.GroupList, |
| 377 | urls.HOTLIST_CREATE: hotlistcreate.HotlistCreate, |
| 378 | urls.BAN_SPAMMER_TASK: banspammer.BanSpammerTask, |
| 379 | urls.WIPEOUT_SYNC_CRON: deleteusers.WipeoutSyncCron, |
| 380 | urls.SEND_WIPEOUT_USER_LISTS_TASK: deleteusers.SendWipeoutUserListsTask, |
| 381 | urls.DELETE_WIPEOUT_USERS_TASK: deleteusers.DeleteWipeoutUsersTask, |
| 382 | urls.DELETE_USERS_TASK: deleteusers.DeleteUsersTask, |
| 383 | }) |
| 384 | |
| 385 | self._SetupUserServlets({ |
| 386 | urls.USER_PROFILE: userprofile.UserProfile, |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 387 | urls.BAN_USER: userprofile.BanUser, |
| 388 | urls.BAN_SPAMMER: banspammer.BanSpammer, |
| 389 | urls.USER_CLEAR_BOUNCING: userclearbouncing.UserClearBouncing, |
| 390 | urls.USER_UPDATES_PROJECTS: userupdates.UserUpdatesProjects, |
| 391 | urls.USER_UPDATES_DEVELOPERS: userupdates.UserUpdatesDevelopers, |
| 392 | urls.USER_UPDATES_MINE: userupdates.UserUpdatesIndividual, |
| 393 | }) |
| 394 | |
Adrià Vilanova Martínez | de94280 | 2022-07-15 14:06:55 +0200 | [diff] [blame^] | 395 | self._SetupUserHotlistServlets( |
| 396 | { |
| 397 | urls.HOTLIST_ISSUES: hotlistissues.HotlistIssues, |
| 398 | urls.HOTLIST_ISSUES_CSV: hotlistissuescsv.HotlistIssuesCsv, |
| 399 | urls.HOTLIST_PEOPLE: hotlistpeople.HotlistPeopleList, |
| 400 | urls.HOTLIST_DETAIL: hotlistdetails.HotlistDetails, |
| 401 | urls.HOTLIST_RERANK_JSON: rerankhotlist.RerankHotlistIssue, |
| 402 | }) |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 403 | |
| 404 | profile_redir = registerpages_helpers.MakeRedirectInScope( |
| 405 | urls.USER_PROFILE, 'u') |
| 406 | self._SetupUserServlets({'': profile_redir}) |
| 407 | |
| 408 | self._SetupGroupServlets({ |
| 409 | urls.GROUP_DETAIL: groupdetail.GroupDetail, |
| 410 | urls.GROUP_ADMIN: groupadmin.GroupAdmin, |
| 411 | }) |
| 412 | |
| 413 | def _RegisterWebComponentsHanders(self): |
| 414 | """Register page handlers that are handled by WebComponentsPage.""" |
| 415 | self._AddRoute('/', webcomponentspage.ProjectListPage, 'GET') |
| 416 | self._AddRoute( |
| 417 | '/hotlists<unused:.*>', webcomponentspage.WebComponentsPage, 'GET') |
| 418 | self._AddRoute('/users<unused:.*>', webcomponentspage.WebComponentsPage, |
| 419 | 'GET') |
| 420 | |
| 421 | def _RegisterRedirects(self): |
| 422 | """Register redirects among pages inside monorail.""" |
| 423 | redirect = registerpages_helpers.MakeRedirect('/') |
| 424 | self._SetupServlets( |
| 425 | { |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 426 | '/hosting/': redirect, |
| 427 | '/hosting': redirect, |
| 428 | '/p': redirect, |
| 429 | '/p/': redirect, |
| 430 | '/u': redirect, |
| 431 | '/u/': redirect, |
| 432 | '/': redirect, |
| 433 | }) |
| 434 | |
| 435 | redirect = registerpages_helpers.MakeRedirectInScope( |
| 436 | urls.PEOPLE_LIST, 'p') |
| 437 | self._SetupProjectServlets({ |
| 438 | '/people': redirect, |
| 439 | '/people/': redirect, |
| 440 | }) |
| 441 | |
| 442 | redirect = registerpages_helpers.MakeRedirect(urls.GROUP_LIST) |
| 443 | self._SetupServlets({'/g': redirect}) |
| 444 | |
| 445 | group_redir = registerpages_helpers.MakeRedirectInScope( |
| 446 | urls.USER_PROFILE, 'g') |
| 447 | self._SetupGroupServlets({'': group_redir}) |
| 448 | |
| 449 | def _RegisterInboundMail(self): |
| 450 | """Register a handler for inbound email and email bounces.""" |
Adrià Vilanova Martínez | de94280 | 2022-07-15 14:06:55 +0200 | [diff] [blame^] | 451 | self.routes.append( |
| 452 | webapp2.Route( |
| 453 | '/_ah/mail/<project_addr:.+>', |
| 454 | handler=inboundemail.InboundEmail, |
| 455 | methods=['POST', 'GET'])) |
| 456 | self.routes.append( |
| 457 | webapp2.Route( |
| 458 | '/_ah/bounce', |
| 459 | handler=inboundemail.BouncedEmail, |
| 460 | methods=['POST', 'GET'])) |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 461 | |
| 462 | def _RegisterErrorPages(self): |
| 463 | """Register handlers for errors.""" |
| 464 | self._AddRoute( |
| 465 | '/p/<project_name:%s>/<unrecognized:.+>' % self._PROJECT_NAME_REGEX, |
| 466 | custom_404.ErrorPage, 'GET') |