From 2a2ea58f34aba11dc4c2685fa0d25d7e5c2e98d0 Mon Sep 17 00:00:00 2001
From: Leonidas Poulopoulos <leopoul@noc.grnet.gr>
Date: Mon, 20 Feb 2012 13:17:55 +0200
Subject: [PATCH] User monkeypatching (longer username) now works for admin as
 well

---
 flowspec/admin.py        |  4 ++++
 monkey_patch/__init__.py |  7 +++++++
 monkey_patch/admin.py    | 12 ++++++++++++
 monkey_patch/forms.py    | 32 ++++++++++++++++++++++++++++++++
 monkey_patch/models.py   | 21 ++++++++++-----------
 monkey_patch/views.py    |  1 +
 6 files changed, 66 insertions(+), 11 deletions(-)
 create mode 100644 monkey_patch/admin.py
 create mode 100644 monkey_patch/forms.py
 create mode 100644 monkey_patch/views.py

diff --git a/flowspec/admin.py b/flowspec/admin.py
index e0f12ade..732f30ba 100644
--- a/flowspec/admin.py
+++ b/flowspec/admin.py
@@ -10,6 +10,8 @@ from flowspy.flowspec.forms import *
 import datetime
 from django.conf import settings
 
+from flowspy.monkey_patch.forms import UserCreationForm, UserChangeForm
+
 class RouteAdmin(admin.ModelAdmin):
     form = RouteForm
     actions = ['deactivate']
@@ -49,6 +51,8 @@ class UserProfileInline(admin.StackedInline):
     model = UserProfile
     
 class UserProfileAdmin(UserAdmin):
+    add_form = UserCreationForm
+    form = UserChangeForm
     actions = ['deactivate', 'activate']
     list_display = ('username', 'email', 'first_name' , 'last_name', 'is_staff', 'is_active', 'is_superuser', 'get_userprofile_peer')
     inlines = [UserProfileInline]
diff --git a/monkey_patch/__init__.py b/monkey_patch/__init__.py
index e69de29b..e148912c 100644
--- a/monkey_patch/__init__.py
+++ b/monkey_patch/__init__.py
@@ -0,0 +1,7 @@
+from django.conf import settings
+# This patch was retrieved from: https://github.com/GoodCloud/django-longer-username
+def MAX_USERNAME_LENGTH():
+    if hasattr(settings,"MAX_USERNAME_LENGTH"):
+        return settings.MAX_USERNAME_LENGTH
+    else:
+        return 255
diff --git a/monkey_patch/admin.py b/monkey_patch/admin.py
new file mode 100644
index 00000000..14237f87
--- /dev/null
+++ b/monkey_patch/admin.py
@@ -0,0 +1,12 @@
+from django.contrib import admin
+from django.contrib.auth.admin import UserAdmin
+from django.contrib.auth.models import User
+
+from flowspy.monkey_patch.forms import UserCreationForm, UserChangeForm
+
+class LongerUserNameUserAdmin(UserAdmin):
+    add_form = UserCreationForm
+    form = UserChangeForm
+
+admin.site.unregister(User)
+admin.site.register(User, LongerUserNameUserAdmin)
\ No newline at end of file
diff --git a/monkey_patch/forms.py b/monkey_patch/forms.py
new file mode 100644
index 00000000..81a780be
--- /dev/null
+++ b/monkey_patch/forms.py
@@ -0,0 +1,32 @@
+from django.utils.translation import ugettext as _
+from django.core.validators import MaxLengthValidator
+from django.contrib.auth import forms as auth_forms
+from django import forms
+
+from flowspy.monkey_patch import MAX_USERNAME_LENGTH
+
+def update_username_field(field):
+    field.widget.attrs['maxlength'] = MAX_USERNAME_LENGTH()
+    field.max_length = MAX_USERNAME_LENGTH()
+    field.help_text = _("Required, %s characters or fewer. Only letters, numbers, and characters such as @.+_- are allowed." % MAX_USERNAME_LENGTH())
+
+    # we need to find the MaxLengthValidator and change its
+    # limit_value otherwise the auth forms will fail validation
+    for v in field.validators:
+        if isinstance(v, MaxLengthValidator):
+            v.limit_value = MAX_USERNAME_LENGTH()
+
+class UserCreationForm(auth_forms.UserCreationForm):
+    def __init__(self, *args, **kwargs):
+        super(UserCreationForm, self).__init__(*args, **kwargs)
+        update_username_field(self.fields['username'])
+
+class UserChangeForm(auth_forms.UserChangeForm):
+    def __init__(self, *args, **kwargs):
+        super(UserChangeForm, self).__init__(*args, **kwargs)
+        update_username_field(self.fields['username'])
+
+class AuthenticationForm(auth_forms.AuthenticationForm):
+    def __init__(self, *args, **kwargs):
+        super(AuthenticationForm, self).__init__(*args, **kwargs)
+        update_username_field(self.fields['username'])
diff --git a/monkey_patch/models.py b/monkey_patch/models.py
index a39d2a5c..9fe1d6b0 100644
--- a/monkey_patch/models.py
+++ b/monkey_patch/models.py
@@ -1,13 +1,12 @@
-from django.contrib.auth.models import User
+from django.utils.translation import ugettext as _
+from django.db.models.signals import class_prepared
 from django.core.validators import MaxLengthValidator
+from flowspy.monkey_patch import MAX_USERNAME_LENGTH
 
-NEW_USERNAME_LENGTH = 255
-
-def monkey_patch_username():
-    username = User._meta.get_field("username")
-    username.max_length = NEW_USERNAME_LENGTH
-    for v in username.validators:
-        if isinstance(v, MaxLengthValidator):
-            v.limit_value = NEW_USERNAME_LENGTH
-
-monkey_patch_username()
+def longer_username(sender, *args, **kwargs):
+    if sender.__name__ == "User" and sender.__module__ == "django.contrib.auth.models":
+        sender._meta.get_field("username").max_length = MAX_USERNAME_LENGTH()
+        # For Django 1.2 to work, the validator has to be declared apart from max_length
+        sender._meta.get_field("username").validators = [MaxLengthValidator(MAX_USERNAME_LENGTH())]
+        sender._meta.get_field("username").help_text = _("Required, %s characters or fewer. Only letters, numbers, and @, ., +, -, or _ characters." % MAX_USERNAME_LENGTH())
+class_prepared.connect(longer_username)
diff --git a/monkey_patch/views.py b/monkey_patch/views.py
new file mode 100644
index 00000000..60f00ef0
--- /dev/null
+++ b/monkey_patch/views.py
@@ -0,0 +1 @@
+# Create your views here.
-- 
GitLab