Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(390)

Side by Side Diff: chrome/common/extensions/docs/server2/admin_servlets.py

Issue 1151283007: Docserver overhaul: Gitiles away from me. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove inform_users template to fix presubmit failure (it's now a redirect) Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 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 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 from appengine_wrappers import taskqueue 5 import json
6 import logging
7
8 from appengine_wrappers import memcache
6 from commit_tracker import CommitTracker 9 from commit_tracker import CommitTracker
10 from environment import IsDevServer
11 from environment_wrappers import CreateUrlFetcher
7 from future import All 12 from future import All
8 from object_store_creator import ObjectStoreCreator 13 from object_store_creator import ObjectStoreCreator
9 from refresh_tracker import RefreshTracker
10 from servlet import Servlet, Response 14 from servlet import Servlet, Response
11 15
12 16
13 class EnqueueServlet(Servlet): 17 # This is the service account ID associated with the chrome-apps-doc project in
14 '''This Servlet can be used to manually enqueue tasks on the default 18 # the Google Developers Console.
15 taskqueue. Useful for when an admin wants to manually force a specific 19 _SERVICE_ACCOUNT_NAME = '636061184119-compute@developer.gserviceaccount.com'
16 DataSource refresh, but the refresh operation takes longer than the 60 sec
17 timeout of a non-taskqueue request. For example, you might query
18 20
19 /_enqueue/_refresh/content_providers/cr-native-client?commit=123ff65468dcafff0 21 # This is Google's OAuth2 service for retrieving user information from an access
20 22 # token. It is used to authenticate an incoming access token in the metadata
21 which will enqueue a task (/_refresh/content_providers/cr-native-client) to 23 # flush servlet, ensuring that only requests from the above service account are
22 refresh the NaCl documentation cache for commit 123ff65468dcafff0. 24 # fulfilled.
23 25 _ACCOUNT_INFO_URL = ('https://www.googleapis.com/oauth2/v1/userinfo?'
24 Access to this servlet should always be restricted to administrative users. 26 'access_token=%s')
25 '''
26 def __init__(self, request):
27 Servlet.__init__(self, request)
28
29 def Get(self):
30 queue = taskqueue.Queue()
31 queue.add(taskqueue.Task(url='/%s' % self._request.path,
32 params=self._request.arguments))
33 return Response.Ok('Task enqueued.')
34 27
35 28
36 class QueryCommitServlet(Servlet): 29 class QueryCommitServlet(Servlet):
37 '''Provides read access to the commit ID cache within the server. For example: 30 '''Provides read access to the commit ID cache within the server. For example:
38 31
39 /_query_commit/master 32 /_query_commit/master
40 33
41 will return the commit ID stored under the commit key "master" within the 34 will return the commit ID stored under the commit key "master" within the
42 commit cache. Currently "master" is the only named commit we cache, and it 35 commit cache. Currently "master" is the only named commit we cache, and it
43 corresponds to the commit ID whose data currently populates the data cache 36 corresponds to the commit ID whose data currently populates the data cache
(...skipping 14 matching lines...) Expand all
58 commit_id, history_log) 51 commit_id, history_log)
59 return response 52 return response
60 53
61 commit_name = self._request.path 54 commit_name = self._request.path
62 id_future = commit_tracker.Get(commit_name) 55 id_future = commit_tracker.Get(commit_name)
63 history_future = commit_tracker.GetHistory(commit_name) 56 history_future = commit_tracker.GetHistory(commit_name)
64 return Response.Ok( 57 return Response.Ok(
65 All((id_future, history_future)).Then(generate_response).Get()) 58 All((id_future, history_future)).Then(generate_response).Get())
66 59
67 60
68 class DumpRefreshServlet(Servlet): 61 class FlushMemcacheServlet(Servlet):
69 def __init__(self, request): 62 '''Flushes the entire memcache.
70 Servlet.__init__(self, request)
71 63
72 def Get(self): 64 This requires an access token for the project's main service account. Without
73 object_store_creator = ObjectStoreCreator(start_empty=False) 65 said token, the request is considered invalid.
74 refresh_tracker = RefreshTracker(object_store_creator)
75 commit_id = self._request.path
76 work_order = refresh_tracker._GetWorkOrder(commit_id).Get()
77 task_names = ['%s@%s' % (commit_id, task) for task in work_order.tasks]
78 completions = refresh_tracker._task_completions.GetMulti(task_names).Get()
79 missing = []
80 for task in task_names:
81 if task not in completions:
82 missing.append(task)
83 response = 'Missing:<br>%s' % ''.join('%s<br>' % task for task in missing)
84 return Response.Ok(response)
85
86 class ResetCommitServlet(Servlet):
87 '''Writes a new commit ID to the commit cache. For example:
88
89 /_reset_commit/master/123456
90
91 will reset the 'master' commit ID to '123456'. The provided commit MUST be
92 in the named commit's recent history or it will be ignored.
93 ''' 66 '''
94 67
95 class Delegate(object): 68 class Delegate(object):
96 def CreateCommitTracker(self): 69 def IsAuthorized(self, access_token):
97 return CommitTracker(ObjectStoreCreator(start_empty=False)) 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
98 81
99 def __init__(self, request, delegate=Delegate()): 82 def __init__(self, request, delegate=Delegate()):
100 Servlet.__init__(self, request) 83 Servlet.__init__(self, request)
101 self._delegate = delegate 84 self._delegate = delegate
102 85
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
97
103 def Get(self): 98 def Get(self):
104 commit_tracker = self._delegate.CreateCommitTracker() 99 access_token = self.GetAccessToken()
105 commit_name, commit_id = self._request.path.split('/', 1) 100 if not access_token:
106 history = commit_tracker.GetHistory(commit_name).Get() 101 return Response.Unauthorized('Unauthorized', 'Bearer', 'update')
107 if not any(entry.commit_id == commit_id for entry in history): 102 if not self._delegate.IsAuthorized(access_token):
108 return Response.BadRequest('Commit %s not cached.' % commit_id) 103 return Response.Forbidden('Forbidden')
109 commit_tracker.Set(commit_name, commit_id).Get() 104 result = memcache.flush_all()
110 return Response.Ok('Commit "%s" updated to %s' % (commit_name, commit_id)) 105 return Response.Ok('Flushed: %s' % result)
111 106
107
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:
112
113 /_update_cache/FOO_DATA
114
115 to make the devserver read FOO_DATA from its pwd and push all the data into
116 datastore.
117 '''
118 def __init__(self, request):
119 Servlet.__init__(self, request)
120
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!')
OLDNEW
« no previous file with comments | « chrome/common/extensions/docs/server2/README ('k') | chrome/common/extensions/docs/server2/admin_servlets_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698