Repository: readthedocs/readthedocs.org

Issue:
Validate profile fields on form
Related code

https://github.com/rtfd/readthedocs.org/blob/164800694a25d769234c6e7019c483f347fe9226/readthedocs/core/forms.py#L20-L46

This will raise an exception if the length is greater than the model

Sentry issue https://sentry.io/read-the-docs/readthedocs-org/issues/666774301/


Discussion:
@stsewd 
Can I take this issue?

As of now,
I think there is no limit for `first_name` and other fields.
I am able to set my first_name and last_name to a very long string.

![screenshot from 2018-11-11 13-33-29](https://user-images.githubusercontent.com/29149191/48310531-aa5f9700-e5b6-11e8-900c-440a49f1b1e4.png)

I guess you are using sqlite, this can be replicated using postgres
@stsewd 
I am unable to set up postgres as of now, but i found from the django documentation that there is a limitation of 30 characters for both first_name and last_name in Django 1.11([reference](https://docs.djangoproject.com/en/1.11/ref/contrib/auth/#django.contrib.auth.models.User.first_name)).
Also the limit for homepage is set for 100 characters.

@stsewd Can i start working on this?
@dojutsu-user If you can craft a PR that seems to make a substantive difference towards resolving this issue, go ahead. You don't need to ask permission for that. We'll review it when we can. If you're asking for more help in figuring out how to resolve this issue, there's no need to ask if you can start working on it - just ask for help. :) 

Resolving patch:
diff --git a/readthedocs/core/forms.py b/readthedocs/core/forms.py
--- a/readthedocs/core/forms.py
+++ b/readthedocs/core/forms.py
@@ -18,8 +18,8 @@
 
 
 class UserProfileForm(forms.ModelForm):
-    first_name = CharField(label=_('First name'), required=False)
-    last_name = CharField(label=_('Last name'), required=False)
+    first_name = CharField(label=_('First name'), required=False, max_length=30)
+    last_name = CharField(label=_('Last name'), required=False, max_length=30)
 
     class Meta(object):
         model = UserProfile


Test patch:
diff --git a/readthedocs/rtd_tests/tests/test_profile_views.py b/readthedocs/rtd_tests/tests/test_profile_views.py
--- a/readthedocs/rtd_tests/tests/test_profile_views.py
+++ b/readthedocs/rtd_tests/tests/test_profile_views.py
@@ -35,6 +35,27 @@ def test_edit_profile(self):
         self.assertEqual(self.user.last_name, 'Docs')
         self.assertEqual(self.user.profile.homepage, 'readthedocs.org')
 
+    def test_edit_profile_with_invalid_values(self):
+        resp = self.client.get(
+            reverse('profiles_profile_edit'),
+        )
+        self.assertTrue(resp.status_code, 200)
+
+        resp = self.client.post(
+            reverse('profiles_profile_edit'),
+            data={
+                'first_name': 'a' * 31,
+                'last_name': 'b' * 31,
+                'homepage': 'c' * 101,
+            }
+        )
+
+        FORM_ERROR_FORMAT = 'Ensure this value has at most {} characters (it has {}).'
+
+        self.assertFormError(resp, form='form', field='first_name', errors=FORM_ERROR_FORMAT.format(30, 31))
+        self.assertFormError(resp, form='form', field='last_name', errors=FORM_ERROR_FORMAT.format(30, 31))
+        self.assertFormError(resp, form='form', field='homepage', errors=FORM_ERROR_FORMAT.format(100, 101))
+
     def test_delete_account(self):
         resp = self.client.get(
             reverse('delete_account')