Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / admin_servlets.py
blob4e0a838a8bcb86ce177e0508688297bed8aa7436
1 # Copyright 2014 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 import json
6 import logging
8 from appengine_wrappers import memcache
9 from commit_tracker import CommitTracker
10 from environment import IsDevServer
11 from environment_wrappers import CreateUrlFetcher
12 from future import All
13 from object_store_creator import ObjectStoreCreator
14 from servlet import Servlet, Response
17 # This is the service account ID associated with the chrome-apps-doc project in
18 # the Google Developers Console.
19 _SERVICE_ACCOUNT_NAME = '636061184119-compute@developer.gserviceaccount.com'
21 # This is Google's OAuth2 service for retrieving user information from an access
22 # token. It is used to authenticate an incoming access token in the metadata
23 # flush servlet, ensuring that only requests from the above service account are
24 # fulfilled.
25 _ACCOUNT_INFO_URL = ('https://www.googleapis.com/oauth2/v1/userinfo?'
26 'access_token=%s')
29 class QueryCommitServlet(Servlet):
30 '''Provides read access to the commit ID cache within the server. For example:
32 /_query_commit/master
34 will return the commit ID stored under the commit key "master" within the
35 commit cache. Currently "master" is the only named commit we cache, and it
36 corresponds to the commit ID whose data currently populates the data cache
37 used by live instances.
38 '''
39 def __init__(self, request):
40 Servlet.__init__(self, request)
42 def Get(self):
43 object_store_creator = ObjectStoreCreator(start_empty=False)
44 commit_tracker = CommitTracker(object_store_creator)
46 def generate_response(result):
47 commit_id, history = result
48 history_log = ''.join('%s: %s<br>' % (entry.datetime, entry.commit_id)
49 for entry in reversed(history))
50 response = 'Current commit: %s<br><br>Most recent commits:<br>%s' % (
51 commit_id, history_log)
52 return response
54 commit_name = self._request.path
55 id_future = commit_tracker.Get(commit_name)
56 history_future = commit_tracker.GetHistory(commit_name)
57 return Response.Ok(
58 All((id_future, history_future)).Then(generate_response).Get())
61 class FlushMemcacheServlet(Servlet):
62 '''Flushes the entire memcache.
64 This requires an access token for the project's main service account. Without
65 said token, the request is considered invalid.
66 '''
68 class Delegate(object):
69 def IsAuthorized(self, access_token):
70 '''Verifies that a given access_token represents the main service account.
71 '''
72 fetcher = CreateUrlFetcher()
73 response = fetcher.Fetch(_ACCOUNT_INFO_URL % access_token)
74 if response.status_code != 200:
75 return False
76 try:
77 info = json.loads(response.content)
78 except:
79 return False
80 return info['email'] == _SERVICE_ACCOUNT_NAME
82 def __init__(self, request, delegate=Delegate()):
83 Servlet.__init__(self, request)
84 self._delegate = delegate
86 def GetAccessToken(self):
87 auth_header = self._request.headers.get('Authorization')
88 if not auth_header:
89 return None
90 try:
91 method, token = auth_header.split(' ', 1)
92 except:
93 return None
94 if method != 'Bearer':
95 return None
96 return token
98 def Get(self):
99 access_token = self.GetAccessToken()
100 if not access_token:
101 return Response.Unauthorized('Unauthorized', 'Bearer', 'update')
102 if not self._delegate.IsAuthorized(access_token):
103 return Response.Forbidden('Forbidden')
104 result = memcache.flush_all()
105 return Response.Ok('Flushed: %s' % result)
108 class UpdateCacheServlet(Servlet):
109 '''Devserver-only servlet for pushing local file data into the datastore.
110 This is useful if you've used update_cache.py to build a local datastore
111 for testing. Query:
113 /_update_cache/FOO_DATA
115 to make the devserver read FOO_DATA from its pwd and push all the data into
116 datastore.
118 def __init__(self, request):
119 Servlet.__init__(self, request)
121 def Get(self):
122 if not IsDevServer():
123 return Response.BadRequest('')
124 import cPickle
125 from persistent_object_store_appengine import PersistentObjectStoreAppengine
126 with open(self._request.path, 'r') as f:
127 data = cPickle.load(f)
128 for namespace, contents in data.iteritems():
129 store = PersistentObjectStoreAppengine(namespace)
130 for k, v in cPickle.loads(contents).iteritems():
131 try:
132 store.Set(k, v).Get()
133 except:
134 logging.warn('Skipping entry %s because of errors.' % k)
135 return Response.Ok('Data pushed!')