Merge lp:~nataliabidart/django-oauth-backend/use-own-models into lp:django-oauth-backend

Proposed by Natalia Bidart
Status: Merged
Approved by: Matias Bordese
Approved revision: 21
Merged at revision: 20
Proposed branch: lp:~nataliabidart/django-oauth-backend/use-own-models
Merge into: lp:django-oauth-backend
Diff against target: 232 lines (+87/-64)
2 files modified
oauth_backend/models.py (+70/-56)
oauth_backend/tests.py (+17/-8)
To merge this branch: bzr merge lp:~nataliabidart/django-oauth-backend/use-own-models
Reviewer Review Type Date Requested Status
Matias Bordese (community) Approve
Review via email: mp+203395@code.launchpad.net

Commit message

- Return local models instead of those from the oauth library.
- Adapt some signatures to those expected from Piston.

Description of the change

This branch ensures the loopup method from the data store will return "local" models. It also includes some cleaner methods to provide the hacks from:

http://bazaar.launchpad.net/~canonical-isd-hackers/canonical-identity-provider/trunk/view/head:/src/identityprovider/store.py

To post a comment you must log in.
Revision history for this message
Matias Bordese (matiasb) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'oauth_backend/models.py'
2--- oauth_backend/models.py 2014-01-23 14:20:45 +0000
3+++ oauth_backend/models.py 2014-01-27 18:41:15 +0000
4@@ -45,10 +45,38 @@
5 for x in range(length))
6
7
8+class Consumer(models.Model):
9+ """An OAuth consumer (client)."""
10+
11+ user = models.OneToOneField(User, related_name='oauth_consumer')
12+
13+ secret = models.CharField(
14+ max_length=255, blank=True,
15+ default=partial(generate_random_string, CONSUMER_SECRET_LENGTH)
16+ )
17+
18+ created_at = models.DateTimeField(auto_now_add=True)
19+ updated_at = models.DateTimeField(auto_now=True)
20+
21+ class Meta:
22+ db_table = 'oauth_consumer'
23+
24+ def __unicode__(self):
25+ return self.key
26+
27+ @property
28+ def key(self):
29+ return self.user.username
30+
31+ def oauth_consumer(self):
32+ """Return OAuthConsumer based on information contained in this model"""
33+ return OAuthConsumer(self.key, self.secret)
34+
35+
36 class Token(models.Model):
37 """An OAuth access token."""
38
39- consumer = models.ForeignKey('Consumer')
40+ consumer = models.ForeignKey(Consumer)
41
42 token = models.CharField(
43 max_length=TOKEN_LENGTH,
44@@ -64,6 +92,27 @@
45 created_at = models.DateTimeField(default=datetime.utcnow)
46 updated_at = models.DateTimeField(default=datetime.utcnow)
47
48+ class Meta:
49+ db_table = 'oauth_token'
50+
51+ def __unicode__(self):
52+ return self.token
53+
54+ # This class will be used from Piston oauth handlers, which assume the
55+ # Token instance have key, secret and user attributes.
56+
57+ @property
58+ def key(self):
59+ return self.token
60+
61+ @property
62+ def secret(self):
63+ return self.token_secret
64+
65+ @property
66+ def user(self):
67+ return self.consumer.user
68+
69 def oauth_token(self):
70 """Return OAuthToken with information contained in this model"""
71 return OAuthToken(self.token, self.token_secret)
72@@ -79,42 +128,6 @@
73 'updated': str(self.updated_at),
74 }
75
76- def __unicode__(self):
77- return self.token
78-
79- class Meta:
80- db_table = 'oauth_token'
81-
82-
83-class Consumer(models.Model):
84- """An OAuth consumer (client)."""
85-
86- user = models.OneToOneField(User, related_name='oauth_consumer')
87-
88- @property
89- def key(self):
90- return self.user.username
91-
92- secret = models.CharField(
93- max_length=255,
94- blank=True,
95- null=False,
96- default=partial(generate_random_string, CONSUMER_SECRET_LENGTH)
97- )
98-
99- created_at = models.DateTimeField(auto_now_add=True)
100- updated_at = models.DateTimeField(auto_now=True)
101-
102- def __unicode__(self):
103- return self.key
104-
105- def oauth_consumer(self):
106- """Return OAuthConsumer based on information contained in this model"""
107- return OAuthConsumer(self.key, self.secret)
108-
109- class Meta:
110- db_table = 'oauth_consumer'
111-
112
113 class Nonce(models.Model):
114 token = models.ForeignKey(Token)
115@@ -142,36 +155,37 @@
116
117 DEFAULT_NONCE_TIMEOUT = 3600 # one hour
118
119+ def __init__(self, oauth_request=None):
120+ """To serve as a Piston datastore we'll need provide this signature.
121+
122+ We later won't use the oauth_request, so we can ignore it here.
123+ """
124+ super(DataStore, self).__init__()
125+
126 def lookup_token(self, token_type, token_field):
127- """
128- :param token_type: type of token to lookup
129- :param token_field: token to look up
130-
131- :note: token_type should always be 'access' as only such tokens are
132- stored in database
133-
134- :returns: OAuthToken object
135+ """Return the Token object for the given token_field value.
136+
137+ The value for token_type should always be 'access' as only such tokens
138+ are stored in database.
139+
140 """
141 assert token_type == 'access'
142
143 try:
144 token = Token.objects.get(token=token_field)
145- return OAuthToken(token.token, token.token_secret)
146 except Token.DoesNotExist:
147- return None
148+ token = None
149+
150+ return token
151
152 def lookup_consumer(self, consumer_key):
153- """
154- :param consumer_key: consumer key to lookup
155-
156- :returns: OAuthConsumer object
157- """
158+ """Return the Consumer object for the given consumer_key value."""
159 try:
160- consumer = Consumer.objects.get(
161- user__username=consumer_key)
162- return consumer.oauth_consumer()
163+ consumer = Consumer.objects.get(user__username=consumer_key)
164 except Consumer.DoesNotExist:
165- return None
166+ consumer = None
167+
168+ return consumer
169
170 @property
171 def _nonce_timeout_seconds(self):
172
173=== modified file 'oauth_backend/tests.py'
174--- oauth_backend/tests.py 2014-01-23 14:58:32 +0000
175+++ oauth_backend/tests.py 2014-01-27 18:41:15 +0000
176@@ -6,8 +6,9 @@
177 from django.contrib.auth.models import User
178 from django.core.cache import cache
179 from django.test import TestCase
180+from oauth.oauth import OAuthDataStore
181
182-from .models import Consumer, DataStore, Nonce, Token, OAuthToken
183+from .models import Consumer, DataStore, Nonce, Token
184
185
186 class BaseTestCase(TestCase):
187@@ -129,20 +130,29 @@
188 consumer=self.consumer, token_key='token', token_secret='secret')
189 self.addCleanup(cache.clear)
190
191+ def test_data_store_creation_piston_compatible(self):
192+ store = DataStore(oauth_request=object())
193+ self.assertIsInstance(store, OAuthDataStore)
194+
195 def test_lookup_token_wrong_type(self):
196- self.assertRaises(AssertionError, self.ds.lookup_token, 'value',
197- 'token')
198+ self.assertRaises(
199+ AssertionError, self.ds.lookup_token, 'value', 'token')
200
201 def test_lookup_token_exists(self):
202- # create a token
203+ token = self.ds.lookup_token('access', 'token')
204+ self.assertEqual(token.token, 'token')
205+ self.assertEqual(token.token_secret, 'secret')
206+
207+ def test_lookup_token_has_expected_attributes(self):
208 token = self.ds.lookup_token('access', 'token')
209 self.assertEqual(token.key, 'token')
210 self.assertEqual(token.secret, 'secret')
211+ self.assertEqual(token.user, self.consumer.user)
212
213 def test_lookup_token_not_exists(self):
214 self.token.delete()
215 token = self.ds.lookup_token('access', 'token')
216- self.assertEqual(token, None)
217+ self.assertIsNone(token)
218
219 def test_lookup_consumer_exists(self):
220 consumer_key = self.consumer.key
221@@ -151,9 +161,8 @@
222 self.assertEqual(result.secret, self.consumer.secret)
223
224 def test_lookup_consumer_not_exists(self):
225- consumer_key = 'foo'
226- consumer = self.ds.lookup_consumer(consumer_key)
227- self.assertEqual(consumer, None)
228+ consumer = self.ds.lookup_consumer('foo')
229+ self.assertIsNone(consumer,)
230
231 def test_lookup_nonce_does_not_exist(self):
232 nonce = self.ds.lookup_nonce(self.consumer, self.token, 'nonce')

Subscribers

People subscribed via source and target branches