Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 import calendar | 5 import calendar |
| 6 from datetime import datetime | 6 from datetime import datetime |
| 7 import functools | |
| 7 import hashlib | 8 import hashlib |
| 8 import json | 9 import json |
| 9 import logging | 10 import logging |
| 11 import os | |
| 10 | 12 |
| 11 from google.appengine.api import memcache | 13 from google.appengine.api import memcache |
| 12 from google.appengine.api import users | 14 from google.appengine.api import users |
| 15 from google.appengine.api import app_identity | |
| 13 | 16 |
| 14 from shared.config import VALID_EMAIL_RE | 17 from shared.config import HOST_ACLS |
| 15 | 18 |
| 16 compressed_separators = (',', ':') | 19 compressed_separators = (',', ':') |
| 17 minutes_per_day = 24 * 60 | 20 minutes_per_day = 24 * 60 |
| 18 | 21 |
| 19 def cronjob(cronjob_handler): | 22 def cronjob(cronjob_handler): |
| 20 def checked_cronjob_handler(self, *args): | 23 def checked_cronjob_handler(self, *args): |
| 21 assert (self.request.headers.get('X-AppEngine-Cron') or # pragma: no cover | 24 assert (self.request.headers.get('X-AppEngine-Cron') or # pragma: no cover |
| 22 users.is_current_user_admin()) | 25 users.is_current_user_admin()) |
| 23 cronjob_handler(self, *args) # pragma: no cover | 26 cronjob_handler(self, *args) # pragma: no cover |
| 24 return checked_cronjob_handler | 27 return checked_cronjob_handler |
| 25 | 28 |
| 26 def cross_origin_json(handler): | 29 def cross_origin_json(handler): |
| 30 @functools.wraps(handler) | |
| 27 def headered_json_handler(self, *args): | 31 def headered_json_handler(self, *args): |
| 28 self.response.headers.add_header("Access-Control-Allow-Origin", "*") | 32 self.response.headers.add_header("Access-Control-Allow-Origin", "*") |
| 29 result = handler(self, *args) | 33 result = handler(self, *args) |
| 30 if result is not None: | 34 if result is not None: |
| 31 self.response.headers.add_header('Content-Type', 'application/json') | 35 self.response.headers.add_header('Content-Type', 'application/json') |
| 32 self.response.write(compressed_json_dumps(result)) | 36 self.response.write(compressed_json_dumps(result)) |
| 33 return headered_json_handler | 37 return headered_json_handler |
| 34 | 38 |
| 35 def filter_dict(d, keys): | 39 def filter_dict(d, keys): |
| 36 return {key: d[key] for key in d if key in keys} | 40 return {key: d[key] for key in d if key in keys} |
| 37 | 41 |
| 38 def is_valid_user(): | 42 |
| 43 def get_host_permissions(kind): | |
| 44 """Returns compiled regex of allowed user email or True if everyone is | |
| 45 allowed.""" | |
| 46 assert kind in ('read', 'write') | |
| 47 if os.environ.get('SERVER_SOFTWARE', '').startswith('Development'): | |
| 48 host = 'Development' | |
| 49 else: | |
| 50 host = app_identity.get_default_version_hostname() | |
| 51 return HOST_ACLS[host][kind] | |
| 52 | |
| 53 def has_permission(kind): | |
| 39 if users.is_current_user_admin(): | 54 if users.is_current_user_admin(): |
| 55 logging.info('user is admin') | |
| 56 return True | |
| 57 email_pattern = get_host_permissions(kind) | |
| 58 if email_pattern is True: # Everyone. | |
|
Sergiy Byelozyorov
2016/07/01 17:13:06
I'd use 'everyone' rather than True. Then it's als
tandrii(chromium)
2016/07/01 18:56:55
good idea.
| |
| 40 return True | 59 return True |
| 41 user = users.get_current_user() | 60 user = users.get_current_user() |
| 42 return user and VALID_EMAIL_RE.match(user.email()) | 61 return user and bool(email_pattern.match(user.email())) |
| 62 | |
| 63 | |
| 64 def read_access(handler): | |
| 65 """Decorator ensuring current user has read access to this host.""" | |
| 66 @functools.wraps(handler) | |
| 67 def ensure(self, *args, **kwargs): | |
| 68 if not has_permission('read'): | |
| 69 self.redirect(users.create_login_url(self.request.url)) | |
| 70 return | |
| 71 return handler(self, *args, **kwargs) | |
| 72 return ensure | |
| 73 | |
| 74 | |
| 75 def get_friendly_hostname(): | |
| 76 host = app_identity.get_default_version_hostname() | |
| 77 return host.split('-')[0].capitalize() | |
|
Sergiy Byelozyorov
2016/07/01 17:13:06
Not so friendly to developers trying to understand
tandrii(chromium)
2016/07/01 18:56:55
added comment.
| |
| 78 | |
| 43 | 79 |
| 44 def memcachize(cache_check): | 80 def memcachize(cache_check): |
| 45 def decorator(f): | 81 def decorator(f): |
| 46 def memcachized(**kwargs): | 82 def memcachized(**kwargs): |
| 47 key = '%s.%s(%s)' % ( | 83 key = '%s.%s(%s)' % ( |
| 48 f.__module__, | 84 f.__module__, |
| 49 f.__name__, | 85 f.__name__, |
| 50 ', '.join('%s=%r' % i for i in sorted(kwargs.items())), | 86 ', '.join('%s=%r' % i for i in sorted(kwargs.items())), |
| 51 ) | 87 ) |
| 52 cache = memcache.get(key) | 88 cache = memcache.get(key) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 | 139 |
| 104 | 140 |
| 105 def get_full_patchset_url(codereview_hostname, issue, patchset): | 141 def get_full_patchset_url(codereview_hostname, issue, patchset): |
| 106 if codereview_hostname.split('.')[0].split('-')[-1] == 'review': | 142 if codereview_hostname.split('.')[0].split('-')[-1] == 'review': |
| 107 # This is Gerrit, which has host-review.googlesource.com. | 143 # This is Gerrit, which has host-review.googlesource.com. |
| 108 templ = 'https://%s/#/c/%s/%s' | 144 templ = 'https://%s/#/c/%s/%s' |
| 109 else: | 145 else: |
| 110 # Rietveld. | 146 # Rietveld. |
| 111 templ = 'https://%s/%s/#ps%s' | 147 templ = 'https://%s/%s/#ps%s' |
| 112 return templ % (codereview_hostname, issue, patchset) | 148 return templ % (codereview_hostname, issue, patchset) |
| OLD | NEW |