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.

Clone this repository (size: 114.7 KB): HTTPS / SSH
$ hg clone http://code.welldev.org/django-oauth
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
David Larlet / david
12 months ago

Changed (Δ1.9 KB):

raw changeset »

oauth_provider/consts.py (15 lines added, 0 lines removed)

oauth_provider/models.py (58 lines added, 12 lines removed)

Up to file-list oauth_provider/consts.py:

1
from django.utils.translation import ugettext_lazy as _
2
1
3
KEY_SIZE = 16
2
4
SECRET_SIZE = 16
5
VERIFIER_SIZE = 10
3
6
CONSUMER_KEY_SIZE = 256
7
8
PENDING = 1
9
ACCEPTED = 2
10
CANCELED = 3
11
REJECTED = 4
12
13
CONSUMER_STATES = (
14
    (PENDING,  _('Pending')),
15
    (ACCEPTED, _('Accepted')),
16
    (CANCELED, _('Canceled')),
17
    (REJECTED, _('Rejected')),
18
)

Up to file-list oauth_provider/models.py:

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