david / django-oauth (http://oauth.net/)
Support of OAuth in Django. Note that http://code.welldev.org/django-oauth-plus will use python-oauth2 if you're interested in it.
| commit 28: | 8579a1562b16 |
| parent 27: | c038f3e47c5f |
| branch: | default |
Update models (stolen from piston) to be 1.0a ready, note that it will affect your Token/Consumer tables
12 months ago
django-oauth /
oauth_provider
/
models.py
| # Introduced |
|---|
1 |
c3ff630fbbb4 |
import urllib |
2 |
8579a1562b16 |
import urlparse |
3 |
8579a1562b16 |
from time import time |
4 |
c3ff630fbbb4 |
|
5 |
c3ff630fbbb4 |
from django.db import models |
6 |
c3ff630fbbb4 |
from django.contrib.auth.models import User |
7 |
c3ff630fbbb4 |
|
8 |
c3ff630fbbb4 |
from managers import TokenManager, ConsumerManager, ResourceManager |
9 |
8579a1562b16 |
from consts import KEY_SIZE, SECRET_SIZE, CONSUMER_KEY_SIZE, CONSUMER_STATES,\ |
10 |
8579a1562b16 |
PENDING, VERIFIER_SIZE |
11 |
c3ff630fbbb4 |
|
12 |
8579a1562b16 |
generate_random = User.objects.make_random_password |
13 |
c3ff630fbbb4 |
|
14 |
c3ff630fbbb4 |
class Nonce(models.Model): |
15 |
c3ff630fbbb4 |
token_key = models.CharField(max_length=KEY_SIZE) |
16 |
f6dd3126f023 |
consumer_key = models.CharField(max_length=CONSUMER_KEY_SIZE) |
17 |
c3ff630fbbb4 |
key = models.CharField(max_length=255) |
18 |
c3ff630fbbb4 |
|
19 |
c3ff630fbbb4 |
def __unicode__(self): |
20 |
c3ff630fbbb4 |
return u"Nonce %s for %s" % (self.key, self.consumer_key) |
21 |
c3ff630fbbb4 |
|
22 |
c3ff630fbbb4 |
|
23 |
c3ff630fbbb4 |
class Resource(models.Model): |
24 |
c3ff630fbbb4 |
name = models.CharField(max_length=255) |
25 |
c3ff630fbbb4 |
url = models.TextField(max_length=2047) |
26 |
c3ff630fbbb4 |
is_readonly = models.BooleanField(default=True) |
27 |
c3ff630fbbb4 |
|
28 |
c3ff630fbbb4 |
objects = ResourceManager() |
29 |
c3ff630fbbb4 |
|
30 |
c3ff630fbbb4 |
def __unicode__(self): |
31 |
c3ff630fbbb4 |
return u"Resource %s with url %s" % (self.name, self.url) |
32 |
c3ff630fbbb4 |
|
33 |
c3ff630fbbb4 |
|
34 |
c3ff630fbbb4 |
class Consumer(models.Model): |
35 |
c3ff630fbbb4 |
name = models.CharField(max_length=255) |
36 |
8579a1562b16 |
description = models.TextField() |
37 |
8579a1562b16 |
|
38 |
f6dd3126f023 |
key = models.CharField(max_length=CONSUMER_KEY_SIZE) |
39 |
616f3b587327 |
secret = models.CharField(max_length=SECRET_SIZE, blank=True) |
40 |
8579a1562b16 |
|
41 |
8579a1562b16 |
status = models.SmallIntegerField(choices=CONSUMER_STATES, default=PENDING) |
42 |
c3ff630fbbb4 |
user = models.ForeignKey(User, null=True, blank=True) |
43 |
c3ff630fbbb4 |
|
44 |
c3ff630fbbb4 |
objects = ConsumerManager() |
45 |
c3ff630fbbb4 |
|
46 |
c3ff630fbbb4 |
def __unicode__(self): |
47 |
c3ff630fbbb4 |
return u"Consumer %s with key %s" % (self.name, self.key) |
48 |
c3ff630fbbb4 |
|
49 |
c3ff630fbbb4 |
def generate_random_codes(self): |
50 |
8579a1562b16 |
""" |
51 |
8579a1562b16 |
Used to generate random key/secret pairings. |
52 |
8579a1562b16 |
Use this after you've added the other data in place of save(). |
53 |
8579a1562b16 |
""" |
54 |
8579a1562b16 |
key = generate_random(length=KEY_SIZE) |
55 |
8579a1562b16 |
secret = generate_random(length=SECRET_SIZE) |
56 |
c3ff630fbbb4 |
while Consumer.objects.filter(key__exact=key, secret__exact=secret).count(): |
57 |
8579a1562b16 |
secret = generate_random(length=SECRET_SIZE) |
58 |
c3ff630fbbb4 |
self.key = key |
59 |
c3ff630fbbb4 |
self.secret = secret |
60 |
c3ff630fbbb4 |
self.save() |
61 |
c3ff630fbbb4 |
|
62 |
c3ff630fbbb4 |
|
63 |
c3ff630fbbb4 |
class Token(models.Model): |
64 |
c3ff630fbbb4 |
REQUEST = 1 |
65 |
c3ff630fbbb4 |
ACCESS = 2 |
66 |
c3ff630fbbb4 |
TOKEN_TYPES = ((REQUEST, u'Request'), (ACCESS, u'Access')) |
67 |
c3ff630fbbb4 |
|
68 |
c3ff630fbbb4 |
key = models.CharField(max_length=KEY_SIZE) |
69 |
c3ff630fbbb4 |
secret = models.CharField(max_length=SECRET_SIZE) |
70 |
8579a1562b16 |
token_type = models.SmallIntegerField(choices=TOKEN_TYPES) |
71 |
8579a1562b16 |
timestamp = models.IntegerField(default=long(time())) |
72 |
c3ff630fbbb4 |
is_approved = models.BooleanField(default=False) |
73 |
c3ff630fbbb4 |
|
74 |
8579a1562b16 |
user = models.ForeignKey(User, null=True, blank=True, related_name='tokens') |
75 |
c3ff630fbbb4 |
consumer = models.ForeignKey(Consumer) |
76 |
c3ff630fbbb4 |
resource = models.ForeignKey(Resource) |
77 |
c3ff630fbbb4 |
|
78 |
8579a1562b16 |
## OAuth 1.0a stuff |
79 |
8579a1562b16 |
verifier = models.CharField(max_length=VERIFIER_SIZE) |
80 |
8579a1562b16 |
callback = models.CharField(max_length=255, null=True, blank=True) |
81 |
8579a1562b16 |
callback_confirmed = models.BooleanField(default=False) |
82 |
8579a1562b16 |
|
83 |
c3ff630fbbb4 |
objects = TokenManager() |
84 |
c3ff630fbbb4 |
|
85 |
c3ff630fbbb4 |
def __unicode__(self): |
86 |
c3ff630fbbb4 |
return u"%s Token %s for %s" % (self.get_token_type_display(), self.key, self.consumer) |
87 |
c3ff630fbbb4 |
|
88 |
c3ff630fbbb4 |
def to_string(self, only_key=False): |
89 |
c3ff630fbbb4 |
token_dict = { |
90 |
c3ff630fbbb4 |
'oauth_token': self.key, |
91 |
8579a1562b16 |
'oauth_token_secret': self.secret, |
92 |
8579a1562b16 |
'oauth_callback_confirmed': 'true', |
93 |
c3ff630fbbb4 |
} |
94 |
8579a1562b16 |
if self.verifier: |
95 |
8579a1562b16 |
token_dict.update({ 'oauth_verifier': self.verifier }) |
96 |
8579a1562b16 |
|
97 |
c3ff630fbbb4 |
if only_key: |
98 |
c3ff630fbbb4 |
del token_dict['oauth_token_secret'] |
99 |
8579a1562b16 |
|
100 |
c3ff630fbbb4 |
return urllib.urlencode(token_dict) |
101 |
c3ff630fbbb4 |
|
102 |
c3ff630fbbb4 |
def generate_random_codes(self): |
103 |
8579a1562b16 |
""" |
104 |
8579a1562b16 |
Used to generate random key/secret pairings. |
105 |
8579a1562b16 |
Use this after you've added the other data in place of save(). |
106 |
8579a1562b16 |
""" |
107 |
8579a1562b16 |
key = generate_random(length=KEY_SIZE) |
108 |
8579a1562b16 |
secret = generate_random(length=SECRET_SIZE) |
109 |
c3ff630fbbb4 |
while Token.objects.filter(key__exact=key, secret__exact=secret).count(): |
110 |
8579a1562b16 |
secret = generate_random(length=SECRET_SIZE) |
111 |
c3ff630fbbb4 |
self.key = key |
112 |
c3ff630fbbb4 |
self.secret = secret |
113 |
c3ff630fbbb4 |
self.save() |
114 |
8579a1562b16 |
|
115 |
8579a1562b16 |
## OAuth 1.0a stuff |
116 |
8579a1562b16 |
|
117 |
8579a1562b16 |
def get_callback_url(self): |
118 |
8579a1562b16 |
if self.callback and self.verifier: |
119 |
8579a1562b16 |
# Append the oauth_verifier. |
120 |
8579a1562b16 |
parts = urlparse.urlparse(self.callback) |
121 |
8579a1562b16 |
scheme, netloc, path, params, query, fragment = parts[:6] |
122 |
8579a1562b16 |
if query: |
123 |
8579a1562b16 |
query = '%s&oauth_verifier=%s' % (query, self.verifier) |
124 |
8579a1562b16 |
else: |
125 |
8579a1562b16 |
query = 'oauth_verifier=%s' % self.verifier |
126 |
8579a1562b16 |
return urlparse.urlunparse((scheme, netloc, path, params, |
127 |
8579a1562b16 |
query, fragment)) |
128 |
8579a1562b16 |
return self.callback |
129 |
8579a1562b16 |
|
130 |
8579a1562b16 |
def set_callback(self, callback): |
131 |
8579a1562b16 |
if callback != "oob": # out of band, says "we can't do this!" |
132 |
8579a1562b16 |
self.callback = callback |
133 |
8579a1562b16 |
self.callback_confirmed = True |
134 |
8579a1562b16 |
self.save() |
