mirror of https://github.com/snachodog/mybuddy.git
Add per-user token-based API authentication.
This commit is contained in:
parent
e9a80504e2
commit
a9c0757b4d
|
@ -7,6 +7,8 @@ from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils.timezone import timedelta
|
from django.utils.timezone import timedelta
|
||||||
|
|
||||||
|
from rest_framework.authtoken.models import Token
|
||||||
|
|
||||||
|
|
||||||
class Settings(models.Model):
|
class Settings(models.Model):
|
||||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||||
|
@ -30,6 +32,16 @@ class Settings(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{}\'s Settings'.format(self.user)
|
return '{}\'s Settings'.format(self.user)
|
||||||
|
|
||||||
|
def api_key(self, reset=False):
|
||||||
|
"""
|
||||||
|
Get or create an API key for the associated user.
|
||||||
|
:param reset: If True, delete the existing key and create a new one.
|
||||||
|
:return: The user's API key.
|
||||||
|
"""
|
||||||
|
if reset:
|
||||||
|
Token.objects.get(user=self.user).delete()
|
||||||
|
return Token.objects.get_or_create(user=self.user)[0]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dashboard_refresh_rate_milliseconds(self):
|
def dashboard_refresh_rate_milliseconds(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -35,6 +35,7 @@ INSTALLED_APPS = [
|
||||||
|
|
||||||
'django_filters',
|
'django_filters',
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
|
'rest_framework.authtoken',
|
||||||
'widget_tweaks',
|
'widget_tweaks',
|
||||||
'easy_thumbnails',
|
'easy_thumbnails',
|
||||||
|
|
||||||
|
@ -144,6 +145,10 @@ WHITENOISE_ROOT = os.path.join(BASE_DIR, 'static', 'root')
|
||||||
# http://www.django-rest-framework.org/#
|
# http://www.django-rest-framework.org/#
|
||||||
|
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
|
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||||
|
'rest_framework.authentication.SessionAuthentication',
|
||||||
|
'rest_framework.authentication.TokenAuthentication',
|
||||||
|
],
|
||||||
'DEFAULT_FILTER_BACKENDS': [
|
'DEFAULT_FILTER_BACKENDS': [
|
||||||
'django_filters.rest_framework.DjangoFilterBackend',
|
'django_filters.rest_framework.DjangoFilterBackend',
|
||||||
],
|
],
|
||||||
|
|
|
@ -50,6 +50,16 @@
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>API</legend>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="id_email" class="col-sm-2 col-form-label">Key</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<samp>{{ user.settings.api_key }}</samp>
|
||||||
|
<a class="btn btn-xs btn-danger" href="{% url 'babybuddy:user-reset-api-key' %}">Regenerate</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,10 +17,13 @@ app_patterns = [
|
||||||
|
|
||||||
url(r'^$', views.RootRouter.as_view(), name='root-router'),
|
url(r'^$', views.RootRouter.as_view(), name='root-router'),
|
||||||
url(r'^welcome/$', views.Welcome.as_view(), name='welcome'),
|
url(r'^welcome/$', views.Welcome.as_view(), name='welcome'),
|
||||||
url(r'^user/settings/$', views.UserSettings.as_view(),
|
|
||||||
name='user-settings'),
|
|
||||||
url(r'^user/password/$', views.UserPassword.as_view(),
|
url(r'^user/password/$', views.UserPassword.as_view(),
|
||||||
name='user-password'),
|
name='user-password'),
|
||||||
|
url(r'^user/reset-api-key/$', views.UserResetAPIKey.as_view(),
|
||||||
|
name='user-reset-api-key'),
|
||||||
|
url(r'^user/settings/$', views.UserSettings.as_view(),
|
||||||
|
name='user-settings'),
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
|
|
@ -53,6 +53,15 @@ class UserPassword(LoginRequiredMixin, View):
|
||||||
return render(request, self.template_name, {'form': form})
|
return render(request, self.template_name, {'form': form})
|
||||||
|
|
||||||
|
|
||||||
|
class UserResetAPIKey(LoginRequiredMixin, View):
|
||||||
|
"""
|
||||||
|
Resets the API key of the logged in user.
|
||||||
|
"""
|
||||||
|
def get(self, request):
|
||||||
|
request.user.settings.api_key(reset=True)
|
||||||
|
return redirect('babybuddy:user-settings')
|
||||||
|
|
||||||
|
|
||||||
class UserSettings(LoginRequiredMixin, View):
|
class UserSettings(LoginRequiredMixin, View):
|
||||||
"""
|
"""
|
||||||
Handles both the User and Settings models.
|
Handles both the User and Settings models.
|
||||||
|
|
Loading…
Reference in New Issue