# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""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.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import six

from google.appengine.api import memcache
from google.appengine.ext import ndb

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)
  pagination_key = ndb.StringProperty(required=True)


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()
  secrets.pagination_key = framework_helpers.MakeRandomKey()
  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 six.ensure_binary(GetSecrets().xsrf_key)


def GetEmailKey():
  """Return a secret key string used to generate email tokens."""
  return six.ensure_binary(GetSecrets().email_key)


def GetPaginationKey():
  """Return a secret key string used to generate pagination tokens."""
  return six.ensure_binary(GetSecrets().pagination_key)
