diff --git a/seahub/forms.py b/seahub/forms.py index 50cf273da8..89775acf92 100644 --- a/seahub/forms.py +++ b/seahub/forms.py @@ -16,6 +16,9 @@ class AddUserForm(forms.Form): Form for adding a user. """ email = forms.EmailField() + name = forms.CharField(max_length=64, required=False) + department = forms.CharField(max_length=512, required=False) + role = forms.ChoiceField(choices=[(DEFAULT_USER, DEFAULT_USER), (GUEST_USER, GUEST_USER)]) password1 = forms.CharField(widget=forms.PasswordInput()) @@ -32,6 +35,16 @@ class AddUserForm(forms.Form): except User.DoesNotExist: return self.cleaned_data['email'] + def clean_name(self): + """ + should not include '/' + """ + if "/" in self.cleaned_data["name"]: + raise forms.ValidationError(_(u"Name should not include ' / '")) + + return self.cleaned_data["name"] + + def clean(self): """ Verifiy that the values entered into the two password fields diff --git a/seahub/templates/sysadmin/sys_useradmin.html b/seahub/templates/sysadmin/sys_useradmin.html index 7c7b8567fa..c65d025a38 100644 --- a/seahub/templates/sysadmin/sys_useradmin.html +++ b/seahub/templates/sysadmin/sys_useradmin.html @@ -32,6 +32,12 @@

{% trans "Add user" %}



+ +
+
+
+
+ {% if is_pro %} -

{% trans "File format: user@mail.com,password"%}

+

+ {% trans "File format: user@mail.com,password,name,department"%}
+ {% trans "Name and department are optional." %} +

{% trans "Please choose a CSV file" %}

@@ -143,6 +152,8 @@ $('#add-user-form').submit(function() { var form = $(this), form_id = $(this).attr('id'), email = $.trim(form.children('[name="email"]').val()), + name = $.trim($('[name="name"]', form).val()), + department = $.trim($('[name="department"]', form).val()), {% if is_pro %} role = $('select[name="role"]', form).val(), {% endif %} @@ -176,6 +187,8 @@ $('#add-user-form').submit(function() { beforeSend: prepareCSRFToken, data: { 'email': email, + 'name': name, + 'department': department, {% if is_pro %} 'role': role, {% endif %} diff --git a/seahub/templates/sysadmin/userinfo.html b/seahub/templates/sysadmin/userinfo.html index 432a3ffcc8..5a301b3456 100644 --- a/seahub/templates/sysadmin/userinfo.html +++ b/seahub/templates/sysadmin/userinfo.html @@ -41,23 +41,61 @@
{{ org_name }}
{% endif %} - {% if profile %}
{% trans "Name" context "true name" %}
-
{{ profile.nickname }}
- {% endif %} +
+ + {% if profile and profile.nickname %} + {{ profile.nickname }} + {% else %} + -- + {% endif %} + + +
- {% if d_profile %}
{% trans "Department" %}
-
{{ d_profile.department }}
+
+ + {% if d_profile and d_profile.department %} + {{ d_profile.department }} + {% else %} + -- + {% endif %} + + +
+ {% if d_profile and d_profile.telephone %}
{% trans "Telephone" %}
{{ d_profile.telephone }}
{% endif %} -
{% trans "Space Used" %}
-
{{ space_usage|seahub_filesizeformat }} {% if space_quota > 0 %} / {{ space_quota|seahub_filesizeformat }} {% endif %} {% trans "Set Quota" %}
+
{% trans "Space Used / Quota" %}
+
+ {{ space_usage|seahub_filesizeformat }} / + {% if space_quota > 0 %} + {{ space_quota|seahub_filesizeformat }} + {% else %} + -- + {% endif %} + +
+
{% csrf_token %} +

{% trans "Set user name" %}

+
+

+ +
+ +
{% csrf_token %} +

{% trans "Set user department" %}

+
+

+ +
+
{% csrf_token %}

{% trans "Set user storage limit" %}

@@ -254,9 +292,94 @@ $('.rm-link').click(function() { }); return false; }); - +$('#set-name').click(function() { + $("#set-name-form").modal({appendTo: "#main"}); + $('#simplemodal-container').css({'width':'auto', 'height':'auto'}); +}); +$('#set-dept').click(function() { + $("#set-dept-form").modal({appendTo: "#main"}); + $('#simplemodal-container').css({'width':'auto', 'height':'auto'}); +}); $('#set-quota').click(function() { $("#set-quota-form").modal({appendTo: "#main"}); + $('#simplemodal-container').css({'width':'auto', 'height':'auto'}); +}); + +$('#set-name-form').submit(function() { + var nickname = $.trim($('[name="nickname"]', $(this)).val()); + var $error = $('.error', $(this)); + if (!nickname) { + $error.html("{% trans "It is required." %}").show(); + return false; + } + if (nickname.indexOf('/') != -1) { + $error.html("{% trans "Name should not include '/'." %}").show(); + return false; + } + + var $submitBtn = $('[type="submit"]', $(this)); + disable($submitBtn); + + $.ajax({ + url: '{% url 'user_set_nickname' email %}', + type: 'POST', + dataType: 'json', + cache: false, + beforeSend: prepareCSRFToken, + data: {'nickname': nickname}, + success: function(data) { + $('#nickname').html(data.nickname); + $.modal.close(); + }, + error: function(xhr, textStatus, errorThrown) { + var err_msg; + if (xhr.responseText) { + err_msg = $.parseJSON(xhr.responseText).error; + } else { + err_msg = "{% trans "Failed. Please check the network." %}"; + } + $error.html(err_msg).show(); + enable($submitBtn); + } + }); + + return false; +}); + +$('#set-dept-form').submit(function() { + var department = $.trim($('[name="department"]', $(this)).val()); + var $error = $('.error', $(this)); + if (!department) { + $error.html("{% trans "It is required." %}").show(); + return false; + } + + var $submitBtn = $('[type="submit"]', $(this)); + disable($submitBtn); + + $.ajax({ + url: '{% url 'user_set_department' email %}', + type: 'POST', + dataType: 'json', + cache: false, + beforeSend: prepareCSRFToken, + data: {'department': department}, + success: function(data) { + $('#department').html(data.department); + $.modal.close(); + }, + error: function(xhr, textStatus, errorThrown) { + var err_msg; + if (xhr.responseText) { + err_msg = $.parseJSON(xhr.responseText).error; + } else { + err_msg = "{% trans "Failed. Please check the network." %}"; + } + $error.html(err_msg).show(); + enable($submitBtn); + } + }); + return false; }); diff --git a/seahub/urls.py b/seahub/urls.py index b96a94b0c6..432c34eaa0 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -285,6 +285,8 @@ urlpatterns = patterns( url(r'^useradmin/toggle_status/(?P[^/]+)/$', user_toggle_status, name='user_toggle_status'), url(r'^useradmin/toggle_role/(?P[^/]+)/$', user_toggle_role, name='user_toggle_role'), url(r'^useradmin/(?P[^/]+)/set_quota/$', user_set_quota, name='user_set_quota'), + url(r'^useradmin/(?P[^/]+)/set_nickname/$', user_set_nickname, name='user_set_nickname'), + url(r'^useradmin/(?P[^/]+)/set_department/$', user_set_department, name='user_set_department'), url(r'^sys/termsadmin/$', sys_terms_admin, name='sys_terms_admin'), url(r'^sys/termsadmin/delete/(?P[^/]+)/$', sys_delete_terms, name='sys_delete_terms'), url(r'^useradmin/password/reset/(?P[^/]+)/$', user_reset, name='user_reset'), diff --git a/seahub/views/sysadmin.py b/seahub/views/sysadmin.py index 94e6575be3..ac5df5580e 100644 --- a/seahub/views/sysadmin.py +++ b/seahub/views/sysadmin.py @@ -54,6 +54,7 @@ from seahub.views.ajax import (get_related_users_by_org_repo, get_related_users_by_repo) from seahub.forms import SetUserQuotaForm, AddUserForm, BatchAddUserForm, \ TermsAndConditionsForm +from seahub.profile.forms import ProfileForm, DetailedProfileForm from seahub.options.models import UserOptions from seahub.profile.models import Profile, DetailedProfile from seahub.signals import repo_deleted @@ -672,6 +673,40 @@ def user_set_quota(request, email): result['error'] = str(f.errors.values()[0]) return HttpResponse(json.dumps(result), status=400, content_type=content_type) +@login_required_ajax +@sys_staff_required +def user_set_nickname(request, email): + if request.method != 'POST': + raise Http404 + + content_type = 'application/json; charset=utf-8' + result = {} + + form = ProfileForm(request.POST) + if form.is_valid(): + form.save(username=email) + return HttpResponse(json.dumps({'nickname': form.cleaned_data["nickname"]}), content_type=content_type) + else: + result['error'] = str(form.errors.values()[0]) + return HttpResponse(json.dumps(result), status=400, content_type=content_type) + +@login_required_ajax +@sys_staff_required +def user_set_department(request, email): + if request.method != 'POST': + raise Http404 + + content_type = 'application/json; charset=utf-8' + result = {} + + form = DetailedProfileForm(request.POST) + if form.is_valid(): + form.save(username=email) + return HttpResponse(json.dumps({'department': form.cleaned_data["department"]}), content_type=content_type) + else: + result['error'] = str(form.errors.values()[0]) + return HttpResponse(json.dumps(result), status=400, content_type=content_type) + @login_required_ajax @sys_staff_required def sys_org_set_quota(request, org_id): @@ -980,6 +1015,8 @@ def user_add(request): form = AddUserForm(post_values) if form.is_valid(): email = form.cleaned_data['email'] + name = form.cleaned_data['name'] + department = form.cleaned_data['department'] role = form.cleaned_data['role'] password = form.cleaned_data['password1'] @@ -995,6 +1032,10 @@ def user_add(request): User.objects.update_role(email, role) if config.FORCE_PASSWORD_CHANGE: UserOptions.objects.set_force_passwd_change(email) + if name: + Profile.objects.add_or_update(email, name, '') + if department: + DetailedProfile.objects.add_or_update(email, department, '') if request.user.org: org_id = request.user.org.org_id @@ -1834,12 +1875,31 @@ def batch_add_user(request): username = row[0].strip() password = row[1].strip() + # nickname & department are optional + try: + nickname = row[2].strip() + except IndexError: + nickname = '' + + try: + department = row[3].strip() + except IndexError: + department = '' + if not is_valid_username(username): continue if password == '': continue + if nickname: + if len(nickname) > 64 or '/' in nickname: + continue + + if department: + if len(department) > 512: + continue + try: User.objects.get(email=username) continue @@ -1847,6 +1907,11 @@ def batch_add_user(request): User.objects.create_user(username, password, is_staff=False, is_active=True) + if nickname: + Profile.objects.add_or_update(username, nickname, '') + if department: + DetailedProfile.objects.add_or_update(username, department, '') + send_html_email_with_dj_template( username, dj_template='sysadmin/user_batch_add_email.html', subject=_(u'You are invited to join %s') % SITE_NAME,