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

Unified Diff: appengine/monorail/services/secrets_svc.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « appengine/monorail/services/project_svc.py ('k') | appengine/monorail/services/service_manager.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/monorail/services/secrets_svc.py
diff --git a/appengine/monorail/services/secrets_svc.py b/appengine/monorail/services/secrets_svc.py
new file mode 100644
index 0000000000000000000000000000000000000000..cfb5df291627c63514f510aec11ec8fac601f5a0
--- /dev/null
+++ b/appengine/monorail/services/secrets_svc.py
@@ -0,0 +1,110 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is govered by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""A set of functions that provide persistence for secret keys.
+
+These keys are used in generating XSRF tokens, calling the CAPTCHA API,
+and validating that inbound emails are replies to notifications that
+we sent.
+
+Unlike other data stored in Monorail, this is kept in the GAE
+datastore rather than SQL because (1) it never needs to be used in
+combination with other SQL data, and (2) we may want to replicate
+issue content for various off-line reporting functionality, but we
+will never want to do that with these keys. A copy is also kept in
+memcache for faster access.
+
+When no secrets are found, a new Secrets entity is created and initialized
+with randomly generated values for XSRF and email keys.
+
+If these secret values ever need to change:
+(1) Make the change on the Google Cloud Console in the Cloud Datastore tab.
+(2) Flush memcache.
+"""
+
+import logging
+
+from google.appengine.api import memcache
+from google.appengine.ext import ndb
+
+import settings
+from framework import framework_helpers
+
+
+GLOBAL_KEY = 'secrets_singleton_key'
+
+
+class Secrets(ndb.Model):
+ """Model for representing secret keys."""
+ # Keys we use to generate tokens.
+ xsrf_key = ndb.StringProperty(required=True)
+ email_key = ndb.StringProperty(required=True)
+
+ # Keys for other APIs that we use.
+ recaptcha_public_key = ndb.StringProperty()
+ recaptcha_private_key = ndb.StringProperty()
+
+
+def MakeSecrets():
+ """Make a new Secrets model with random values for keys."""
+ secrets = Secrets(id=GLOBAL_KEY)
+ secrets.xsrf_key = framework_helpers.MakeRandomKey()
+ secrets.email_key = framework_helpers.MakeRandomKey()
+ # Note that recaptcha keys are not generated. An admin
+ # will need to set them via the Google Cloud Console.
+ return secrets
+
+
+def GetSecrets():
+ """Get secret keys from memcache or datastore. Or, make new ones."""
+ secrets = memcache.get(GLOBAL_KEY)
+ if secrets:
+ return secrets
+
+ secrets = Secrets.get_by_id(GLOBAL_KEY)
+ if not secrets:
+ secrets = MakeSecrets()
+ secrets.put()
+
+ memcache.set(GLOBAL_KEY, secrets)
+ return secrets
+
+
+def GetXSRFKey():
+ """Return a secret key string used to generate XSRF tokens."""
+ return GetSecrets().xsrf_key
+
+
+def GetEmailKey():
+ """Return a secret key string used to generate email tokens."""
+ return GetSecrets().email_key
+
+
+def GetRecaptchaPublicKey():
+ """Return our public API key for reCAPTCHA."""
+ if settings.dev_mode:
+ return '6LebzNMSAAAAAMY8b_FaZvp8wymUO5Jsa0pIX7HO'
+
+ result = GetSecrets().recaptcha_public_key
+ if not result:
+ logging.warn('No recaptcha_public_key set. Get one at recaptcha.net.')
+ logging.warn('Store it in Cloud Datastore via the Google Cloud Console.')
+
+ return result
+
+
+def GetRecaptchaPrivateKey():
+ """Return our private API key for reCAPTCHA."""
+ if settings.dev_mode:
+ return '6LebzNMSAAAAAHNVNiP2I7aNMv2AmxY5nReE2LZ4'
+
+ result = GetSecrets().recaptcha_private_key
+ if not result:
+ logging.warn('No recaptcha_private_key set. Get one at recaptcha.net.')
+ logging.warn('Store it in Cloud Datastore via the Google Cloud Console.')
+
+ return result
+
+
« no previous file with comments | « appengine/monorail/services/project_svc.py ('k') | appengine/monorail/services/service_manager.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698