blob: 18a4a28bf51bd98bedcf646d334a9eee59d64738 [file] [log] [blame]
Joe Gregorio7c22ab22011-02-16 15:32:39 -05001# Copyright 2010 Google Inc. All Rights Reserved.
2
3"""OAuth 2.0 utilities for Django.
4
5Utilities for using OAuth 2.0 in conjunction with
6the Django datastore.
7"""
8
9__author__ = 'jcgregorio@google.com (Joe Gregorio)'
10
Joe Gregoriofc1e2782011-02-15 16:04:03 -050011import oauth2client
12import base64
13import pickle
14
Joe Gregorio695fdc12011-01-16 16:46:55 -050015from django.db import models
Joe Gregoriodeeb0202011-02-15 14:49:57 -050016from oauth2client.client import Storage as BaseStorage
Joe Gregorio695fdc12011-01-16 16:46:55 -050017
18class CredentialsField(models.Field):
19
20 __metaclass__ = models.SubfieldBase
21
22 def db_type(self):
23 return 'VARCHAR'
24
25 def to_python(self, value):
Joe Gregoriofc1e2782011-02-15 16:04:03 -050026 if not value:
Joe Gregorio695fdc12011-01-16 16:46:55 -050027 return None
Joe Gregoriofc1e2782011-02-15 16:04:03 -050028 if isinstance(value, oauth2client.client.Credentials):
Joe Gregorio695fdc12011-01-16 16:46:55 -050029 return value
30 return pickle.loads(base64.b64decode(value))
31
32 def get_db_prep_value(self, value):
33 return base64.b64encode(pickle.dumps(value))
34
35
36class FlowField(models.Field):
37
38 __metaclass__ = models.SubfieldBase
39
40 def db_type(self):
41 return 'VARCHAR'
42
43 def to_python(self, value):
Joe Gregorio695fdc12011-01-16 16:46:55 -050044 if value is None:
45 return None
Joe Gregoriofc1e2782011-02-15 16:04:03 -050046 if isinstance(value, oauth2client.client.Flow):
Joe Gregorio695fdc12011-01-16 16:46:55 -050047 return value
48 return pickle.loads(base64.b64decode(value))
49
50 def get_db_prep_value(self, value):
51 return base64.b64encode(pickle.dumps(value))
Joe Gregoriodeeb0202011-02-15 14:49:57 -050052
53
54class Storage(BaseStorage):
55 """Store and retrieve a single credential to and from
56 the datastore.
57
58 This Storage helper presumes the Credentials
59 have been stored as a CredenialsField
60 on a db model class.
61 """
62
63 def __init__(self, model_class, key_name, key_value, property_name):
64 """Constructor for Storage.
65
66 Args:
67 model: db.Model, model class
68 key_name: string, key name for the entity that has the credentials
69 key_value: string, key value for the entity that has the credentials
70 property_name: string, name of the property that is an CredentialsProperty
71 """
72 self.model_class = model_class
73 self.key_name = key_name
74 self.key_value = key_value
75 self.property_name = property_name
76
77 def get(self):
78 """Retrieve Credential from datastore.
79
80 Returns:
81 oauth2client.Credentials
82 """
Joe Gregoriofc1e2782011-02-15 16:04:03 -050083 credential = None
84
Joe Gregoriodeeb0202011-02-15 14:49:57 -050085 query = {self.key_name: self.key_value}
Joe Gregoriofc1e2782011-02-15 16:04:03 -050086 entities = self.model_class.objects.filter(**query)
87 if len(entities) > 0:
88 credential = getattr(entities[0], self.property_name)
89 if credential and hasattr(credential, 'set_store'):
90 credential.set_store(self.put)
Joe Gregoriodeeb0202011-02-15 14:49:57 -050091 return credential
92
93 def put(self, credentials):
94 """Write a Credentials to the datastore.
95
96 Args:
97 credentials: Credentials, the credentials to store.
98 """
Joe Gregoriofc1e2782011-02-15 16:04:03 -050099 args = {self.key_name: self.key_value}
100 entity = self.model_class(**args)
Joe Gregoriodeeb0202011-02-15 14:49:57 -0500101 setattr(entity, self.property_name, credentials)
102 entity.save()