Permalink
Browse files

pin verification is a real resource (bug 807537)

  • Loading branch information...
1 parent 3da2e21 commit 3deada966d9bb36732eba2be4eb6fa76f1259330 @wraithan wraithan committed Dec 5, 2012
Showing with 83 additions and 89 deletions.
  1. +13 −5 lib/buyers/forms.py
  2. +32 −3 lib/buyers/resources.py
  3. +35 −28 lib/buyers/tests/test_api.py
  4. +0 −32 lib/buyers/tests/test_views.py
  5. +0 −18 lib/buyers/views.py
  6. +3 −3 solitude/urls.py
View
@@ -1,14 +1,11 @@
from django import forms
+
from tastypie.validation import FormValidation
from .models import Buyer
-class BuyerValidation(forms.ModelForm):
-
- class Meta:
- model = Buyer
-
+class PinMixin(object):
def clean_pin(self):
pin = self.cleaned_data['pin']
@@ -24,6 +21,17 @@ def clean_pin(self):
return pin
+class BuyerForm(forms.ModelForm, PinMixin):
+
+ class Meta:
+ model = Buyer
+
+
+class BuyerVerifyPinForm(forms.Form, PinMixin):
+ uuid = forms.CharField(required=True)
+ pin = forms.CharField(required=True)
+
+
class BuyerFormValidation(FormValidation):
def is_valid(self, bundle, request=None):
data = bundle.data
View
@@ -1,9 +1,10 @@
from django.core.urlresolvers import resolve
-from solitude.base import ModelResource
+from solitude.base import get_object_or_404, ModelResource, Resource
from tastypie import fields
+from tastypie.validation import FormValidation
-from .forms import BuyerFormValidation, BuyerValidation
+from .forms import BuyerForm, BuyerFormValidation, BuyerVerifyPinForm
from .models import Buyer, BuyerPaypal
@@ -18,7 +19,7 @@ class Meta(ModelResource.Meta):
list_allowed_methods = ['get', 'post', 'put']
allowed_methods = ['get', 'patch', 'put']
resource_name = 'buyer'
- validation = BuyerFormValidation(form_class=BuyerValidation)
+ validation = BuyerFormValidation(form_class=BuyerForm)
filtering = {
'uuid': 'exact',
}
@@ -54,3 +55,31 @@ class Meta(ModelResource.Meta):
list_allowed_methods = ['post']
allowed_methods = ['get', 'delete', 'patch']
resource_name = 'buyer'
+
+
+class BuyerVerifyPin(object):
+ pk = 'verify_pin'
+ uuid = 'fake'
+ valid = False
+
+
+class BuyerVerifyPinResource(Resource):
+ uuid = fields.CharField(attribute='uuid')
+ valid = fields.BooleanField(attribute='valid')
+
+ class Meta(Resource.Meta):
+ allowed_methods = ('post')
+ resource_name = 'verify_pin'
+ object_class = BuyerVerifyPin
+ validation = FormValidation(form_class=BuyerVerifyPinForm)
+
+ def obj_create(self, bundle, request=None, **kwargs):
+ bundle.obj = BuyerVerifyPin()
+ buyer = get_object_or_404(Buyer, uuid=bundle.data['uuid'])
+ bundle.obj.uuid = bundle.data['uuid']
+ bundle.obj.valid = buyer.pin == bundle.data.pop('pin')
+ return bundle
+
+ def get_resource_uri(self, bundle_or_obj):
+ # Needed as this isn't a model resource.
+ return 'no_uri'
@@ -1,6 +1,5 @@
import json
-from django.core.urlresolvers import reverse
from nose.tools import eq_
from lib.buyers.models import Buyer, BuyerPaypal
@@ -102,33 +101,6 @@ def test_patch_same_uuid(self):
eq_(obj.reget().uuid, self.uuid)
-class TestPinValidator(APITest):
-
- def setUp(self):
- self.api_name = 'generic'
- self.uuid = 'sample:uid'
- self.pin = '1234'
- self.validator_url = reverse('check-pin')
-
- def test_post_only(self):
- res = self.client.get(self.validator_url)
- eq_(res.status_code, 405)
-
- def test_valid_pin(self):
- Buyer.objects.create(uuid=self.uuid, pin=self.pin)
- res = self.client.post(self.validator_url, data={'uuid': self.uuid,
- 'pin': self.pin})
- eq_(res.status_code, 200)
- eq_(json.loads(res.content)['valid'], True)
-
- def test_invalid_pin(self):
- Buyer.objects.create(uuid=self.uuid, pin=self.pin)
- res = self.client.post(self.validator_url, data={'uuid': self.uuid,
- 'pin': 'bad pin'})
- eq_(res.status_code, 200)
- eq_(json.loads(res.content)['valid'], False)
-
-
class TestBuyerPaypal(APITest):
def setUp(self):
@@ -207,3 +179,38 @@ def test_patch_key(self):
obj.save()
self.client.patch(url, data={'key': ''})
eq_(BuyerPaypal.objects.get(pk=obj.pk).key, None)
+
+
+class TestBuyerVerifyPin(APITest):
+
+ def setUp(self):
+ self.api_name = 'generic'
+ self.uuid = 'sample:uid'
+ self.pin = '1234'
+ self.buyer = Buyer.objects.create(uuid=self.uuid, pin=self.pin)
+ self.list_url = self.get_list_url('verify_pin')
+
+ def test_good_uuid_and_pin(self):
+ res = self.client.post(self.list_url, data={'uuid': self.uuid,
+ 'pin': self.pin})
+ eq_(res.status_code, 201)
+ data = json.loads(res.content)
+ assert data['valid']
+ eq_(data['uuid'], self.uuid)
+
+ def test_good_uuid_and_bad_pin(self):
+ res = self.client.post(self.list_url, data={'uuid': self.uuid,
+ 'pin': '4321'})
+ eq_(res.status_code, 201)
+ data = json.loads(res.content)
+ assert not data['valid']
+ eq_(data['uuid'], self.uuid)
+
+ def test_bad_uuid(self):
+ res = self.client.post(self.list_url, data={'uuid': 'bad:uuid',
+ 'pin': '4321'})
+ eq_(res.status_code, 404)
+
+ def test_empty_post(self):
+ res = self.client.post(self.list_url, data={})
+ eq_(res.status_code, 400)
@@ -1,32 +0,0 @@
-import json
-
-from django.test import TestCase
-from django.core.urlresolvers import reverse
-
-from lib.buyers.models import Buyer
-
-
-class CheckPinTest(TestCase):
-
- def setUp(self):
- self.url = reverse('check-pin')
- self.uuid = 'a:uuid'
- self.pin = '5678'
-
- def test_good_pin(self):
- Buyer.objects.create(uuid=self.uuid, pin=self.pin)
- res = self.client.post(self.url,
- json.dumps({'uuid': self.uuid, 'pin': self.pin}),
- content_type='application/octet-stream')
- data = json.loads(res.content)
- assert 'valid' in data
- assert data['valid']
-
- def test_bad_pin(self):
- Buyer.objects.create(uuid=self.uuid, pin=self.pin)
- res = self.client.post(self.url,
- json.dumps({'uuid': self.uuid, 'pin': 'lame'}),
- content_type='application/octet-stream')
- data = json.loads(res.content)
- assert 'valid' in data
- assert not data['valid']
View
@@ -1,18 +0,0 @@
-import json
-
-from django.http import HttpResponse
-from django.views.decorators.http import require_POST
-
-from .models import Buyer
-
-
-@require_POST
-def check_pin(request):
- data = json.loads(request.body)
- try:
- buyer = Buyer.objects.get(uuid=data['uuid'])
- result = buyer.pin.check(data['pin'])
- except Buyer.DoesNotExist:
- result = False
- return HttpResponse(json.dumps({'valid': result}),
- mimetype='application/json')
View
@@ -4,8 +4,8 @@
from tastypie.api import Api
from lib.bango.urls import bango
-from lib.buyers.resources import BuyerResource, BuyerPaypalResource
-from lib.buyers.views import check_pin
+from lib.buyers.resources import (BuyerResource, BuyerPaypalResource,
+ BuyerVerifyPinResource)
from lib.paypal.urls import paypal
from lib.sellers.resources import (SellerResource, SellerPaypalResource,
SellerProductResource)
@@ -16,6 +16,7 @@
# Generic APIs
api = Api(api_name='generic')
api.register(BuyerResource())
+api.register(BuyerVerifyPinResource())
api.register(SellerResource())
api.register(SellerProductResource())
api.register(TransactionResource())
@@ -37,7 +38,6 @@
url(r'^', include(paypal.urls)),
url(r'^', include(bango.urls)),
url(r'^', include(service.urls)),
- url(r'^buyer/check_pin', check_pin, name='check-pin'),
url(r'^$', 'solitude.views.home', name='home'),
)

0 comments on commit 3deada9

Please sign in to comment.