1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-21 11:27:18 +00:00

[sys useradmin] enable add 'name, department' when add/import user; enable set 'name, department' in user info page

This commit is contained in:
llj
2016-12-21 11:41:32 +08:00
parent 24968ae639
commit d3ab1d76a3
5 changed files with 225 additions and 9 deletions

View File

@@ -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

View File

@@ -32,6 +32,12 @@
<h3>{% trans "Add user" %}</h3>
<label for="id_email">{% trans "Email" %}</label><br />
<input type="text" name="email" id="id_email" class="input" /><br />
<label for="id_name">{% trans "Name(optional)" %}</label><br />
<input type="text" name="name" id="id_name" class="input" /><br />
<label for="id_dept">{% trans "Department(optional)" %}</label><br />
<input type="text" name="department" id="id_dept" class="input" /><br />
{% if is_pro %}
<label>{% trans "Role"%}</label><span class="icon-question-sign" title="{% trans "You can also add a user as a guest, who will not be allowed to create libraries and groups." %}" style="color:#666; margin-left:3px;"></span>
<select name="role" class="w100">
@@ -54,7 +60,10 @@
<form id="upload-csv-form" class="hide" enctype="multipart/form-data" method="post" action="{% url 'batch_add_user' %}">{% csrf_token %}
<h3>{% trans "Import users from a CSV file" %}</h3>
<input type="file" name="file" />
<p class="tip">{% trans "File format: user@mail.com,password"%}</p>
<p class="tip">
{% trans "File format: user@mail.com,password,name,department"%}<br />
{% trans "Name and department are optional." %}
</p>
<p class="error hide">{% trans "Please choose a CSV file" %}</p>
<button type="submit" class="submit">{% trans "Submit" %}</button>
</form>
@@ -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 %}

View File

@@ -41,23 +41,61 @@
<dd>{{ org_name }}</dd>
{% endif %}
{% if profile %}
<dt>{% trans "Name" context "true name" %}</dt>
<dd>{{ profile.nickname }}</dd>
{% endif %}
<dd>
<span id="nickname">
{% if profile and profile.nickname %}
{{ profile.nickname }}
{% else %}
--
{% endif %}
</span>
<span id="set-name" title="{% trans "Edit"%}" class="sf2-icon-edit op-icon"></span>
</dd>
{% if d_profile %}
<dt>{% trans "Department" %}</dt>
<dd>{{ d_profile.department }}</dd>
<dd>
<span id="department">
{% if d_profile and d_profile.department %}
{{ d_profile.department }}
{% else %}
--
{% endif %}
</span>
<span id="set-dept" title="{% trans "Edit"%}" class="sf2-icon-edit op-icon"></span>
</dd>
{% if d_profile and d_profile.telephone %}
<dt>{% trans "Telephone" %}</dt>
<dd>{{ d_profile.telephone }}</dd>
{% endif %}
<dt>{% trans "Space Used" %}</dt>
<dd>{{ space_usage|seahub_filesizeformat }} {% if space_quota > 0 %} / {{ space_quota|seahub_filesizeformat }} {% endif %} <a href="#" class="sf-btn-link" style="margin-left:20px;" id="set-quota">{% trans "Set Quota" %}</a></dd>
<dt>{% trans "Space Used / Quota" %}</dt>
<dd>
{{ space_usage|seahub_filesizeformat }} /
{% if space_quota > 0 %}
{{ space_quota|seahub_filesizeformat }}
{% else %}
--
{% endif %}
<span id="set-quota" title="{% trans "Edit" %}" class="sf2-icon-edit op-icon"></span>
</dd>
</dl>
<form id="set-name-form" method="post" action="" class="hide">{% csrf_token %}
<h3>{% trans "Set user name" %}</h3>
<input type="text" name="nickname" class="input" value="" /><br />
<p class="error hide"></p>
<input type="submit" value="{% trans "Submit" %}" class="submit" />
</form>
<form id="set-dept-form" method="post" action="" class="hide">{% csrf_token %}
<h3>{% trans "Set user department" %}</h3>
<input type="text" name="department" class="input" value="" /><br />
<p class="error hide"></p>
<input type="submit" value="{% trans "Submit" %}" class="submit" />
</form>
<form id="set-quota-form" method="post" class="hide">{% csrf_token %}
<h3>{% trans "Set user storage limit" %}</h3>
<input type="hidden" name="email" value="{{ email }}" />
@@ -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;
});

View File

@@ -285,6 +285,8 @@ urlpatterns = patterns(
url(r'^useradmin/toggle_status/(?P<email>[^/]+)/$', user_toggle_status, name='user_toggle_status'),
url(r'^useradmin/toggle_role/(?P<email>[^/]+)/$', user_toggle_role, name='user_toggle_role'),
url(r'^useradmin/(?P<email>[^/]+)/set_quota/$', user_set_quota, name='user_set_quota'),
url(r'^useradmin/(?P<email>[^/]+)/set_nickname/$', user_set_nickname, name='user_set_nickname'),
url(r'^useradmin/(?P<email>[^/]+)/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<pk>[^/]+)/$', sys_delete_terms, name='sys_delete_terms'),
url(r'^useradmin/password/reset/(?P<email>[^/]+)/$', user_reset, name='user_reset'),

View File

@@ -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,