1# Copyright (c) 2012-2016 Seafile Ltd.
2# encoding: utf-8
3from django.conf import settings
4from django import forms
5from django.utils.translation import ugettext_lazy as _
6
7from pysearpc import SearpcError
8
9from seahub.base.accounts import User
10from seahub.constants import DEFAULT_USER, GUEST_USER
11from seahub.utils import is_valid_dirent_name
12from seahub.utils.licenseparse import user_number_over_limit
13from seahub.role_permissions.utils import get_available_roles
14
15class AddUserForm(forms.Form):
16    """
17    Form for adding a user.
18    """
19    email = forms.EmailField()
20    name = forms.CharField(max_length=64, required=False)
21    department = forms.CharField(max_length=512, required=False)
22
23    role = forms.ChoiceField(choices=[ (i, i) for i in get_available_roles() ])
24
25    password1 = forms.CharField(widget=forms.PasswordInput())
26    password2 = forms.CharField(widget=forms.PasswordInput())
27
28    def clean_email(self):
29        if user_number_over_limit():
30            raise forms.ValidationError(_("The number of users exceeds the limit."))
31
32        email = self.cleaned_data['email']
33        try:
34            user = User.objects.get(email=email)
35            raise forms.ValidationError(_("A user with this email already exists."))
36        except User.DoesNotExist:
37            return self.cleaned_data['email']
38
39    def clean_name(self):
40        """
41        should not include '/'
42        """
43        if "/" in self.cleaned_data["name"]:
44            raise forms.ValidationError(_("Name should not include '/'."))
45
46        return self.cleaned_data["name"]
47
48
49    def clean(self):
50        """
51        Verifiy that the values entered into the two password fields
52        match. Note that an error here will end up in
53        ``non_field_errors()`` because it doesn't apply to a single
54        field.
55
56        """
57        if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
58            if self.cleaned_data['password1'] != self.cleaned_data['password2']:
59                raise forms.ValidationError(_("The two passwords didn't match."))
60        return self.cleaned_data
61
62class RepoCreateForm(forms.Form):
63    """
64    Form for creating repo and org repo.
65    """
66    repo_name = forms.CharField(max_length=settings.MAX_FILE_NAME,
67                                error_messages={
68            'required': _('Name can\'t be empty'),
69            'max_length': _('Name is too long (maximum is 255 characters)')
70            })
71    repo_desc = forms.CharField(max_length=100, error_messages={
72            'required': _('Description can\'t be empty'),
73            'max_length': _('Description is too long (maximum is 100 characters)')
74            })
75    encryption = forms.CharField(max_length=1)
76    uuid = forms.CharField(required=False)
77    magic_str = forms.CharField(required=False)
78    encrypted_file_key = forms.CharField(required=False)
79
80    def clean_repo_name(self):
81        repo_name = self.cleaned_data['repo_name']
82        if not is_valid_dirent_name(repo_name):
83            error_msg = _("Name %s is not valid") % repo_name
84            raise forms.ValidationError(error_msg)
85        else:
86            return repo_name
87
88    def clean(self):
89        encryption = self.cleaned_data['encryption']
90        if int(encryption) == 0:
91            return self.cleaned_data
92
93        uuid = self.cleaned_data['uuid']
94        magic_str = self.cleaned_data['magic_str']
95        encrypted_file_key = self.cleaned_data['encrypted_file_key']
96        if not (uuid and magic_str and encrypted_file_key):
97            raise forms.ValidationError(_("Argument missing"))
98
99        return self.cleaned_data
100
101class SharedRepoCreateForm(RepoCreateForm):
102    """
103    Used for creating group repo and public repo
104    """
105    permission = forms.ChoiceField(choices=(('rw', 'read-write'), ('r', 'read-only')))
106
107class RepoRenameDirentForm(forms.Form):
108    """
109    Form for rename a file/dir.
110    """
111    oldname = forms.CharField(error_messages={'required': _("Oldname is required")})
112    newname = forms.CharField(max_length=settings.MAX_FILE_NAME,
113                                error_messages={
114                                    'max_length': _("It's too long."),
115                                    'required': _("It's required."),
116                                })
117
118    def clean_newname(self):
119        newname = self.cleaned_data['newname']
120        try:
121            if not is_valid_dirent_name(newname):
122                error_msg = _('Name "%s" is not valid') % newname
123                raise forms.ValidationError(error_msg)
124            else:
125                return newname
126        except SearpcError as e:
127            raise forms.ValidationError(str(e))
128
129class RepoNewDirentForm(forms.Form):
130    """
131    Form for create a new empty dir or a new empty file.
132    """
133    dirent_name = forms.CharField(max_length=settings.MAX_FILE_NAME,
134                                error_messages={
135                                    'max_length': _("It's too long."),
136                                    'required': _("It's required."),
137                            })
138
139    def clean_dirent_name(self):
140        dirent_name = self.cleaned_data['dirent_name']
141        try:
142            if not is_valid_dirent_name(dirent_name):
143                error_msg = _('Name "%s" is not valid') % dirent_name
144                raise forms.ValidationError(error_msg)
145            else:
146                return dirent_name
147        except SearpcError as e:
148            raise forms.ValidationError(str(e))
149
150class SetUserQuotaForm(forms.Form):
151    """
152    Form for setting user quota.
153    """
154    space_quota = forms.IntegerField(min_value=0,
155                               error_messages={'required': _('Space quota can\'t be empty'),
156                                               'min_value': _('Space quota is too low (minimum value is 0)')})
157
158class RepoSettingForm(forms.Form):
159    """
160    Form for saving repo settings.
161    """
162    repo_name = forms.CharField(error_messages={'required': _('Library name is required')})
163    days = forms.IntegerField(required=False,
164                              error_messages={'invalid': _('Please enter a number')})
165
166    def clean_repo_name(self):
167        repo_name = self.cleaned_data['repo_name']
168        if not is_valid_dirent_name(repo_name):
169            error_msg = _("Name %s is not valid") % repo_name
170            raise forms.ValidationError(error_msg)
171        else:
172            return repo_name
173
174class BatchAddUserForm(forms.Form):
175    """
176    Form for importing users from XLSX file.
177    """
178    file = forms.FileField()
179
180
181class TermsAndConditionsForm(forms.Form):
182    """Form to save T&C.
183    """
184    name = forms.CharField(error_messages={'required': _('Name is required')})
185    version_number = forms.DecimalField(required=True, error_messages={'invalid': _('Please enter a valid number')})
186    text = forms.CharField(error_messages={'required': _('Text is required')})
187