blob: df4de79020275d02a007d46b21565754bd0d30cb [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Decorator that validates XSRF tokens."""
import os
from google.appengine.api import users
from google.appengine.ext import ndb
from oauth2client import xsrfutil
class XsrfSecretKey(ndb.Model):
"""Stores a secret XSRF key for the site."""
token = ndb.StringProperty(indexed=False)
def _ValidateToken(token, user):
"""Validates an XSRF token generated by GenerateXsrfToken."""
return xsrfutil.validate_token(
_GetSecretKey(), token, user_id=user.user_id(), action_id='')
def GenerateToken(user):
return xsrfutil.generate_token(
_GetSecretKey(), user_id=user.user_id(), action_id='')
def _GenerateNewSecretKey():
"""Returns a random XSRF secret key."""
return str(os.urandom(16).encode('hex'))
def _GetSecretKey():
"""Gets or creates the secret key to use for validating XSRF tokens."""
key_entity = ndb.Key('XsrfSecretKey', 'site').get()
if not key_entity:
key_entity = XsrfSecretKey(id='site', token=_GenerateNewSecretKey())
key_entity.put()
return key_entity.token.encode('ascii', 'ignore')
def TokenRequired(handler_method):
"""A decorator to require that the XSRF token be validated for the handler."""
def CheckToken(self, *args, **kwargs):
user = users.get_current_user()
token = str(self.request.get('xsrf_token'))
if not user or not _ValidateToken(token, user):
self.abort(403)
handler_method(self, *args, **kwargs)
return CheckToken