Reputation: 1169
Has anybody had success implementing ApiKey for User from mongoengine.django.auth for use with tastypie ApiKeyAuthentication?
I'm aware of the previous posts on the matter, but they address ORM only, while i'm trying to set it up for mongoengine. Also, it seems that tastypie's own ApiKey class heavily relies on relational structure (using related field api_key
of User)
thanks in advance!
Upvotes: 0
Views: 308
Reputation: 1169
following this thread https://github.com/mitar/django-tastypie-mongoengine/issues/25 i've created MongoUser class with api_key field
# models.py (or documents.py)
from mongoengine.django.auth import User
class MongoUser(User):
"""
Subclass of mongoengine.django.auth.User with email as username
and API key for authentication.
"""
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['password']
api_key = StringField(max_length=256, default='')
api_key_created = DateTimeField(help_text=_(u'Created'))
def save(self, *args, **kwargs):
if not self.api_key:
self.set_api_key()
return super(MongoUser, self).save(*args, **kwargs)
def set_api_key(self):
self.api_key = self.generate_key()
self.api_key_created = datetime.now()
def generate_key(self):
new_uuid = uuid.uuid4()
return hmac.new(str(new_uuid), digestmod=sha1).hexdigest()
added a signal (the usual):
# resources.py
from mongoengine import signals
from myapp import models
signals.post_save.connect(create_api_key, sender=models.MongoUser)
and then subclassed tastypie.ApiKeyAuthentication with the following:
# resources.py
class CustomApiKeyAuthentication(ApiKeyAuthentication):
"""
Authenticates everyone if the request is GET otherwise performs
ApiKeyAuthentication.
"""
def is_mongouser_authenticated(self, request):
"""
Custom solution for MongoUser ApiKey authentication.
ApiKey here is not a class (as it is realized in ORM approach),
but a field MongoUser class.
"""
username, api_key = super(CustomApiKeyAuthentication,
self).extract_credentials(request)
try:
models.MongoUser.objects.get(username=username, api_key=api_key)
except models.MongoUser.DoesNotExist:
return False
return True
def is_authenticated(self, request, **kwargs):
"""
Custom solution for `is_authenticated` function: MongoUsers has got
authenticated through custom api_key check.
"""
if request.method == 'GET':
return True
try:
is_authenticated = super(CustomApiKeyAuthentication,
self).is_authenticated(request, **kwargs)
except TypeError as e:
if "MongoUser" in str(e):
is_authenticated = self.is_mongouser_authenticated(request)
else:
is_authenticated = False
return is_authenticated
Upvotes: 1