1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-02 07:47:32 +00:00

Merge branch '5.1'

Conflicts:
	seahub/base/accounts.py
	seahub/share/views.py
	seahub/views/sysadmin.py
	tests/seahub/base/test_accounts.py
	tests/seahub/share/views/test_ajax_get_download_link.py
	tests/seahub/share/views/test_ajax_get_upload_link.py
This commit is contained in:
zhengxie 2016-07-21 10:55:50 +08:00
commit 57cc2b4aba
27 changed files with 659 additions and 722 deletions

View File

@ -92,6 +92,7 @@
.icon-eye:before { content: "\f06e"; }
.icon-eye-slash:before { content: "\f070"; }
.icon-plus-square:before { content: "\f0fe"; }
.icon-envelope:before { content: "\f0e0"; }
.fa-1x {
font-size: 1.3em;
}
@ -3275,18 +3276,18 @@ button.sf-dropdown-toggle:focus {
#user-profile .avatar {
border-radius: 0;
}
#user-profile p {
.user-profile-nickname {
padding: 8px 15px;
margin: 0;
}
#user-profile .nickname {
font-size: 18px;
}
#user-profile .info {
.user-profile-info {
padding: 8px 15px;
border-top: 1px solid #eee;
}
#user-profile .info-detail {
padding-left: 6px;
.user-profile-info-icon {
display:inline-block;
width:1.4em;
}
/* shared file view */
#shared-file-view-hd .cur-path,

View File

@ -5,7 +5,6 @@ from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from seaserv import seafile_api, ccnet_api
from pysearpc import SearpcError
@ -15,7 +14,6 @@ from seahub.utils.licenseparse import parse_license
from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error
import seahub.settings
try:
@ -29,9 +27,14 @@ class SysInfo(APIView):
"""Show system info.
"""
authentication_classes = (TokenAuthentication, SessionAuthentication)
throttle_classes = (UserRateThrottle, )
throttle_classes = (UserRateThrottle,)
permission_classes = (IsAdminUser,)
def _get_license_dict(self):
license_file = os.path.join(seahub.settings.PROJECT_ROOT, '../../seafile-license.txt')
license_dict = parse_license(license_file)
return license_dict
def get(self, request, format=None):
# count repos
try:
@ -92,15 +95,20 @@ class SysInfo(APIView):
is_pro = is_pro_version()
if is_pro:
license_file = os.path.join(seahub.settings.PROJECT_ROOT, '../../seafile-license.txt')
license_dict = parse_license(license_file)
license_dict = self._get_license_dict()
else:
license_dict = {}
if license_dict:
with_license = True
try:
max_users = int(license_dict.get('MaxUsers', ''))
except ValueError as e:
logger.error(e)
max_users = 0
else:
with_license = False
max_users = 0
info = {
'users_count': active_users + inactive_users,
@ -111,7 +119,9 @@ class SysInfo(APIView):
'multi_tenancy_enabled': multi_tenancy_enabled,
'is_pro': is_pro,
'with_license': with_license,
'license': license_dict
'license_expiration': license_dict.get('Expiration', ''),
'license_maxusers': max_users,
'license_to': license_dict.get('Name', ''),
}
return Response(info)

View File

@ -8,19 +8,20 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework import status
from django.conf import settings
import seaserv
from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error
from seahub.utils import is_org_context
from seahub.utils import is_valid_email, is_org_context
from seahub.base.accounts import User
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.profile.models import Profile
from seahub.contacts.models import Contact
from seahub.avatar.templatetags.avatar_tags import api_avatar_url
from seahub.settings import ENABLE_GLOBAL_ADDRESSBOOK, ENABLE_SEARCH_FROM_LDAP_DIRECTLY
class SearchUser(APIView):
@ -50,7 +51,7 @@ class SearchUser(APIView):
users_result = []
username = request.user.username
if request.cloud_mode:
if settings.CLOUD_MODE:
if is_org_context(request):
url_prefix = request.user.org.url_prefix
users = seaserv.get_org_users_by_url_prefix(url_prefix, -1, -1)
@ -61,13 +62,14 @@ class SearchUser(APIView):
# when search profile, only search users in org
# 'nickname__icontains' for search by nickname
# 'contact_email__icontains' for search by contact email
users_from_profile = Profile.objects.filter(Q(user__in=[u.email for u in users]) & \
(Q(nickname__icontains=q)) | \
Q(contact_email__icontains=q)).values('user')
elif ENABLE_GLOBAL_ADDRESSBOOK:
users_from_profile = Profile.objects.filter(Q(user__in=[u.email for u in users]) &
(Q(nickname__icontains=q)) | Q(contact_email__icontains=q)).values('user')
elif settings.ENABLE_GLOBAL_ADDRESSBOOK:
users_from_ccnet = search_user_from_ccnet(q)
users_from_profile = Profile.objects.filter(Q(contact_email__icontains=q) | \
users_from_profile = Profile.objects.filter(Q(contact_email__icontains=q) |
Q(nickname__icontains=q)).values('user')
else:
# in cloud mode, user will be added to Contact when share repo
users = []
@ -83,16 +85,18 @@ class SearchUser(APIView):
users.append(c)
users_from_ccnet = filter(lambda u: q in u.email, users)
if is_valid_email(q):
users_from_ccnet += search_user_from_ccnet(q)
# 'user__in' for only get profile of contacts
# 'nickname__icontains' for search by nickname
# 'contact_email__icontains' for search by contact
users_from_profile = Profile.objects.filter(Q(user__in=[u.email for u in users]) & \
(Q(nickname__icontains=q)) | \
Q(contact_email__icontains=q)).values('user')
users_from_profile = Profile.objects.filter(Q(user__in=[u.email for u in users]) &
(Q(nickname__icontains=q)) | Q(contact_email__icontains=q)).values('user')
else:
users_from_ccnet = search_user_from_ccnet(q)
users_from_profile = Profile.objects.filter(Q(contact_email__icontains=q) | \
users_from_profile = Profile.objects.filter(Q(contact_email__icontains=q) |
Q(nickname__icontains=q)).values('user')
# remove inactive users and add to result
@ -158,7 +162,7 @@ def search_user_from_ccnet(q):
users.extend(ldap_imported_users)
count = len(users)
if count < 10 and ENABLE_SEARCH_FROM_LDAP_DIRECTLY:
if count < 10 and settings.ENABLE_SEARCH_FROM_LDAP_DIRECTLY:
all_ldap_users = seaserv.ccnet_threaded_rpc.search_ldapusers(q, 0, 10 - count)
users.extend(all_ldap_users)

View File

@ -61,7 +61,7 @@ urlpatterns = patterns('',
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/revert/$', FileRevert.as_view(), name='api2-file-revert'),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/shared-link/$', FileSharedLinkView.as_view()),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/$', DirView.as_view(), name='DirView'),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/sub_repo/$', DirSubRepoView.as_view()),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/sub_repo/$', DirSubRepoView.as_view(), name="api2-dir-sub-repo"),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/shared_items/$', DirSharedItemsEndpoint.as_view(), name="api2-dir-shared-items"),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/download/$', DirDownloadView.as_view(), name='api2-dir-download'),
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/revert/$', DirRevert.as_view(), name='api2-dir-revert'),

View File

@ -2716,67 +2716,94 @@ class DirRevert(APIView):
class DirSubRepoView(APIView):
authentication_classes = (TokenAuthentication, )
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
throttle_classes = (UserRateThrottle,)
# from seahub.views.ajax.py::sub_repo
def get(self, request, repo_id, format=None):
'''
check if a dir has a corresponding sub_repo
if it does not have, create one
'''
""" Create sub-repo for folder
result = {}
Permission checking:
1. user with `r` or `rw` permission.
2. password correct for encrypted repo.
"""
path = request.GET.get('p')
name = request.GET.get('name')
password = request.GET.get('password', None)
# argument check
path = request.GET.get('p', None)
if not path:
error_msg = 'p invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
name = request.GET.get('name', None)
if not name:
error_msg = 'name invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# recourse check
repo = get_repo(repo_id)
if not repo:
result['error'] = 'Library not found.'
return HttpResponse(json.dumps(result), status=404, content_type=json_content_type)
error_msg = 'Library %s not found.' % repo_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
if not (path and name):
result['error'] = 'Argument missing'
return HttpResponse(json.dumps(result), status=400, content_type=json_content_type)
# permission check
if not check_folder_permission(request, repo_id, path) or \
not request.user.permissions.can_add_repo():
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
username = request.user.username
# check if the sub-lib exist
try:
sub_repo = seafile_api.get_virtual_repo(repo_id, path, username)
except SearpcError, e:
result['error'] = e.msg
return HttpResponse(json.dumps(result), status=500, content_type=json_content_type)
if sub_repo:
result['sub_repo_id'] = sub_repo.id
else:
if not request.user.permissions.can_add_repo():
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to create library.')
# create a sub-lib
try:
# use name as 'repo_name' & 'repo_desc' for sub_repo
if repo.encrypted:
if password:
sub_repo_id = seafile_api.create_virtual_repo(repo_id,
path, name, name, username, password)
password = request.GET.get('password', '')
if repo.encrypted:
# check password for encrypted repo
if not password:
error_msg = 'password invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
else:
try:
seafile_api.set_passwd(repo_id, username, password)
except SearpcError as e:
if e.msg == 'Bad arguments':
error_msg = 'Bad arguments'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
elif e.msg == 'Incorrect password':
error_msg = _(u'Wrong password')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
elif e.msg == 'Internal server error':
error_msg = _(u'Internal server error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
else:
result['error'] = 'Password Required.'
return HttpResponse(json.dumps(result), status=403, content_type=json_content_type)
error_msg = _(u'Decrypt library error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
# create sub-lib for encrypted repo
try:
if is_org_context(request):
org_id = request.user.org.org_id
sub_repo_id = seafile_api.create_org_virtual_repo(
org_id, repo_id, path, name, name, username, password)
else:
sub_repo_id = seafile_api.create_virtual_repo(repo_id, path, name, name, username)
sub_repo_id = seafile_api.create_virtual_repo(
repo_id, path, name, name, username, password)
except SearpcError as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
else:
# create sub-lib for common repo
try:
if is_org_context(request):
org_id = request.user.org.org_id
sub_repo_id = seafile_api.create_org_virtual_repo(
org_id, repo_id, path, name, name, username)
else:
sub_repo_id = seafile_api.create_virtual_repo(
repo_id, path, name, name, username)
except SearpcError as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
result['sub_repo_id'] = sub_repo_id
except SearpcError, e:
result['error'] = e.msg
return HttpResponse(json.dumps(result), status=500, content_type=json_content_type)
return HttpResponse(json.dumps(result), content_type=json_content_type)
return Response({'sub_repo_id': sub_repo_id})
########## Sharing
class SharedRepos(APIView):

View File

@ -1,4 +1,6 @@
# encoding: utf-8
import re
from django import forms
from django.core.mail import send_mail
from django.utils import translation
@ -8,7 +10,7 @@ from django.contrib.sites.models import RequestSite
from django.contrib.sites.models import Site
import seaserv
from seaserv import ccnet_threaded_rpc, unset_repo_passwd, is_passwd_set, \
seafile_api
seafile_api, ccnet_api
from constance import config
from registration import signals
@ -220,7 +222,9 @@ class User(object):
seafile_api.remove_repo(r.id)
clear_token(self.username)
ccnet_threaded_rpc.remove_emailuser(source, self.username)
# remove current user from joined groups
ccnet_api.remove_group_user(self.username)
ccnet_api.remove_emailuser(source, self.username)
Profile.objects.delete_profile_by_user(self.username)
def get_and_delete_messages(self):
@ -552,9 +556,15 @@ class RegistrationForm(forms.Form):
password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False),
label=_("Password (again)"))
@classmethod
def allow_register(self, email):
prog = re.compile(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)",
re.IGNORECASE)
return False if prog.match(email) is None else True
def clean_email(self):
email = self.cleaned_data['email']
if not is_valid_username(email):
if not self.allow_register(email):
raise forms.ValidationError(_("Enter a valid email address."))
emailuser = ccnet_threaded_rpc.get_emailuser(email)

View File

@ -31,7 +31,12 @@
{% else %}
<span class="user-status-cur-value">{% trans "Inactive" %}</span>
{% endif %}
<span title="{% trans "Edit"%}" class="user-status-edit-icon sf2-icon-edit op-icon vh"></span>
</div>
<select name="permission" class="user-status-select hide">
<option value="1" {%if user.is_active %}selected="selected"{% endif %}>{% trans "Active" %}</option>
<option value="0" {%if not user.is_active %}selected="selected"{% endif %}>{% trans "Inactive"%}</option>
</select>
</td>
<td style="font-size:11px;">
<p> {{ user.space_usage|seahub_filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|seahub_filesizeformat }} {% endif %} </p>
@ -58,6 +63,10 @@
<p>{% trans "Empty" %}</p>
{% endif %}
<div id="activate-msg" class="hide">
<p>{% trans "Activating..., please wait" %}</p>
</div>
{% endblock %}
{% block extra_script %}
@ -68,5 +77,75 @@
'post': true // post request
});
$('tr:gt(0)').hover(
function() {
$(this).find('.user-status-edit-icon, .user-role-edit-icon').removeClass('vh');
},
function() {
$(this).find('.user-status-edit-icon, .user-role-edit-icon').addClass('vh');
}
);
$('.user-status-edit-icon, .user-role-edit-icon').click(function() {
$(this).parent().addClass('hide');
$(this).parent().next().removeClass('hide'); // show 'select'
});
$('.user-status-select, .user-role-select').change(function() {
var select = $(this),
select_val = select.val(),
uid = select.parents('tr').attr('data-userid'),
$select_prev = $(this).prev('.user-status, .user-role'), // .user-status, .user-role
url, data;
if (select.hasClass('user-status-select')) {
url = "{{ SITE_ROOT }}inst/useradmin/toggle_status/" + uid + "/";
data = {'s': select_val};
} else {
url = "{{ SITE_ROOT }}inst/useradmin/toggle_role/" + uid + "/";
data = {'r': select_val};
}
if (select_val == 1) {
// show activating popup
$('#activate-msg').modal();
$('#simplemodal-container').css({'height':'auto'});
}
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
data: data,
cache: false,
beforeSend: prepareCSRFToken,
success: function(data) {
if (data['email_sent']) {
feedback("{% trans "Edit succeeded, an email has been sent." %}", 'success');
} else if (data['email_sent'] === false) {
feedback("{% trans "Edit succeeded, but failed to send email, please check your email configuration." %}", 'success');
} else {
feedback("{% trans "Edit succeeded" %}", 'success');
}
$('.user-status-cur-value', $select_prev).html(select.children('option[value="' +select.val() + '"]').text());
select.addClass('hide');
$select_prev.removeClass('hide');
$.modal.close();
},
error: function() {
feedback("{% trans "Edit failed." %}", 'error');
select.addClass('hide');
$select_prev.removeClass('hide');
$.modal.close();
}
});
});
// select shows, but the user doesn't select a value, or doesn't change the permission, click other place to hide the select
$(document).click(function(e) {
var target = e.target || event.srcElement;
// target can't be edit-icon
if (!$('.user-status-edit-icon, .user-status-select').is(target)) {
$('.user-status').removeClass('hide');
$('.user-status-select').addClass('hide');
}
});
</script>
{% endblock %}

View File

@ -1,6 +1,7 @@
from django.conf.urls import patterns, url
from .views import info, useradmin, user_info, user_remove, useradmin_search
from .views import (info, useradmin, user_info, user_remove, useradmin_search,
user_toggle_status)
urlpatterns = patterns(
'',
@ -9,4 +10,5 @@ urlpatterns = patterns(
url(r'^useradmin/info/(?P<email>[^/]+)/$', user_info, name='user_info'),
url(r'^useradmin/remove/(?P<email>[^/]+)/$', user_remove, name='user_remove'),
url('^useradmin/search/$', useradmin_search, name="useradmin_search"),
url(r'^useradmin/toggle_status/(?P<email>[^/]+)/$', user_toggle_status, name='user_toggle_status'),
)

View File

@ -1,8 +1,9 @@
import json
import logging
from django.core.urlresolvers import reverse
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext as _
@ -10,13 +11,16 @@ import seaserv
from seaserv import seafile_api
from pysearpc import SearpcError
from seahub.auth.decorators import login_required_ajax
from seahub.base.accounts import User
from seahub.base.decorators import require_POST
from seahub.base.models import UserLastLogin
from seahub.institutions.decorators import (inst_admin_required,
inst_admin_can_manage_user)
from seahub.profile.models import Profile, DetailedProfile
from seahub.utils import is_valid_username, clear_token
from seahub.utils.rpc import mute_seafile_api
from seahub.views.sysadmin import email_user_on_activation
logger = logging.getLogger(__name__)
@ -181,3 +185,46 @@ def user_remove(request, email):
messages.error(request, _(u'Failed to delete: the user does not exist'))
return HttpResponseRedirect(next)
@login_required_ajax
@require_POST
@inst_admin_required
@inst_admin_can_manage_user
def user_toggle_status(request, email):
content_type = 'application/json; charset=utf-8'
if not is_valid_username(email):
return HttpResponse(json.dumps({'success': False}), status=400,
content_type=content_type)
try:
user_status = int(request.POST.get('s', 0))
except ValueError:
user_status = 0
try:
user = User.objects.get(email)
user.is_active = bool(user_status)
result_code = user.save()
if result_code == -1:
return HttpResponse(json.dumps({'success': False}), status=403,
content_type=content_type)
if user.is_active is True:
try:
email_user_on_activation(user)
email_sent = True
except Exception as e:
logger.error(e)
email_sent = False
return HttpResponse(json.dumps({'success': True,
'email_sent': email_sent,
}), content_type=content_type)
else:
clear_token(user.email)
return HttpResponse(json.dumps({'success': True}),
content_type=content_type)
except User.DoesNotExist:
return HttpResponse(json.dumps({'success': False}), status=500,
content_type=content_type)

View File

@ -3,25 +3,32 @@
{% block main_panel %}
<div id="user-profile">
{% if user %}
{% if user %}
{% avatar user.username 290 %}
{% else %}
{% avatar "" 290 %}
{% endif %}
<p title="{{ nickname }}" class="nickname ellipsis">{{ nickname }}</p>
{% if d_profile %}
<p title="{{ nickname }}" class="user-profile-nickname ellipsis">{{ nickname }}</p>
<ul>
{% if d_profile %}
{% if d_profile.department %}
<p title="{{ d_profile.department }}" class="info ellipsis">
<span class="icon-building fa-1x vam"></span>
<span class="info-detail vam">{{ d_profile.department }}</span>
</p>
<li title="{{ d_profile.department }}" class="user-profile-info ellipsis">
<span class="user-profile-info-icon icon-building fa-1x vam"></span>
<span class="vam">{{ d_profile.department }}</span>
</li>
{% endif %}
{% if d_profile.telephone %}
<p title="{{ d_profile.telephone }}" class="info ellipsis">
<span class="icon-phone fa-1x vam"></span>
<span class="info-detail vam">{{ d_profile.telephone }}</span>
</p>
<li title="{{ d_profile.telephone }}" class="user-profile-info ellipsis">
<span class="user-profile-info-icon icon-phone fa-1x vam"></span>
<span class="vam">{{ d_profile.telephone }}</span>
</li>
{% endif %}
{% endif %}
{% endif %}
<li title="{{ contact_email }}" class="user-profile-info ellipsis">
<span class="user-profile-info-icon icon-envelope fa-1x vam"></span>
<span class="vam">{{ contact_email }}</span>
</li>
</ul>
{% else %}
{% avatar "" 290 %}
{% endif %}
</div>
{% endblock %}

View File

@ -113,17 +113,20 @@ def user_profile(request, username):
else:
user = None
nickname = '' if user is None else email2nickname(user.username)
if user is not None:
nickname = email2nickname(user.username)
contact_email = Profile.objects.get_contact_email_by_user(user.username)
d_profile = DetailedProfile.objects.get_detailed_profile_by_user(
user.username)
else:
nickname = ''
contact_email = ''
d_profile = None
return render_to_response('profile/user_profile.html', {
'user': user,
'nickname': nickname,
'contact_email': contact_email,
'd_profile': d_profile,
}, context_instance=RequestContext(request))

View File

@ -345,6 +345,8 @@ REST_FRAMEWORK = {
'anon': '5/minute',
'user': '300/minute',
},
# https://github.com/tomchristie/django-rest-framework/issues/2891
'UNICODE_JSON': False,
}
# file and path

View File

@ -91,7 +91,9 @@
<dd><% if (is_pro) { %>
{% trans "Professional Edition" %}
<% if (with_license) { %>
{% trans "expires on" %} <%- license.Expiration %>
{% trans "licensed to" %} <%- license_to %>
,
{% trans "expires on" %} <%- license_expiration %>
<% } %>
<% } else { %>
{% trans "Community Edition" %}
@ -110,7 +112,7 @@
<%- users_count %>
/
<% if (with_license) { %>
<%- license.MaxUsers %>
<%- license_maxusers %>
<% } else { %>
--
<% } %>

View File

@ -1,50 +0,0 @@
{% extends "sysadmin/base.html" %}
{% load seahub_tags i18n %}
{% block cur_info %}tab-cur{% endblock %}
{% block right_panel %}
<h3 class="hd">{% trans "Info" %}</h3>
<dl>
<dt>{% trans "System Info" %}</dt>
<dd>{% if is_pro %}
{% trans "Professional Edition" %} {% if license_dict %} {% trans "expires on" %} {{ license_dict.Expiration}}{% endif %}
{% else %}
{% trans "Community Edition" %}
<a href="http://manual{% if LANGUAGE_CODE == 'zh-cn' %}-cn{% endif %}.seafile.com/deploy_pro/migrate_from_seafile_community_server.html" target="_blank">{% trans "Upgrade to Pro Edition" %}</a>
{% endif %}
</dd>
<dt>{% trans "Libraries" %}</dt>
<dd>{{repos_count}}</dd>
{% if is_pro %}
<dt>{% trans "Active Users" %} / {% trans "Total Users" %} / {% trans "Limits" %}</dt>
<dd>
{% if active_users_count %}{{ active_users_count }}{% else %}--{% endif %}
/
{% if users_count %}{{ users_count }}{% else %}--{% endif %}
/
{% if license_dict %}{{ license_dict.MaxUsers }}{% else %}--{% endif %}
</dd>
{% else %}
<dt>{% trans "Active Users" %} / {% trans "Total Users" %}</dt>
<dd>
{% if active_users_count %}{{ active_users_count }}{% else %}--{% endif %}
/
{% if users_count %}{{ users_count }}{% else %}--{% endif %}
</dd>
{% endif %}
<dt>{% trans "Groups" %}</dt>
<dd>{{groups_count}}</dd>
{% if multi_tenancy %}
<dt>{% trans "Organizations" %}</dt>
<dd>{{org_count}}</dd>
{% endif %}
</dl>
{% endblock %}

View File

@ -45,8 +45,8 @@
</td>
<td>
{% if not user.is_self %}
<a href="#" class="remove-user-btn op vh" data-url="{% url 'user_remove' user.id %}" data-target="{{ user.email }}">{% trans "Delete" %}</a>
<a href="#" class="reset-user-btn op vh" data-url="{% url 'user_reset' user.id %}" data-target="{{ user.email }}">{% trans "ResetPwd" %}</a>
<a href="#" class="remove-user-btn op vh" data-url="{% url 'user_remove' user.email %}" data-target="{{ user.email }}">{% trans "Delete" %}</a>
<a href="#" class="reset-user-btn op vh" data-url="{% url 'user_reset' user.email %}" data-target="{{ user.email }}">{% trans "ResetPwd" %}</a>
{% endif %}
</td>
</tr>
@ -63,12 +63,14 @@
<script type="text/javascript">
{% include 'sysadmin/sys_org_set_quota_js.html' %}
addConfirmTo($('.remove-user-btn'), {
'title':"{% trans "Delete User" %}",
'con':"{% trans "Are you sure you want to delete %s ?" %}"
'title':"{% trans "Delete User" %}",
'con':"{% trans "Are you sure you want to delete %s ?" %}",
'post': true // post request
});
addConfirmTo($('.reset-user-btn'), {
'title':"{% trans "Password Reset" %}",
'con':"{% trans "Are you sure you want to reset the password of %s ?" %}"
'title':"{% trans "Password Reset" %}",
'con':"{% trans "Are you sure you want to reset the password of %s ?" %}",
'post': true // post request
});
$('tr:gt(0)').hover(
function() {

View File

@ -227,7 +227,6 @@ urlpatterns = patterns(
### system admin ###
url(r'^sysadmin/$', sysadmin, name='sysadmin'),
url(r'^sys/info/$', sys_info, name='sys_info'),
url(r'^sys/settings/$', sys_settings, name='sys_settings'),
url(r'^sysadmin/#all-libs/$', fake_view, name='sys_repo_admin'),
url(r'^sysadmin/#libs/(?P<repo_id>[-0-9a-f]{36})/$', fake_view, name='sys_admin_repo'),

View File

@ -10,6 +10,7 @@ import csv, chardet, StringIO
import time
from constance import config
from django.db.models import Q
from django.conf import settings as dj_settings
from django.core.urlresolvers import reverse
from django.contrib import messages
@ -1534,10 +1535,24 @@ def user_search(request):
"""
email = request.GET.get('email', '')
users = ccnet_threaded_rpc.search_emailusers('DB', email, -1, -1)
ldap_users = ccnet_threaded_rpc.search_emailusers('LDAP', email, -1, -1)
# search user from ccnet db
users = ccnet_api.search_emailusers('DB', email, -1, -1)
# search user from ccnet ldap
ldap_users = ccnet_api.search_emailusers('LDAP', email, -1, -1)
users.extend(ldap_users)
# search user from profile
users_from_profile = Profile.objects.filter((Q(nickname__icontains=email)) |
Q(contact_email__icontains=email))
for user in users_from_profile:
try:
user_obj = User.objects.get(email=user.user)
except User.DoesNotExist:
continue
users.append(user_obj)
last_logins = UserLastLogin.objects.filter(username__in=[x.email for x in users])
if ENABLE_TRIAL_ACCOUNT:
trial_users = TrialAccount.objects.filter(user_or_org__in=[x.email for x in users])

View File

@ -1,3 +1,4 @@
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
@ -9,9 +10,6 @@
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `api2_token`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
@ -24,19 +22,8 @@ CREATE TABLE `api2_token` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `api2_token`
--
LOCK TABLES `api2_token` WRITE;
/*!40000 ALTER TABLE `api2_token` DISABLE KEYS */;
/*!40000 ALTER TABLE `api2_token` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `api2_tokenv2`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `api2_tokenv2` (
@ -54,19 +41,8 @@ CREATE TABLE `api2_tokenv2` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `api2_tokenv2`
--
LOCK TABLES `api2_tokenv2` WRITE;
/*!40000 ALTER TABLE `api2_tokenv2` DISABLE KEYS */;
/*!40000 ALTER TABLE `api2_tokenv2` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `avatar_avatar`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `avatar_avatar` (
@ -79,19 +55,8 @@ CREATE TABLE `avatar_avatar` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `avatar_avatar`
--
LOCK TABLES `avatar_avatar` WRITE;
/*!40000 ALTER TABLE `avatar_avatar` DISABLE KEYS */;
/*!40000 ALTER TABLE `avatar_avatar` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `avatar_groupavatar`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `avatar_groupavatar` (
@ -103,19 +68,8 @@ CREATE TABLE `avatar_groupavatar` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `avatar_groupavatar`
--
LOCK TABLES `avatar_groupavatar` WRITE;
/*!40000 ALTER TABLE `avatar_groupavatar` DISABLE KEYS */;
/*!40000 ALTER TABLE `avatar_groupavatar` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_clientlogintoken`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_clientlogintoken` (
@ -127,19 +81,8 @@ CREATE TABLE `base_clientlogintoken` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_clientlogintoken`
--
LOCK TABLES `base_clientlogintoken` WRITE;
/*!40000 ALTER TABLE `base_clientlogintoken` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_clientlogintoken` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_commandslastcheck`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_commandslastcheck` (
@ -150,19 +93,8 @@ CREATE TABLE `base_commandslastcheck` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_commandslastcheck`
--
LOCK TABLES `base_commandslastcheck` WRITE;
/*!40000 ALTER TABLE `base_commandslastcheck` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_commandslastcheck` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_devicetoken`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_devicetoken` (
@ -177,19 +109,8 @@ CREATE TABLE `base_devicetoken` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_devicetoken`
--
LOCK TABLES `base_devicetoken` WRITE;
/*!40000 ALTER TABLE `base_devicetoken` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_devicetoken` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_filediscuss`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_filediscuss` (
@ -205,19 +126,8 @@ CREATE TABLE `base_filediscuss` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_filediscuss`
--
LOCK TABLES `base_filediscuss` WRITE;
/*!40000 ALTER TABLE `base_filediscuss` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_filediscuss` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_groupenabledmodule`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_groupenabledmodule` (
@ -229,19 +139,8 @@ CREATE TABLE `base_groupenabledmodule` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_groupenabledmodule`
--
LOCK TABLES `base_groupenabledmodule` WRITE;
/*!40000 ALTER TABLE `base_groupenabledmodule` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_groupenabledmodule` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_innerpubmsg`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_innerpubmsg` (
@ -253,19 +152,8 @@ CREATE TABLE `base_innerpubmsg` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_innerpubmsg`
--
LOCK TABLES `base_innerpubmsg` WRITE;
/*!40000 ALTER TABLE `base_innerpubmsg` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_innerpubmsg` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_innerpubmsgreply`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_innerpubmsgreply` (
@ -280,19 +168,8 @@ CREATE TABLE `base_innerpubmsgreply` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_innerpubmsgreply`
--
LOCK TABLES `base_innerpubmsgreply` WRITE;
/*!40000 ALTER TABLE `base_innerpubmsgreply` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_innerpubmsgreply` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_userenabledmodule`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_userenabledmodule` (
@ -304,19 +181,8 @@ CREATE TABLE `base_userenabledmodule` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_userenabledmodule`
--
LOCK TABLES `base_userenabledmodule` WRITE;
/*!40000 ALTER TABLE `base_userenabledmodule` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_userenabledmodule` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_userlastlogin`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_userlastlogin` (
@ -328,19 +194,8 @@ CREATE TABLE `base_userlastlogin` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_userlastlogin`
--
LOCK TABLES `base_userlastlogin` WRITE;
/*!40000 ALTER TABLE `base_userlastlogin` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_userlastlogin` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `base_userstarredfiles`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `base_userstarredfiles` (
@ -356,19 +211,8 @@ CREATE TABLE `base_userstarredfiles` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `base_userstarredfiles`
--
LOCK TABLES `base_userstarredfiles` WRITE;
/*!40000 ALTER TABLE `base_userstarredfiles` DISABLE KEYS */;
/*!40000 ALTER TABLE `base_userstarredfiles` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `captcha_captchastore`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `captcha_captchastore` (
@ -382,19 +226,8 @@ CREATE TABLE `captcha_captchastore` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `captcha_captchastore`
--
LOCK TABLES `captcha_captchastore` WRITE;
/*!40000 ALTER TABLE `captcha_captchastore` DISABLE KEYS */;
/*!40000 ALTER TABLE `captcha_captchastore` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `constance_config`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `constance_config` (
@ -406,19 +239,8 @@ CREATE TABLE `constance_config` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `constance_config`
--
LOCK TABLES `constance_config` WRITE;
/*!40000 ALTER TABLE `constance_config` DISABLE KEYS */;
/*!40000 ALTER TABLE `constance_config` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `contacts_contact`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `contacts_contact` (
@ -432,19 +254,8 @@ CREATE TABLE `contacts_contact` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `contacts_contact`
--
LOCK TABLES `contacts_contact` WRITE;
/*!40000 ALTER TABLE `contacts_contact` DISABLE KEYS */;
/*!40000 ALTER TABLE `contacts_contact` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `django_content_type`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `django_content_type` (
@ -456,20 +267,9 @@ CREATE TABLE `django_content_type` (
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `django_content_type`
--
LOCK TABLES `django_content_type` WRITE;
/*!40000 ALTER TABLE `django_content_type` DISABLE KEYS */;
INSERT INTO `django_content_type` VALUES (10,'api2','token'),(11,'api2','tokenv2'),(12,'avatar','avatar'),(13,'avatar','groupavatar'),(15,'base','clientlogintoken'),(19,'base','commandslastcheck'),(18,'base','devicetoken'),(17,'base','filediscuss'),(14,'base','groupenabledmodule'),(20,'base','innerpubmsg'),(21,'base','innerpubmsgreply'),(16,'base','userenabledmodule'),(22,'base','userlastlogin'),(23,'base','userstarredfiles'),(4,'captcha','captchastore'),(24,'contacts','contact'),(1,'contenttypes','contenttype'),(5,'database','constance'),(30,'group','groupmessage'),(31,'group','messageattachment'),(32,'group','messagereply'),(29,'group','publicgroup'),(26,'institutions','institution'),(25,'institutions','institutionadmin'),(35,'message','usermessage'),(33,'message','usermsgattachment'),(34,'message','usermsglastcheck'),(36,'notifications','notification'),(37,'notifications','usernotification'),(38,'options','useroptions'),(47,'organizations','orgmemberquota'),(6,'post_office','attachment'),(8,'post_office','email'),(7,'post_office','emailtemplate'),(9,'post_office','log'),(40,'profile','detailedprofile'),(39,'profile','profile'),(3,'registration','registrationprofile'),(2,'sessions','session'),(44,'share','anonymousshare'),(43,'share','fileshare'),(45,'share','orgfileshare'),(41,'share','privatefiledirshare'),(42,'share','uploadlinkshare'),(46,'sysadmin_extra','userloginlog'),(28,'wiki','groupwiki'),(27,'wiki','personalwiki');
/*!40000 ALTER TABLE `django_content_type` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `django_migrations`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `django_migrations` (
@ -481,20 +281,9 @@ CREATE TABLE `django_migrations` (
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `django_migrations`
--
LOCK TABLES `django_migrations` WRITE;
/*!40000 ALTER TABLE `django_migrations` DISABLE KEYS */;
INSERT INTO `django_migrations` VALUES (1,'captcha','0001_initial','2016-03-19 16:11:16.130138'),(2,'contenttypes','0001_initial','2016-03-19 16:11:16.552740'),(3,'contenttypes','0002_remove_content_type_name','2016-03-19 16:11:16.937725'),(4,'database','0001_initial','2016-03-19 16:11:17.155813'),(5,'institutions','0001_initial','2016-03-19 16:11:17.784321'),(6,'post_office','0001_initial','2016-03-19 16:11:21.250718'),(7,'post_office','0002_add_i18n_and_backend_alias','2016-03-19 16:11:23.104720'),(8,'sessions','0001_initial','2016-03-19 16:11:23.598539');
INSERT INTO `django_migrations` VALUES (1,'captcha','0001_initial','2016-06-30 10:21:46.470795'),(2,'contenttypes','0001_initial','2016-06-30 10:21:46.526404'),(3,'contenttypes','0002_remove_content_type_name','2016-06-30 10:21:46.742298'),(4,'database','0001_initial','2016-06-30 10:21:46.766493'),(5,'institutions','0001_initial','2016-06-30 10:21:46.839693'),(6,'post_office','0001_initial','2016-06-30 10:21:47.467643'),(7,'post_office','0002_add_i18n_and_backend_alias','2016-06-30 10:21:47.915981'),(8,'sessions','0001_initial','2016-06-30 10:21:48.100284');
/*!40000 ALTER TABLE `django_migrations` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `django_session`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `django_session` (
@ -506,19 +295,8 @@ CREATE TABLE `django_session` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `django_session`
--
LOCK TABLES `django_session` WRITE;
/*!40000 ALTER TABLE `django_session` DISABLE KEYS */;
/*!40000 ALTER TABLE `django_session` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `group_groupmessage`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `group_groupmessage` (
@ -532,19 +310,8 @@ CREATE TABLE `group_groupmessage` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `group_groupmessage`
--
LOCK TABLES `group_groupmessage` WRITE;
/*!40000 ALTER TABLE `group_groupmessage` DISABLE KEYS */;
/*!40000 ALTER TABLE `group_groupmessage` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `group_messageattachment`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `group_messageattachment` (
@ -560,19 +327,8 @@ CREATE TABLE `group_messageattachment` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `group_messageattachment`
--
LOCK TABLES `group_messageattachment` WRITE;
/*!40000 ALTER TABLE `group_messageattachment` DISABLE KEYS */;
/*!40000 ALTER TABLE `group_messageattachment` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `group_messagereply`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `group_messagereply` (
@ -587,19 +343,8 @@ CREATE TABLE `group_messagereply` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `group_messagereply`
--
LOCK TABLES `group_messagereply` WRITE;
/*!40000 ALTER TABLE `group_messagereply` DISABLE KEYS */;
/*!40000 ALTER TABLE `group_messagereply` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `group_publicgroup`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `group_publicgroup` (
@ -610,19 +355,8 @@ CREATE TABLE `group_publicgroup` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `group_publicgroup`
--
LOCK TABLES `group_publicgroup` WRITE;
/*!40000 ALTER TABLE `group_publicgroup` DISABLE KEYS */;
/*!40000 ALTER TABLE `group_publicgroup` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `institutions_institution`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `institutions_institution` (
@ -633,19 +367,8 @@ CREATE TABLE `institutions_institution` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `institutions_institution`
--
LOCK TABLES `institutions_institution` WRITE;
/*!40000 ALTER TABLE `institutions_institution` DISABLE KEYS */;
/*!40000 ALTER TABLE `institutions_institution` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `institutions_institutionadmin`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `institutions_institutionadmin` (
@ -658,19 +381,8 @@ CREATE TABLE `institutions_institutionadmin` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `institutions_institutionadmin`
--
LOCK TABLES `institutions_institutionadmin` WRITE;
/*!40000 ALTER TABLE `institutions_institutionadmin` DISABLE KEYS */;
/*!40000 ALTER TABLE `institutions_institutionadmin` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `message_usermessage`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `message_usermessage` (
@ -688,19 +400,8 @@ CREATE TABLE `message_usermessage` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `message_usermessage`
--
LOCK TABLES `message_usermessage` WRITE;
/*!40000 ALTER TABLE `message_usermessage` DISABLE KEYS */;
/*!40000 ALTER TABLE `message_usermessage` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `message_usermsgattachment`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `message_usermsgattachment` (
@ -715,19 +416,8 @@ CREATE TABLE `message_usermsgattachment` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `message_usermsgattachment`
--
LOCK TABLES `message_usermsgattachment` WRITE;
/*!40000 ALTER TABLE `message_usermsgattachment` DISABLE KEYS */;
/*!40000 ALTER TABLE `message_usermsgattachment` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `message_usermsglastcheck`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `message_usermsglastcheck` (
@ -737,19 +427,8 @@ CREATE TABLE `message_usermsglastcheck` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `message_usermsglastcheck`
--
LOCK TABLES `message_usermsglastcheck` WRITE;
/*!40000 ALTER TABLE `message_usermsglastcheck` DISABLE KEYS */;
/*!40000 ALTER TABLE `message_usermsglastcheck` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `notifications_notification`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `notifications_notification` (
@ -760,19 +439,8 @@ CREATE TABLE `notifications_notification` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `notifications_notification`
--
LOCK TABLES `notifications_notification` WRITE;
/*!40000 ALTER TABLE `notifications_notification` DISABLE KEYS */;
/*!40000 ALTER TABLE `notifications_notification` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `notifications_usernotification`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `notifications_usernotification` (
@ -788,19 +456,8 @@ CREATE TABLE `notifications_usernotification` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `notifications_usernotification`
--
LOCK TABLES `notifications_usernotification` WRITE;
/*!40000 ALTER TABLE `notifications_usernotification` DISABLE KEYS */;
/*!40000 ALTER TABLE `notifications_usernotification` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `options_useroptions`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `options_useroptions` (
@ -813,19 +470,8 @@ CREATE TABLE `options_useroptions` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `options_useroptions`
--
LOCK TABLES `options_useroptions` WRITE;
/*!40000 ALTER TABLE `options_useroptions` DISABLE KEYS */;
/*!40000 ALTER TABLE `options_useroptions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `organizations_orgmemberquota`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `organizations_orgmemberquota` (
@ -837,19 +483,8 @@ CREATE TABLE `organizations_orgmemberquota` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `organizations_orgmemberquota`
--
LOCK TABLES `organizations_orgmemberquota` WRITE;
/*!40000 ALTER TABLE `organizations_orgmemberquota` DISABLE KEYS */;
/*!40000 ALTER TABLE `organizations_orgmemberquota` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `post_office_attachment`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `post_office_attachment` (
@ -860,19 +495,8 @@ CREATE TABLE `post_office_attachment` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `post_office_attachment`
--
LOCK TABLES `post_office_attachment` WRITE;
/*!40000 ALTER TABLE `post_office_attachment` DISABLE KEYS */;
/*!40000 ALTER TABLE `post_office_attachment` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `post_office_attachment_emails`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `post_office_attachment_emails` (
@ -887,19 +511,8 @@ CREATE TABLE `post_office_attachment_emails` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `post_office_attachment_emails`
--
LOCK TABLES `post_office_attachment_emails` WRITE;
/*!40000 ALTER TABLE `post_office_attachment_emails` DISABLE KEYS */;
/*!40000 ALTER TABLE `post_office_attachment_emails` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `post_office_email`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `post_office_email` (
@ -930,19 +543,8 @@ CREATE TABLE `post_office_email` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `post_office_email`
--
LOCK TABLES `post_office_email` WRITE;
/*!40000 ALTER TABLE `post_office_email` DISABLE KEYS */;
/*!40000 ALTER TABLE `post_office_email` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `post_office_emailtemplate`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `post_office_emailtemplate` (
@ -963,19 +565,8 @@ CREATE TABLE `post_office_emailtemplate` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `post_office_emailtemplate`
--
LOCK TABLES `post_office_emailtemplate` WRITE;
/*!40000 ALTER TABLE `post_office_emailtemplate` DISABLE KEYS */;
/*!40000 ALTER TABLE `post_office_emailtemplate` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `post_office_log`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `post_office_log` (
@ -991,19 +582,8 @@ CREATE TABLE `post_office_log` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `post_office_log`
--
LOCK TABLES `post_office_log` WRITE;
/*!40000 ALTER TABLE `post_office_log` DISABLE KEYS */;
/*!40000 ALTER TABLE `post_office_log` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `profile_detailedprofile`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `profile_detailedprofile` (
@ -1016,19 +596,8 @@ CREATE TABLE `profile_detailedprofile` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `profile_detailedprofile`
--
LOCK TABLES `profile_detailedprofile` WRITE;
/*!40000 ALTER TABLE `profile_detailedprofile` DISABLE KEYS */;
/*!40000 ALTER TABLE `profile_detailedprofile` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `profile_profile`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `profile_profile` (
@ -1048,19 +617,8 @@ CREATE TABLE `profile_profile` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `profile_profile`
--
LOCK TABLES `profile_profile` WRITE;
/*!40000 ALTER TABLE `profile_profile` DISABLE KEYS */;
/*!40000 ALTER TABLE `profile_profile` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `registration_registrationprofile`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `registration_registrationprofile` (
@ -1071,19 +629,8 @@ CREATE TABLE `registration_registrationprofile` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `registration_registrationprofile`
--
LOCK TABLES `registration_registrationprofile` WRITE;
/*!40000 ALTER TABLE `registration_registrationprofile` DISABLE KEYS */;
/*!40000 ALTER TABLE `registration_registrationprofile` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `share_anonymousshare`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `share_anonymousshare` (
@ -1097,19 +644,8 @@ CREATE TABLE `share_anonymousshare` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `share_anonymousshare`
--
LOCK TABLES `share_anonymousshare` WRITE;
/*!40000 ALTER TABLE `share_anonymousshare` DISABLE KEYS */;
/*!40000 ALTER TABLE `share_anonymousshare` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `share_fileshare`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `share_fileshare` (
@ -1131,19 +667,8 @@ CREATE TABLE `share_fileshare` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `share_fileshare`
--
LOCK TABLES `share_fileshare` WRITE;
/*!40000 ALTER TABLE `share_fileshare` DISABLE KEYS */;
/*!40000 ALTER TABLE `share_fileshare` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `share_orgfileshare`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `share_orgfileshare` (
@ -1157,19 +682,8 @@ CREATE TABLE `share_orgfileshare` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `share_orgfileshare`
--
LOCK TABLES `share_orgfileshare` WRITE;
/*!40000 ALTER TABLE `share_orgfileshare` DISABLE KEYS */;
/*!40000 ALTER TABLE `share_orgfileshare` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `share_privatefiledirshare`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `share_privatefiledirshare` (
@ -1189,19 +703,8 @@ CREATE TABLE `share_privatefiledirshare` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `share_privatefiledirshare`
--
LOCK TABLES `share_privatefiledirshare` WRITE;
/*!40000 ALTER TABLE `share_privatefiledirshare` DISABLE KEYS */;
/*!40000 ALTER TABLE `share_privatefiledirshare` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `share_uploadlinkshare`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `share_uploadlinkshare` (
@ -1221,19 +724,8 @@ CREATE TABLE `share_uploadlinkshare` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `share_uploadlinkshare`
--
LOCK TABLES `share_uploadlinkshare` WRITE;
/*!40000 ALTER TABLE `share_uploadlinkshare` DISABLE KEYS */;
/*!40000 ALTER TABLE `share_uploadlinkshare` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `sysadmin_extra_userloginlog`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sysadmin_extra_userloginlog` (
@ -1247,19 +739,8 @@ CREATE TABLE `sysadmin_extra_userloginlog` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `sysadmin_extra_userloginlog`
--
LOCK TABLES `sysadmin_extra_userloginlog` WRITE;
/*!40000 ALTER TABLE `sysadmin_extra_userloginlog` DISABLE KEYS */;
/*!40000 ALTER TABLE `sysadmin_extra_userloginlog` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `wiki_groupwiki`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `wiki_groupwiki` (
@ -1271,19 +752,8 @@ CREATE TABLE `wiki_groupwiki` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `wiki_groupwiki`
--
LOCK TABLES `wiki_groupwiki` WRITE;
/*!40000 ALTER TABLE `wiki_groupwiki` DISABLE KEYS */;
/*!40000 ALTER TABLE `wiki_groupwiki` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `wiki_personalwiki`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `wiki_personalwiki` (
@ -1295,14 +765,8 @@ CREATE TABLE `wiki_personalwiki` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `wiki_personalwiki`
--
LOCK TABLES `wiki_personalwiki` WRITE;
/*!40000 ALTER TABLE `wiki_personalwiki` DISABLE KEYS */;
/*!40000 ALTER TABLE `wiki_personalwiki` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@ -1313,4 +777,3 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2016-03-19 16:17:38

View File

@ -461,7 +461,6 @@ define([
// Directory Operations
events: {
'click .path-link': 'visitDir',
'click #add-new-dir': 'newDir',
'click #add-new-file': 'newFile',
'click #share-cur-dir': 'share',
@ -903,6 +902,7 @@ define([
dirents.remove(selected_dirents);
_this.$('th .checkbox').removeClass('checkbox-checked');
_this.$('#multi-dirents-op').hide();
_this.$('#cur-dir-ops').show();
} else {
$(selected_dirents).each(function() {
if (data['deleted'].indexOf(this.get('obj_name')) != -1) {
@ -1044,6 +1044,7 @@ define([
dirents.remove(files);
_this.$('th .checkbox').removeClass('checkbox-checked');
_this.$('#multi-dirents-op').hide();
_this.$('#cur-dir-ops').show();
} else {
$(dirs).each(function() {
if (this.get('obj_name') in data['success']) {

View File

@ -582,12 +582,12 @@ define([
dataType: 'json',
delay: 250,
cache: true,
data: function (params) {
data: function(params) {
return {
q: params
};
},
results: function (data) {
results: function(data) {
var user_list = [], users = data['users'];
for (var i = 0, len = users.length; i < len; i++) {
@ -595,8 +595,9 @@ define([
"id": users[i].email,
// for search. both name & email can be searched.
// use ' '(space) to separate name & email
"text": users[i].name + ' ' + users[i].email,
"text": users[i].name + ' ' + users[i].contact_email,
"avatar_url": users[i].avatar_url,
"contact_email": users[i].contact_email,
"name": users[i].name
});
}
@ -610,7 +611,7 @@ define([
// format items shown in the drop-down menu
formatResult: function(item) {
if (item.avatar_url) {
return '<img src="' + item.avatar_url + '" width="32" height="32" class="avatar"><span class="text ellipsis">' + _this.HTMLescape(item.name) + '<br />' + _this.HTMLescape(item.id) + '</span>';
return '<img src="' + item.avatar_url + '" width="32" height="32" class="avatar"><span class="text ellipsis">' + _this.HTMLescape(item.name) + '<br />' + _this.HTMLescape(item.contact_email) + '</span>';
} else {
return; // if no match, show nothing
}

View File

@ -1,5 +1,7 @@
import json
from mock import patch
from django.core.urlresolvers import reverse
from seahub.test_utils import BaseTestCase
@ -11,12 +13,42 @@ class SysinfoTest(BaseTestCase):
def tearDown(self):
self.remove_repo()
def test_get_sysinfo(self):
@patch('seahub.api2.endpoints.admin.sysinfo.is_pro_version')
def test_get_sysinfo_in_community_edition(self, mock_is_pro_version):
mock_is_pro_version.return_value = False
url = reverse('api-v2.1-sysinfo')
resp = self.client.get(url)
json_resp = json.loads(resp.content)
assert len(json_resp) == 9
assert json_resp['is_pro'] == False
assert json_resp['multi_tenancy_enabled'] == False
assert len(json_resp) == 11
assert json_resp['is_pro'] is False
assert json_resp['multi_tenancy_enabled'] is False
assert json_resp['license_maxusers'] == 0
@patch('seahub.api2.endpoints.admin.sysinfo.is_pro_version')
@patch('seahub.api2.endpoints.admin.sysinfo.SysInfo._get_license_dict')
def test_get_sysinfo_in_pro_edition(self, mock_get_license_dict, mock_is_pro_version):
test_user = 'Test user'
mock_is_pro_version.return_value = True
mock_get_license_dict.return_value = {
'Hash': '2981bd12cf0c83c81aaa453ce249ffdd2e492ed2220f3c89c57f06518de36c487c873be960577a0534f3de4ac2bb52d3918016aaa07d60dccbce92673bc23604f4d8ff547f88287c398f74f16e114a8a3b978cce66961fd0facd283da7b050b5fc6205934420e1b4a65daf1c6dcdb2dc78e38a3799eeb5533779595912f1723129037f093f925d8ab94478c8aded304c62d003c07a6e98e706fdf81b6f73c3a806f523bbff1a92f8eb8ea325e09b2b80acfc4b99dd0f5b339d5ed832da00bad3394b9d40a09cce6066b6dc2c9b2ec47338de41867f5c2380c96f7708a5e9cdf244fbdfa1cc174751b90e74e620f53778593b84ec3b15175c3e432c20dcb4cfde',
'Name': test_user,
'Mode': 'life-time',
'Licencetype': 'User',
'LicenceKEY': '1461659711',
'Expiration': '2016-5-6',
'MaxUsers': '500',
'ProductID': 'Seafile server'
}
url = reverse('api-v2.1-sysinfo')
resp = self.client.get(url)
json_resp = json.loads(resp.content)
assert len(json_resp) == 11
assert json_resp['license_maxusers'] == 500
assert json_resp['license_to'] == test_user

View File

@ -1,6 +1,8 @@
import json
from mock import patch
from django.core.urlresolvers import reverse
from django.test import override_settings
from seahub.profile.models import Profile
from seahub.profile.utils import refresh_cache
@ -11,6 +13,7 @@ class SearchUserTest(BaseTestCase):
self.login_as(self.user)
self.endpoint = reverse('search-user')
@override_settings(CLOUD_MODE = False)
def test_can_search(self):
email = self.admin.email
nickname = 'admin_test'
@ -29,6 +32,7 @@ class SearchUserTest(BaseTestCase):
assert json_resp['users'][0]['name'] == nickname
assert json_resp['users'][0]['contact_email'] == contact_email
@override_settings(CLOUD_MODE = False)
def test_search_myself(self):
email = self.user.email
nickname = 'user_test'
@ -47,6 +51,7 @@ class SearchUserTest(BaseTestCase):
assert json_resp['users'][0]['name'] == nickname
assert json_resp['users'][0]['contact_email'] == contact_email
@override_settings(CLOUD_MODE = False)
def test_search_without_myself(self):
email = self.user.email
resp = self.client.get(self.endpoint + '?include_self=0&q=' + email)
@ -55,6 +60,7 @@ class SearchUserTest(BaseTestCase):
self.assertEqual(200, resp.status_code)
assert len(json_resp['users']) == 0
@override_settings(CLOUD_MODE = False)
def test_search_unregistered_user(self):
resp = self.client.get(self.endpoint + '?q=unregistered_user@seafile.com')
json_resp = json.loads(resp.content)
@ -62,6 +68,7 @@ class SearchUserTest(BaseTestCase):
self.assertEqual(200, resp.status_code)
assert len(json_resp['users']) == 0
@override_settings(CLOUD_MODE = False)
def test_can_search_by_nickname(self):
admin_email = self.admin.email
@ -81,6 +88,7 @@ class SearchUserTest(BaseTestCase):
assert json_resp['users'][0]['name'] == 'Carl Smith'
assert json_resp['users'][0]['contact_email'] == 'new_mail@test.com'
@override_settings(CLOUD_MODE = False)
def test_can_search_by_nickname_insensitive(self):
admin_email = self.admin.email
@ -112,6 +120,7 @@ class SearchUserTest(BaseTestCase):
assert json_resp['users'][0]['name'] == 'Carl Smith'
assert json_resp['users'][0]['contact_email'] == 'new_mail@test.com'
@override_settings(CLOUD_MODE = False)
def test_can_search_by_contact_email(self):
admin_email = self.admin.email
nickname = 'admin_test'
@ -132,3 +141,16 @@ class SearchUserTest(BaseTestCase):
assert json_resp['users'][0]['name'] == nickname
assert json_resp['users'][0]['contact_email'] == 'new_mail@test.com'
@override_settings(CLOUD_MODE = True)
@override_settings(ENABLE_GLOBAL_ADDRESSBOOK = False)
@patch('seahub.api2.endpoints.search_user.is_org_context')
def test_search_full_email(self, mock_is_org_context):
mock_is_org_context.return_value = False
resp = self.client.get(self.endpoint + '?q=%s' % self.admin.username)
json_resp = json.loads(resp.content)
self.assertEqual(200, resp.status_code)
assert json_resp['users'][0]['email'] == self.admin.username

View File

@ -0,0 +1,118 @@
import os
import json
from django.core.urlresolvers import reverse
from seaserv import seafile_api
from seahub.test_utils import BaseTestCase
from tests.common.utils import randstring
try:
from seahub.settings import LOCAL_PRO_DEV_ENV
except ImportError:
LOCAL_PRO_DEV_ENV = False
class DirSubRepoViewTest(BaseTestCase):
def setUp(self):
self.user_name = self.user.username
self.user_repo_id = self.repo.id
self.user_folder_path = self.folder
self.user_folder_name = os.path.basename(self.folder.rstrip('/'))
self.admin_name = self.admin.username
self.url = reverse("api2-dir-sub-repo", args=[self.user_repo_id])
def tearDown(self):
self.remove_repo()
def test_can_create_dir_sub_repo(self):
self.login_as(self.user)
args = "?p=%s&name=%s" % (self.user_folder_path, self.user_folder_name)
resp = self.client.get(self.url + args)
json_resp = json.loads(resp.content)
assert len(json_resp['sub_repo_id']) == 36
def test_can_create_in_encrypted_lib(self):
password = randstring(8)
encrypted_repo_id = seafile_api.create_repo(
'encrypted_repo_name', '', self.user_name, password)
dirname = randstring(8)
seafile_api.post_dir(repo_id=encrypted_repo_id,
parent_dir='/', dirname=dirname, username=self.user_name)
self.login_as(self.user)
url = reverse("api2-dir-sub-repo", args=[encrypted_repo_id])
args = "?p=/%s&name=%s&password=%s" % (dirname, dirname, password)
resp = self.client.get(url + args)
json_resp = json.loads(resp.content)
assert len(json_resp['sub_repo_id']) == 36
self.remove_repo(encrypted_repo_id)
def test_create_in_encrypted_lib_with_invalid_password(self):
password = randstring(8)
encrypted_repo_id = seafile_api.create_repo(
'encrypted_repo_name', '', self.user_name, password)
dirname = randstring(8)
seafile_api.post_dir(repo_id=encrypted_repo_id,
parent_dir='/', dirname=dirname, username=self.user_name)
self.login_as(self.user)
url = reverse("api2-dir-sub-repo", args=[encrypted_repo_id])
# test invalid password argument
args = "?p=/%s&name=%s&invalid_password=%s" % (dirname, dirname, password)
resp = self.client.get(url + args)
self.assertEqual(400, resp.status_code)
# test wrong password
args = "?p=/%s&name=%s&password=%s" % (dirname, dirname, 'invalid_password')
resp = self.client.get(url + args)
self.assertEqual(400, resp.status_code)
json_resp = json.loads(resp.content)
assert json_resp['error_msg'] == 'Wrong password'
self.remove_repo(encrypted_repo_id)
def test_create_with_invalid_repo_permission(self):
self.login_as(self.admin)
args = "?p=%s&name=%s" % (self.user_folder_path, self.user_folder_name)
resp = self.client.get(self.url + args)
self.assertEqual(403, resp.status_code)
def test_create_with_r_permission_folder(self):
if not LOCAL_PRO_DEV_ENV:
return
self.set_user_folder_r_permission_to_admin()
self.login_as(self.admin)
args = "?p=%s&name=%s" % (self.user_folder_path, self.user_folder_name)
resp = self.client.get(self.url + args)
json_resp = json.loads(resp.content)
assert len(json_resp['sub_repo_id']) == 36
def test_create_with_rw_permission_folder(self):
if not LOCAL_PRO_DEV_ENV:
return
self.set_user_folder_r_permission_to_admin()
self.login_as(self.admin)
args = "?p=%s&name=%s" % (self.user_folder_path, self.user_folder_name)
resp = self.client.get(self.url + args)
json_resp = json.loads(resp.content)
assert len(json_resp['sub_repo_id']) == 36

View File

@ -1,5 +1,5 @@
from seahub.test_utils import BaseTestCase
from seahub.base.accounts import User
from seahub.base.accounts import User, RegistrationForm
from post_office.models import Email
@ -31,3 +31,38 @@ class UserPermissionsTest(BaseTestCase):
assert self.user.permissions.can_invite_guest() is False
assert self.user.permissions.can_export_files_via_mobile_client() is True
class RegistrationFormTest(BaseTestCase):
def setUp(self):
self.valid_emails = [
'a@1.com',
'a.1@1.com',
'a+.1@1.com-pany',
'a+-_.1@1.com-pany',
]
self.invalid_emails = [
'"a"@1.com',
'<script>@1.com',
'//@1.com',
'a+.-{}?1@1.com',
'a+.-()1@1.com',
]
self.form_class = RegistrationForm
def test_allow_register(self):
for e in self.valid_emails:
assert self.form_class.allow_register(e) is True
for e in self.invalid_emails:
assert self.form_class.allow_register(e) is False
def test_clean_email(self):
form = self.form_class({'email': 'some_random_user@1.com',
'password1': '123',
'password2': '123',
})
assert form.is_valid() is True
assert form.clean_email() == 'some_random_user@1.com'

View File

@ -1,8 +1,10 @@
from django.core import mail
from django.conf import settings
from django.core.urlresolvers import reverse
from django.http.cookie import parse_cookie
from django.test import override_settings
from seahub.base.accounts import User
from seahub.institutions.models import Institution, InstitutionAdmin
from seahub.profile.models import Profile
from seahub.test_utils import BaseTestCase
@ -67,3 +69,47 @@ class UseradminSearchTest(InstTestBase):
assert resp.context['inst'] == self.inst
assert len(resp.context['users']) == 2
assert resp.context['q'] == '@'
class UserToggleStatusTest(InstTestBase):
@override_settings(
MIDDLEWARE_CLASSES=settings.MIDDLEWARE_CLASSES,
MULTI_INSTITUTION=True
)
def test_can_activate(self):
self.login_as(self.user)
self.assertEqual(len(mail.outbox), 0)
old_passwd = self.admin.enc_password
resp = self.client.post(
reverse('institutions:user_toggle_status', args=[self.admin.username]),
{'s': 1},
HTTP_X_REQUESTED_WITH='XMLHttpRequest'
)
self.assertEqual(200, resp.status_code)
self.assertContains(resp, '"success": true')
u = User.objects.get(email=self.admin.username)
assert u.is_active is True
assert u.enc_password == old_passwd
self.assertEqual(len(mail.outbox), 1)
@override_settings(
MIDDLEWARE_CLASSES=settings.MIDDLEWARE_CLASSES,
MULTI_INSTITUTION=True
)
def test_can_deactivate(self):
self.login_as(self.user)
old_passwd = self.admin.enc_password
resp = self.client.post(
reverse('institutions:user_toggle_status', args=[self.admin.username]),
{'s': 0},
HTTP_X_REQUESTED_WITH='XMLHttpRequest'
)
self.assertEqual(200, resp.status_code)
self.assertContains(resp, '"success": true')
u = User.objects.get(email=self.admin.username)
assert u.is_active is False
assert u.enc_password == old_passwd

View File

@ -1,12 +1,12 @@
import os
from mock import patch
import pytest
from django.conf.urls import patterns, url
from django.core.urlresolvers import reverse
import seahub
from seahub.test_utils import BaseTestCase
from seahub.views.sysadmin import sys_virus_scan_records, sys_delete_virus_scan_records
TRAVIS = 'TRAVIS' in os.environ
class VirusScanRecord(object):
def __init__(self, repo_id):
@ -14,17 +14,28 @@ class VirusScanRecord(object):
class SysVirusScanRecordsTest(BaseTestCase):
urls = 'seahub.urls'
# @patch('seahub.utils.EVENTS_ENABLED', True)
# @patch('seahub.utils.get_virus_record')
# def test_can_list_empty(self, mock_get_virus_record):
# mock_get_virus_record.return_value = []
def setUp(self):
# http://stackoverflow.com/questions/4892210/django-urlresolver-adding-urls-at-runtime-for-testing
super(SysVirusScanRecordsTest, self).setUp()
# self.login_as(self.admin)
self.original_urls = seahub.urls.urlpatterns
seahub.urls.urlpatterns += patterns(
'',
url(r'^sys/virus_scan_records/$', sys_virus_scan_records, name='sys_virus_scan_records'),
url(r'^sys/virus_scan_records/delete/(?P<vid>\d+)/$', sys_delete_virus_scan_records, name='sys_delete_virus_scan_records'),
)
# resp = self.client.get(reverse('sys_virus_scan_records'))
# self.assertEqual(200, resp.status_code)
# self.assertTemplateUsed(resp, 'sysadmin/sys_virus_scan_records.html')
@patch('seahub.views.sysadmin.get_virus_record')
def test_can_list_empty(self, mock_get_virus_record):
mock_get_virus_record.return_value = []
self.login_as(self.admin)
resp = self.client.get(reverse('sys_virus_scan_records'))
self.assertEqual(200, resp.status_code)
self.assertTemplateUsed(resp, 'sysadmin/sys_virus_scan_records.html')
def _get_virus_record(self, start, limit):
records = []
@ -36,12 +47,8 @@ class SysVirusScanRecordsTest(BaseTestCase):
return records
@pytest.mark.skipif(TRAVIS, reason="TODO: this test can only be run seperately due to the url module init in django, we may need to reload url conf: https://gist.github.com/anentropic/9ac47f6518c88fa8d2b0")
@patch('seahub.utils.EVENTS_ENABLED')
@patch('seahub.utils.get_virus_record')
def test_can_list_records_num_more_than_10(self, mock_get_virus_record,
mock_events_enabled):
mock_events_enabled = True
@patch('seahub.views.sysadmin.get_virus_record')
def test_can_list_records_num_more_than_10(self, mock_get_virus_record):
mock_get_virus_record.side_effect = self._get_virus_record
self.login_as(self.admin)

View File

@ -0,0 +1,52 @@
from django.core.urlresolvers import reverse
from seahub.profile.models import Profile
from seahub.test_utils import BaseTestCase
class UserResetTest(BaseTestCase):
def setUp(self):
self.user_name = self.user.username
def test_can_search_user_from_ccnet(self):
self.login_as(self.admin)
q = self.user_name[:3]
resp = self.client.get(reverse('user_search') + '?email=%s' % q)
self.assertEqual(200, resp.status_code)
self.assertTemplateUsed('sysadmin/user_search.html')
self.assertContains(resp, self.user_name)
def test_can_search_user_from_profile_by_name(self):
self.login_as(self.admin)
nickname = 'nickname'
p = Profile.objects.add_or_update(self.user_name, nickname=nickname)
p.save()
resp = self.client.get(reverse('user_search') + '?email=%s' % nickname)
self.assertEqual(200, resp.status_code)
self.assertTemplateUsed('sysadmin/user_search.html')
self.assertContains(resp, self.user_name)
def test_can_search_user_from_profile_by_contact_email(self):
self.login_as(self.admin)
contact_email= 'contact@email.com'
p = Profile.objects.add_or_update(self.user_name, nickname='nickname')
p.contact_email = contact_email
p.save()
resp = self.client.get(reverse('user_search') +
'?email=%s' % contact_email)
self.assertEqual(200, resp.status_code)
self.assertTemplateUsed('sysadmin/user_search.html')
self.assertContains(resp, self.user_name)
def test_search_user_with_invalid_user_permission(self):
self.login_as(self.user)
resp = self.client.get(reverse('user_search') +
'?email=%s' % self.user_name)
self.assertEqual(404, resp.status_code)