OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 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 import cgi | 6 import cgi |
7 import contextlib | |
8 import datetime | 7 import datetime |
9 import datetime_encoder | |
10 import json | 8 import json |
11 import logging | 9 import logging |
12 import os | 10 import os |
13 import sys | 11 import sys |
14 import time | 12 import time |
| 13 import utils |
15 import webapp2 | 14 import webapp2 |
16 import zlib | 15 import zlib |
17 | 16 |
18 | 17 |
19 from google.appengine.api import app_identity | 18 from google.appengine.api import app_identity |
20 from google.appengine.api import memcache | 19 from google.appengine.api import memcache |
21 from google.appengine.api import users | 20 from google.appengine.api import users |
22 from google.appengine.datastore import datastore_query | |
23 from google.appengine.ext import ndb | 21 from google.appengine.ext import ndb |
24 | 22 |
25 | 23 |
26 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | 24 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
27 sys.path.insert(0, os.path.join(BASE_DIR, 'components', 'third_party')) | 25 sys.path.insert(0, os.path.join(BASE_DIR, 'components', 'third_party')) |
28 | 26 |
29 from components import auth | 27 from components import auth |
30 from components import template | 28 from components import template |
31 | 29 |
32 | 30 |
(...skipping 27 matching lines...) Expand all Loading... |
60 | 58 |
61 MSG_TYPE = 'banner-msg' | 59 MSG_TYPE = 'banner-msg' |
62 | 60 |
63 def set_json_headers(self): | 61 def set_json_headers(self): |
64 self.response.headers['Access-Control-Allow-Origin'] = '*' | 62 self.response.headers['Access-Control-Allow-Origin'] = '*' |
65 self.response.headers['Content-Type'] = 'application/json' | 63 self.response.headers['Content-Type'] = 'application/json' |
66 | 64 |
67 def send_json_data(self, data): | 65 def send_json_data(self, data): |
68 self.set_json_headers() | 66 self.set_json_headers() |
69 self.response.write( | 67 self.response.write( |
70 json.dumps(data, cls=datetime_encoder.DateTimeEncoder, indent=1)) | 68 json.dumps(data, cls=utils.DateTimeEncoder, indent=1)) |
71 | 69 |
72 def get_from_datastore(self, msg_type): | 70 def get_from_datastore(self, msg_type): |
73 last_entry = BannerMessage.get_last_datastore(msg_type) | 71 last_entry = BannerMessage.get_last_datastore(msg_type) |
74 if last_entry and last_entry.active: | 72 if last_entry and last_entry.active: |
75 data = last_entry.to_json_data() | 73 data = last_entry.to_json_data() |
76 memcache.set(msg_type, data) | 74 memcache.set(msg_type, data) |
77 | 75 |
78 self.send_json_data(data) | 76 self.send_json_data(data) |
79 return True | 77 return True |
80 return False | 78 return False |
81 | 79 |
82 def get_from_memcache(self, memcache_key): | 80 def get_from_memcache(self, memcache_key): |
83 data = memcache.get(memcache_key) | 81 data = memcache.get(memcache_key) |
84 if data: | 82 if data: |
85 self.send_json_data(data) | 83 self.send_json_data(data) |
86 return True | 84 return True |
87 return False | 85 return False |
88 | 86 |
89 def get_msg(self, msg_type): | 87 def get_msg(self, msg_type): |
90 if not self.get_from_memcache(msg_type): | 88 if not self.get_from_memcache(msg_type): |
91 if not self.get_from_datastore(msg_type): | 89 if not self.get_from_datastore(msg_type): |
92 self.send_json_data({}) | 90 self.send_json_data({}) |
93 | 91 |
94 def get(self): | 92 def get(self): |
95 self.get_msg(BannerMessageHandler.MSG_TYPE) | 93 self.get_msg(BannerMessageHandler.MSG_TYPE) |
96 | 94 |
97 | 95 |
98 # TODO(seanmccullough): move this into a general purpose auth lib if | |
99 # we need to run this check elsehere in SoM. | |
100 def is_trooper_or_admin(): | |
101 return (auth.is_group_member("mdb/chrome-troopers") or | |
102 users.is_current_user_admin()) | |
103 | |
104 | |
105 class BannerMessageFormHandler(auth.AuthenticatingHandler): | 96 class BannerMessageFormHandler(auth.AuthenticatingHandler): |
106 | 97 |
107 @auth.autologin | 98 @auth.autologin |
108 @auth.require(is_trooper_or_admin) | 99 @auth.require(utils.is_trooper_or_admin) |
109 def get(self): | 100 def get(self): |
110 user = users.get_current_user() | 101 user = users.get_current_user() |
111 template_values = { | 102 template_values = { |
112 'user': user, | 103 'user': user, |
113 'xsrf_token': self.generate_xsrf_token(), | 104 'xsrf_token': self.generate_xsrf_token(), |
114 } | 105 } |
115 | 106 |
116 latest_msg = BannerMessage.get_last_datastore( | 107 latest_msg = BannerMessage.get_last_datastore( |
117 BannerMessageHandler.MSG_TYPE) | 108 BannerMessageHandler.MSG_TYPE) |
118 | 109 |
119 if latest_msg is not None and latest_msg.active: | 110 if latest_msg is not None and latest_msg.active: |
120 template_values['latest_msg'] = latest_msg | 111 template_values['latest_msg'] = latest_msg |
121 | 112 |
122 self.response.write(template.render('som/banner-msg-form.html', | 113 self.response.write(template.render('som/banner-msg-form.html', |
123 template_values)) | 114 template_values)) |
124 | 115 |
125 def store_msg(self, msg_type, msg): | 116 def store_msg(self, msg_type, msg): |
126 uid = int(time.time() * 1000000) | 117 uid = int(time.time() * 1000000) |
127 new_entry = BannerMessage( | 118 new_entry = BannerMessage( |
128 key=ndb.Key('BannerMessageRoot', '0', BannerMessage, uid), | 119 key=ndb.Key('BannerMessageRoot', '0', BannerMessage, uid), |
(...skipping 16 matching lines...) Expand all Loading... |
145 self.response.set_status(500, 'could not find latest message') | 136 self.response.set_status(500, 'could not find latest message') |
146 | 137 |
147 def update_msg(self, msg_type): | 138 def update_msg(self, msg_type): |
148 if self.request.get('deactivate'): | 139 if self.request.get('deactivate'): |
149 return self.deactivate_latest_msg(BannerMessageHandler.MSG_TYPE) | 140 return self.deactivate_latest_msg(BannerMessageHandler.MSG_TYPE) |
150 else: | 141 else: |
151 content = self.request.get('content') | 142 content = self.request.get('content') |
152 if content: | 143 if content: |
153 return self.store_msg(msg_type, content) | 144 return self.store_msg(msg_type, content) |
154 | 145 |
155 @auth.require(is_trooper_or_admin) | 146 @auth.require(utils.is_trooper_or_admin) |
156 def post(self): | 147 def post(self): |
157 user = users.get_current_user() | 148 user = users.get_current_user() |
158 if user: | 149 if user: |
159 msg = self.update_msg(BannerMessageHandler.MSG_TYPE) | 150 msg = self.update_msg(BannerMessageHandler.MSG_TYPE) |
160 if msg: | 151 if msg: |
161 data = msg.to_json_data() | 152 data = msg.to_json_data() |
162 memcache.set(BannerMessageHandler.MSG_TYPE, data) | 153 memcache.set(BannerMessageHandler.MSG_TYPE, data) |
163 | 154 |
164 self.redirect('/banner-msg-form') | 155 self.redirect('/banner-msg-form') |
165 else: | 156 else: |
166 self.response.set_status(401, 'No user auth') | 157 self.response.set_status(401, 'No user auth') |
167 | 158 |
168 template.bootstrap({'som': os.path.dirname(__file__)}) | 159 template.bootstrap({'som': os.path.dirname(__file__)}) |
169 | 160 |
170 app = webapp2.WSGIApplication([ | 161 app = webapp2.WSGIApplication([ |
171 ('/banner-msg', BannerMessageHandler), | 162 ('/banner-msg', BannerMessageHandler), |
172 ('/banner-msg-form', BannerMessageFormHandler), | 163 ('/banner-msg-form', BannerMessageFormHandler), |
173 ]) | 164 ]) |
OLD | NEW |