--- a/server/ammico/admin.py Tue Jun 02 09:46:55 2015 +0200
+++ b/server/ammico/admin.py Thu Jun 04 20:03:04 2015 +0200
@@ -1,9 +1,87 @@
+from django import forms
from django.contrib import admin
+from django.contrib.auth import get_user_model
+from django.contrib.auth.admin import UserAdmin
+from django.contrib.auth.forms import ReadOnlyPasswordHashField
+from django.contrib.auth.models import Group
from ammico.models import Slide, Book
-from django.contrib.auth import get_user_model
+
+
+class UserCreationForm(forms.ModelForm):
+ """A form for creating new users. Includes all the required
+ fields, plus a repeated password."""
+ password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
+ password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
+
+ class Meta:
+ model = get_user_model()
+ fields = ('email', 'idUser')
+
+ def clean_password2(self):
+ # Check that the two password entries match
+ password1 = self.cleaned_data.get("password1")
+ password2 = self.cleaned_data.get("password2")
+ if password1 and password2 and password1 != password2:
+ raise forms.ValidationError("Passwords don't match")
+ return password2
+
+ def save(self, commit=True):
+ # Save the provided password in hashed format
+ user = super(UserCreationForm, self).save(commit=False)
+ user.set_password(self.cleaned_data["password1"])
+ if commit:
+ user.save()
+ return user
-admin.site.register(Slide)
+class UserChangeForm(forms.ModelForm):
+ """A form for updating users. Includes all the fields on
+ the user, but replaces the password field with admin's
+ password hash display field.
+ """
+ password = ReadOnlyPasswordHashField()
+
+ class Meta:
+ model = get_user_model()
+ fields = ('email', 'password', 'idUser', 'is_active', 'is_admin')
+
+ def clean_password(self):
+ # Regardless of what the user provides, return the initial value.
+ # This is done here, rather than on the field, because the
+ # field does not have access to the initial value
+ return self.initial["password"]
+
+
+class MyUserAdmin(UserAdmin):
+ # The forms to add and change user instances
+ form = UserChangeForm
+ add_form = UserCreationForm
+
+ # The fields to be used in displaying the User model.
+ # These override the definitions on the base UserAdmin
+ # that reference specific fields on auth.User.
+ list_display = ('email', 'idUser', 'is_admin')
+ list_filter = ('is_admin',)
+ fieldsets = (
+ (None, {'fields': ('email', 'password')}),
+ ('external id', {'fields': ('idUser',)}),
+ ('Permissions', {'fields': ('is_admin',)}),
+ )
+ # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
+ # overrides get_fieldsets to use this attribute when creating a user.
+ add_fieldsets = (
+ (None, {
+ 'classes': ('wide',),
+ 'fields': ('email', 'idUser', 'password1', 'password2')}
+ ),
+ )
+ search_fields = ('email',)
+ ordering = ('email',)
+ filter_horizontal = ()
+
+
admin.site.register(get_user_model())
+admin.site.unregister(Group)
+admin.site.register(Slide)
admin.site.register(Book)
\ No newline at end of file
--- a/server/ammico/models.py Tue Jun 02 09:46:55 2015 +0200
+++ b/server/ammico/models.py Thu Jun 04 20:03:04 2015 +0200
@@ -8,13 +8,13 @@
class Book(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name = "books")
- idArticle = models.CharField(max_length=512, null=True)
+ idArticle = models.CharField(max_length=512, blank=True, null=True)
title = models.CharField(max_length=512, blank=True)
description = models.CharField(max_length=512, blank=True, null=True)
image = models.URLField(max_length=2048, blank=True)
date = models.DateTimeField(default=datetime.datetime.now)
public = models.BooleanField(default=False, db_index=True)
- parent_visit = models.ForeignKey('Book', related_name = "books_copy", null=True)
+ parent_visit = models.ForeignKey('Book', related_name = "books_copy", blank=True, null=True)
def __str__(self):
return self.title
@@ -28,7 +28,7 @@
image = models.URLField(max_length=2048, blank=True)
date = models.DateTimeField(default=datetime.datetime.now)
favorite = models.BooleanField(default=False, db_index=True)
- tags = TaggableManager()
+ tags = TaggableManager(blank=True)
def __str__(self):
return self.idStop
--- a/server/authentication/models.py Tue Jun 02 09:46:55 2015 +0200
+++ b/server/authentication/models.py Thu Jun 04 20:03:04 2015 +0200
@@ -1,12 +1,80 @@
-from django.contrib.auth.models import AbstractUser
+from django.contrib.auth.models import (
+ BaseUserManager, AbstractBaseUser
+)
from django.db import models
+from django.utils.translation import ugettext_lazy as _
import settings
-class AmmicoUser(AbstractUser):
- idUser = models.CharField(max_length=50, blank=True)
+class AmmicoUserManager(BaseUserManager):
+ def create_user(self, email, idUser=None, password=None):
+ """
+ Creates and saves a User with the given email and password.
+ """
+ if not email:
+ raise ValueError('Users must have an email address')
+
+ user = self.model(
+ email=self.normalize_email(email),
+ idUser=idUser,
+ )
+
+ user.set_password(password)
+ user.save(using=self._db)
+ return user
+
+ def create_superuser(self, email, password, idUser=None):
+ """
+ Creates and saves a superuser with the given email and password.
+ """
+ user = self.create_user(email,
+ password=password,
+ idUser=idUser
+ )
+ user.is_admin = True
+ user.save(using=self._db)
+ return user
+
+
+class AmmicoUser(AbstractBaseUser):
+ email = models.EmailField(verbose_name='email address', max_length=255, unique=True)
+ idUser = models.IntegerField(_('identifiant utilisateur'), blank=True, null=True)
+ is_active = models.BooleanField(default=True)
+ is_admin = models.BooleanField(default=False)
+
+ objects = AmmicoUserManager()
+
+ USERNAME_FIELD = 'email'
+ REQUIRED_FIELDS = []
+
+ def get_full_name(self):
+ # The user is identified by their email address
+ return self.email
+
+ def get_short_name(self):
+ # The user is identified by their email address
+ return self.email
+
+ def __str__(self): # __unicode__ on Python 2
+ return self.email
+
+ def has_perm(self, perm, obj=None):
+ "Does the user have a specific permission?"
+ # Simplest possible answer: Yes, always
+ return True
+
+ def has_module_perms(self, app_label):
+ "Does the user have permissions to view the app `app_label`?"
+ # Simplest possible answer: Yes, always
+ return True
+
+ @property
+ def is_staff(self):
+ "Is the user a member of staff?"
+ # Simplest possible answer: All admins are staff
+ return self.is_admin
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
--- a/server/authentication/urls.py Tue Jun 02 09:46:55 2015 +0200
+++ b/server/authentication/urls.py Thu Jun 04 20:03:04 2015 +0200
@@ -6,5 +6,5 @@
urlpatterns = patterns('',
url(r'^user', User.as_view()),
- url(r'^api-token-auth', ObtainAuthToken.as_view())
+ url(r'^api-token-auth', ObtainAuthToken.as_view()),
)
--- a/server/authentication/views.py Tue Jun 02 09:46:55 2015 +0200
+++ b/server/authentication/views.py Thu Jun 04 20:03:04 2015 +0200
@@ -5,12 +5,11 @@
import requests
from rest_framework import serializers, status, permissions, parsers, renderers
from rest_framework.authtoken.models import Token
-from rest_framework.authtoken.serializers import AuthTokenSerializer
from rest_framework.response import Response
from rest_framework.views import APIView
+from ammico.views import populateVisit
from config import URL_JAMESPOT
-from ammico.views import populateVisit
class UserSerializer(serializers.ModelSerializer):
@@ -31,11 +30,6 @@
def post(self, request):
VALID_USER_FIELDS = [f.name for f in get_user_model()._meta.fields]
- DEFAULTS = {
- "groups":"",
- "user_permissions":""
- }
- request.data.update(DEFAULTS)
serialized = UserSerializer(data=request.data)
if serialized.is_valid():
@@ -60,10 +54,8 @@
renderer_classes = (renderers.JSONRenderer,)
def post(self, request):
- serializer = AuthTokenSerializer(data=request.data)
- serializer.is_valid(raise_exception=True)
- user = serializer.validated_data['user']
+ user = get_user_model().objects.get(email = request.data['email'], password = request.data['password'])
if (user.idUser):
populateVisit(user)
- token, created = Token.objects.get_or_create(user=user)
+ token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
\ No newline at end of file