diff --git a/seahub/api2/serializers.py b/seahub/api2/serializers.py index 8c63b018d8..395bb932fe 100644 --- a/seahub/api2/serializers.py +++ b/seahub/api2/serializers.py @@ -2,7 +2,7 @@ from rest_framework import serializers from seahub.auth import authenticate from seahub.api2.models import Token, TokenV2, DESKTOP_PLATFORMS -from seahub.api2.utils import get_client_ip +from seahub.api2.utils import get_client_ip, is_valid_username def all_none(values): for value in values: @@ -51,7 +51,11 @@ class AuthTokenSerializer(serializers.Serializer): else: raise serializers.ValidationError('invalid params') - # first check password + # first check username and password + if username: + if not is_valid_username(username): + raise serializers.ValidationError('username is not valid.') + if username and password: user = authenticate(username=username, password=password) if user: @@ -88,7 +92,7 @@ class AuthTokenSerializer(serializers.Serializer): if len(device_id) != 16: raise serializers.ValidationError('invalid device id') elif platform == 'ios': - if len(device_id) != 36: + if len(device_id) != 36: raise serializers.ValidationError('invalid device id') else: raise serializers.ValidationError('invalid platform') diff --git a/seahub/auth/forms.py b/seahub/auth/forms.py index 8d8b5d4895..96355a5d93 100644 --- a/seahub/auth/forms.py +++ b/seahub/auth/forms.py @@ -6,7 +6,8 @@ from django.utils.http import int_to_base36 from seahub.base.accounts import User from seahub.auth import authenticate from seahub.auth.tokens import default_token_generator -from seahub.utils import IS_EMAIL_CONFIGURED, send_html_email +from seahub.utils import IS_EMAIL_CONFIGURED, send_html_email, \ + is_valid_username from captcha.fields import CaptchaField @@ -15,7 +16,7 @@ class AuthenticationForm(forms.Form): Base class for authenticating users. Extend this to get a form that accepts username/password logins. """ - username = forms.EmailField(label=_("Username"), max_length=255) + username = forms.CharField(label=_("Username"), max_length=255) password = forms.CharField(label=_("Password"), widget=forms.PasswordInput) def __init__(self, request=None, *args, **kwargs): @@ -29,6 +30,12 @@ class AuthenticationForm(forms.Form): self.user_cache = None super(AuthenticationForm, self).__init__(*args, **kwargs) + def clean_username(self): + username = self.cleaned_data['username'] + if not is_valid_username(username): + raise forms.ValidationError(_("Enter a valid email address.")) + return self.cleaned_data['username'] + def clean(self): username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') diff --git a/seahub/base/accounts.py b/seahub/base/accounts.py index d0968073da..8e99cbacfc 100644 --- a/seahub/base/accounts.py +++ b/seahub/base/accounts.py @@ -13,6 +13,7 @@ from registration import signals from seaserv import ccnet_threaded_rpc, unset_repo_passwd, is_passwd_set from seahub.profile.models import Profile, DetailedProfile +from seahub.utils import is_valid_username UNUSABLE_PASSWORD = '!' # This will never be a valid hash @@ -386,7 +387,7 @@ class RegistrationForm(forms.Form): """ attrs_dict = { 'class': 'input' } - email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict, + email = forms.CharField(widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=75)), label=_("Email address")) userid = forms.RegexField(regex=r'^\w+$', @@ -403,6 +404,9 @@ class RegistrationForm(forms.Form): def clean_email(self): email = self.cleaned_data['email'] + if not is_valid_username(email): + raise forms.ValidationError(_("Enter a valid email address.")) + emailuser = ccnet_threaded_rpc.get_emailuser(email) if not emailuser: return self.cleaned_data['email'] diff --git a/seahub/utils/__init__.py b/seahub/utils/__init__.py index e00f14b767..45db49ef40 100644 --- a/seahub/utils/__init__.py +++ b/seahub/utils/__init__.py @@ -13,7 +13,6 @@ from urlparse import urlparse import ccnet -from django.core.validators import email_re from django.core.urlresolvers import reverse from django.core.mail import EmailMessage from django.contrib.sites.models import RequestSite @@ -209,6 +208,15 @@ def normalize_file_path(path): """ return path.rstrip('/') +# modified from django1.5:/core/validators, and remove the support for single +# quote in email address +email_re = re.compile( + r"(^[-!#$%&*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom + # quoted-string, see also http://tools.ietf.org/html/rfc2822#section-3.2.5 + r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"' + r')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)$)' # domain + r'|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$', re.IGNORECASE) # literal form, ipv4 address (SMTP 4.1.3) + def is_valid_email(email): """A heavy email format validation. """ @@ -218,7 +226,7 @@ def is_valid_username(username): """Check whether username is valid, currently only email can be a username. """ return is_valid_email(username) - + def check_filename_with_rename(repo_id, parent_dir, filename): cmmts = get_commits(repo_id, 0, 1) latest_commit = cmmts[0] if cmmts else None