1 import urllib, time, urlparse
4 from django.db.models.signals import post_save, post_delete
5 from django.db import models
6 from django.contrib.auth.models import User
7 from django.contrib import admin
8 from django.core.mail import send_mail, mail_admins
11 from managers import TokenManager, ConsumerManager, ResourceManager
12 from signals import consumer_post_save, consumer_post_delete
19 ('pending', 'Pending'),
20 ('accepted', 'Accepted'),
21 ('canceled', 'Canceled'),
22 ('rejected', 'Rejected')
25 def generate_random(length=SECRET_SIZE):
26 return User.objects.make_random_password(length=length)
28 class Nonce(models.Model):
29 token_key = models.CharField(max_length=KEY_SIZE)
30 consumer_key = models.CharField(max_length=KEY_SIZE)
31 key = models.CharField(max_length=255)
33 def __unicode__(self):
34 return u"Nonce %s for %s" % (self.key, self.consumer_key)
36 admin.site.register(Nonce)
38 class Consumer(models.Model):
39 name = models.CharField(max_length=255)
40 description = models.TextField()
42 key = models.CharField(max_length=KEY_SIZE)
43 secret = models.CharField(max_length=SECRET_SIZE)
45 status = models.CharField(max_length=16, choices=CONSUMER_STATES, default='pending')
46 user = models.ForeignKey(User, null=True, blank=True, related_name='consumers')
48 objects = ConsumerManager()
50 def __unicode__(self):
51 return u"Consumer %s with key %s" % (self.name, self.key)
53 def generate_random_codes(self):
55 Used to generate random key/secret pairings. Use this after you've
56 added the other data in place of save().
59 c.name = "My consumer"
60 c.description = "An app that makes ponies from the API."
61 c.user = some_user_object
62 c.generate_random_codes()
64 key = User.objects.make_random_password(length=KEY_SIZE)
65 secret = generate_random(SECRET_SIZE)
67 while Consumer.objects.filter(key__exact=key, secret__exact=secret).count():
68 secret = generate_random(SECRET_SIZE)
74 admin.site.register(Consumer)
76 class Token(models.Model):
79 TOKEN_TYPES = ((REQUEST, u'Request'), (ACCESS, u'Access'))
81 key = models.CharField(max_length=KEY_SIZE)
82 secret = models.CharField(max_length=SECRET_SIZE)
83 verifier = models.CharField(max_length=VERIFIER_SIZE)
84 token_type = models.IntegerField(choices=TOKEN_TYPES)
85 timestamp = models.IntegerField(default=long(time.time()))
86 is_approved = models.BooleanField(default=False)
88 user = models.ForeignKey(User, null=True, blank=True, related_name='tokens')
89 consumer = models.ForeignKey(Consumer)
91 callback = models.CharField(max_length=255, null=True, blank=True)
92 callback_confirmed = models.BooleanField(default=False)
94 objects = TokenManager()
96 def __unicode__(self):
97 return u"%s Token %s for %s" % (self.get_token_type_display(), self.key, self.consumer)
99 def to_string(self, only_key=False):
101 'oauth_token': self.key,
102 'oauth_token_secret': self.secret,
103 'oauth_callback_confirmed': 'true',
107 token_dict.update({ 'oauth_verifier': self.verifier })
110 del token_dict['oauth_token_secret']
112 return urllib.urlencode(token_dict)
114 def generate_random_codes(self):
115 key = User.objects.make_random_password(length=KEY_SIZE)
116 secret = generate_random(SECRET_SIZE)
118 while Token.objects.filter(key__exact=key, secret__exact=secret).count():
119 secret = generate_random(SECRET_SIZE)
125 # -- OAuth 1.0a stuff
127 def get_callback_url(self):
128 if self.callback and self.verifier:
129 # Append the oauth_verifier.
130 parts = urlparse.urlparse(self.callback)
131 scheme, netloc, path, params, query, fragment = parts[:6]
133 query = '%s&oauth_verifier=%s' % (query, self.verifier)
135 query = 'oauth_verifier=%s' % self.verifier
136 return urlparse.urlunparse((scheme, netloc, path, params,
140 def set_callback(self, callback):
141 if callback != "oob": # out of band, says "we can't do this!"
142 self.callback = callback
143 self.callback_confirmed = True
146 admin.site.register(Token)
149 post_save.connect(consumer_post_save, sender=Consumer)
150 post_delete.connect(consumer_post_delete, sender=Consumer)