• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 Google Inc. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Google App Engine utilities helper.
16
17Classes that directly require App Engine's ndb library. Provided
18as a separate module in case of failure to import ndb while
19other App Engine libraries are present.
20"""
21
22import logging
23
24from google.appengine.ext import ndb
25
26from oauth2client import client
27
28
29NDB_KEY = ndb.Key
30"""Key constant used by :mod:`oauth2client.contrib.appengine`."""
31
32NDB_MODEL = ndb.Model
33"""Model constant used by :mod:`oauth2client.contrib.appengine`."""
34
35_LOGGER = logging.getLogger(__name__)
36
37
38class SiteXsrfSecretKeyNDB(ndb.Model):
39    """NDB Model for storage for the sites XSRF secret key.
40
41    Since this model uses the same kind as SiteXsrfSecretKey, it can be
42    used interchangeably. This simply provides an NDB model for interacting
43    with the same data the DB model interacts with.
44
45    There should only be one instance stored of this model, the one used
46    for the site.
47    """
48    secret = ndb.StringProperty()
49
50    @classmethod
51    def _get_kind(cls):
52        """Return the kind name for this class."""
53        return 'SiteXsrfSecretKey'
54
55
56class FlowNDBProperty(ndb.PickleProperty):
57    """App Engine NDB datastore Property for Flow.
58
59    Serves the same purpose as the DB FlowProperty, but for NDB models.
60    Since PickleProperty inherits from BlobProperty, the underlying
61    representation of the data in the datastore will be the same as in the
62    DB case.
63
64    Utility property that allows easy storage and retrieval of an
65    oauth2client.Flow
66    """
67
68    def _validate(self, value):
69        """Validates a value as a proper Flow object.
70
71        Args:
72            value: A value to be set on the property.
73
74        Raises:
75            TypeError if the value is not an instance of Flow.
76        """
77        _LOGGER.info('validate: Got type %s', type(value))
78        if value is not None and not isinstance(value, client.Flow):
79            raise TypeError(
80                'Property {0} must be convertible to a flow '
81                'instance; received: {1}.'.format(self._name, value))
82
83
84class CredentialsNDBProperty(ndb.BlobProperty):
85    """App Engine NDB datastore Property for Credentials.
86
87    Serves the same purpose as the DB CredentialsProperty, but for NDB
88    models. Since CredentialsProperty stores data as a blob and this
89    inherits from BlobProperty, the data in the datastore will be the same
90    as in the DB case.
91
92    Utility property that allows easy storage and retrieval of Credentials
93    and subclasses.
94    """
95
96    def _validate(self, value):
97        """Validates a value as a proper credentials object.
98
99        Args:
100            value: A value to be set on the property.
101
102        Raises:
103            TypeError if the value is not an instance of Credentials.
104        """
105        _LOGGER.info('validate: Got type %s', type(value))
106        if value is not None and not isinstance(value, client.Credentials):
107            raise TypeError(
108                'Property {0} must be convertible to a credentials '
109                'instance; received: {1}.'.format(self._name, value))
110
111    def _to_base_type(self, value):
112        """Converts our validated value to a JSON serialized string.
113
114        Args:
115            value: A value to be set in the datastore.
116
117        Returns:
118            A JSON serialized version of the credential, else '' if value
119            is None.
120        """
121        if value is None:
122            return ''
123        else:
124            return value.to_json()
125
126    def _from_base_type(self, value):
127        """Converts our stored JSON string back to the desired type.
128
129        Args:
130            value: A value from the datastore to be converted to the
131                   desired type.
132
133        Returns:
134            A deserialized Credentials (or subclass) object, else None if
135            the value can't be parsed.
136        """
137        if not value:
138            return None
139        try:
140            # Uses the from_json method of the implied class of value
141            credentials = client.Credentials.new_from_json(value)
142        except ValueError:
143            credentials = None
144        return credentials
145
146
147class CredentialsNDBModel(ndb.Model):
148    """NDB Model for storage of OAuth 2.0 Credentials
149
150    Since this model uses the same kind as CredentialsModel and has a
151    property which can serialize and deserialize Credentials correctly, it
152    can be used interchangeably with a CredentialsModel to access, insert
153    and delete the same entities. This simply provides an NDB model for
154    interacting with the same data the DB model interacts with.
155
156    Storage of the model is keyed by the user.user_id().
157    """
158    credentials = CredentialsNDBProperty()
159
160    @classmethod
161    def _get_kind(cls):
162        """Return the kind name for this class."""
163        return 'CredentialsModel'
164