Enable Enterprise enrollment on desktop builds.
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / patch_servlet.py
blobf003c4552b8db8a8e60a92085ec6b0dd5376fd76
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 from fnmatch import fnmatch
6 import logging
7 from urlparse import urlparse
9 from appengine_url_fetcher import AppEngineUrlFetcher
10 from caching_rietveld_patcher import CachingRietveldPatcher
11 from chained_compiled_file_system import ChainedCompiledFileSystem
12 from environment import IsDevServer
13 from extensions_paths import CONTENT_PROVIDERS
14 from instance_servlet import InstanceServlet
15 from render_servlet import RenderServlet
16 from rietveld_patcher import RietveldPatcher, RietveldPatcherError
17 from object_store_creator import ObjectStoreCreator
18 from patched_file_system import PatchedFileSystem
19 from server_instance import ServerInstance
20 from servlet import Request, Response, Servlet
21 import url_constants
22 from gcs_file_system_provider import CloudStorageFileSystemProvider
25 class _PatchServletDelegate(RenderServlet.Delegate):
26 def __init__(self, issue, delegate):
27 self._issue = issue
28 self._delegate = delegate
30 def CreateServerInstance(self):
31 # start_empty=False because a patch can rely on files that are already in
32 # SVN repository but not yet pulled into data store by cron jobs (a typical
33 # example is to add documentation for an existing API).
34 object_store_creator = ObjectStoreCreator(start_empty=False)
36 unpatched_file_system = self._delegate.CreateHostFileSystemProvider(
37 object_store_creator).GetTrunk()
39 rietveld_patcher = CachingRietveldPatcher(
40 RietveldPatcher(self._issue,
41 AppEngineUrlFetcher(url_constants.CODEREVIEW_SERVER)),
42 object_store_creator)
44 patched_file_system = PatchedFileSystem(unpatched_file_system,
45 rietveld_patcher)
47 patched_host_file_system_provider = (
48 self._delegate.CreateHostFileSystemProvider(
49 object_store_creator,
50 # The patched file system needs to be online otherwise it'd be
51 # impossible to add files in the patches.
52 offline=False,
53 # The trunk file system for this creator should be the patched one.
54 default_trunk_instance=patched_file_system))
56 combined_compiled_fs_factory = ChainedCompiledFileSystem.Factory(
57 [unpatched_file_system], object_store_creator)
59 branch_utility = self._delegate.CreateBranchUtility(object_store_creator)
61 server_instance = ServerInstance(
62 object_store_creator,
63 combined_compiled_fs_factory,
64 branch_utility,
65 patched_host_file_system_provider,
66 self._delegate.CreateGithubFileSystemProvider(object_store_creator),
67 CloudStorageFileSystemProvider(object_store_creator),
68 base_path='/_patch/%s/' % self._issue)
70 # HACK: if content_providers.json changes in this patch then the cron needs
71 # to be re-run to pull in the new configuration.
72 _, _, modified = rietveld_patcher.GetPatchedFiles()
73 if CONTENT_PROVIDERS in modified:
74 server_instance.content_providers.Cron().Get()
76 return server_instance
78 class PatchServlet(Servlet):
79 '''Servlet which renders patched docs.
80 '''
81 def __init__(self, request, delegate=None):
82 self._request = request
83 self._delegate = delegate or InstanceServlet.Delegate()
85 def Get(self):
86 if (not IsDevServer() and
87 not fnmatch(urlparse(self._request.host).netloc, '*.appspot.com')):
88 # Only allow patches on appspot URLs; it doesn't matter if appspot.com is
89 # XSS'ed, but it matters for chrome.com.
90 redirect_host = 'https://chrome-apps-doc.appspot.com'
91 logging.info('Redirecting from XSS-able host %s to %s' % (
92 self._request.host, redirect_host))
93 return Response.Redirect(
94 '%s/_patch/%s' % (redirect_host, self._request.path))
96 path_with_issue = self._request.path.lstrip('/')
97 if '/' in path_with_issue:
98 issue, path_without_issue = path_with_issue.split('/', 1)
99 else:
100 return Response.NotFound('Malformed URL. It should look like ' +
101 'https://developer.chrome.com/_patch/12345/extensions/...')
103 try:
104 response = RenderServlet(
105 Request(path_without_issue,
106 self._request.host,
107 self._request.headers),
108 _PatchServletDelegate(issue, self._delegate)).Get()
109 # Disable cache for patched content.
110 response.headers.pop('cache-control', None)
111 except RietveldPatcherError as e:
112 response = Response.NotFound(e.message, {'Content-Type': 'text/plain'})
114 redirect_url, permanent = response.GetRedirect()
115 if redirect_url is not None:
116 response = Response.Redirect('/_patch/%s%s' % (issue, redirect_url),
117 permanent)
118 return response