From 862723e1d811ec52c9928ed4c462bd5ffc6e9a80 Mon Sep 17 00:00:00 2001 From: xiez Date: Fri, 27 Jul 2012 11:39:55 +0800 Subject: [PATCH] Modify org user add --- api/views.py | 2 +- group/views.py | 4 +- .../organizations/org_user_add_email.html | 17 +++ .../organizations/org_useradmin.html | 96 ++++++++++++++ organizations/urls.py | 5 +- organizations/views.py | 118 +++++++++++++++++- templates/org_useradmin.html | 81 ------------ templates/sys_useradmin.html | 50 ++++---- thirdpart/seaserv/__init__.py | 6 +- thirdpart/seaserv/service.py | 81 ++++++++---- urls.py | 2 +- utils.py | 8 ++ views.py | 59 ++++----- 13 files changed, 357 insertions(+), 172 deletions(-) create mode 100644 organizations/templates/organizations/org_user_add_email.html create mode 100644 organizations/templates/organizations/org_useradmin.html delete mode 100644 templates/org_useradmin.html diff --git a/api/views.py b/api/views.py index 1c331ba9a9..60fe66feb0 100644 --- a/api/views.py +++ b/api/views.py @@ -8,7 +8,7 @@ from django.http import HttpResponse, HttpResponseServerError from auth.decorators import login_required, api_login_required -from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_groups, get_repos, \ +from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, \ get_repo, get_commits, get_branches, \ seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, get_ccnetuser, \ get_group_repoids, check_group_staff diff --git a/group/views.py b/group/views.py index dea3e1421f..48071424da 100644 --- a/group/views.py +++ b/group/views.py @@ -7,7 +7,7 @@ from django.template import RequestContext from auth.decorators import login_required from seaserv import ccnet_rpc, ccnet_threaded_rpc, seafserv_threaded_rpc, get_repo, \ - get_group_repoids, check_group_staff, get_commits + get_group_repoids, check_group_staff, get_commits, get_personal_groups from pysearpc import SearpcError from models import GroupMessage, MessageReply @@ -41,7 +41,7 @@ def group_list(request): error_msg = e.msg return go_error(request, error_msg) - groups = ccnet_threaded_rpc.get_groups(request.user.username); + groups = get_personal_groups(request.user.username); return render_to_response("group/groups.html", { "groups": groups, diff --git a/organizations/templates/organizations/org_user_add_email.html b/organizations/templates/organizations/org_user_add_email.html new file mode 100644 index 0000000000..bcc0e9ef45 --- /dev/null +++ b/organizations/templates/organizations/org_user_add_email.html @@ -0,0 +1,17 @@ +{% autoescape off %} +亲爱的 {{ email }}: +{{ user }} 在 SeaCloud 云存储上将您加入到 {{ org_name }} 团队! + +以下是您的登录信息: +用户名: {{ email }} +密码: {{ password }} + +请点击以下链接登录: +{{ protocol }}://{{ domain }}{% url auth_login %} + +登录后请立即更改密码。 +感谢使用我们的网站! + +Seafile团队 + +{% endautoescape %} diff --git a/organizations/templates/organizations/org_useradmin.html b/organizations/templates/organizations/org_useradmin.html new file mode 100644 index 0000000000..f297a050ea --- /dev/null +++ b/organizations/templates/organizations/org_useradmin.html @@ -0,0 +1,96 @@ +{% extends "org_admin_base.html" %} + +{% block nav_useradmin_class %}class="cur"{% endblock %} +{% block left_panel %} +

操作

+ +{% endblock %} + + +{% block right_panel %} +{% if messages %} + +{% endif %} + +

所有用户

+ + + + + + + {% for user in users %} + + + + + {% endfor %} +
邮箱操作
{{ user.props.email }} + {% if not user.is_self %} + + {% endif %} +
+ +
+ {% if current_page != 1 %} + 上一页 + {% endif %} + {% if page_next %} + 下一页 + {% endif %} + 每页: + {% if per_page == 25 %} + 25 + {% else %} + 25 + {% endif %} + {% if per_page == 50 %} + 50 + {% else %} + 50 + {% endif %} + {% if per_page == 100 %} + 100 + {% else %} + 100 + {% endif %} +
+ +
+
+ +

可以是非网站注册用户,我们会以邮件通知对方。

+

输入不能为空。

+ +
+ +{% endblock %} + +{% block extra_script %} + +{% endblock %} diff --git a/organizations/urls.py b/organizations/urls.py index 14aa7bd47d..82646f0877 100644 --- a/organizations/urls.py +++ b/organizations/urls.py @@ -1,7 +1,7 @@ from django.conf.urls.defaults import * from views import * -from seahub.views import repo, repo_history, org_seafadmin, org_useradmin, \ +from seahub.views import repo, repo_history, org_seafadmin, \ org_group_admin urlpatterns = patterns('', @@ -12,9 +12,10 @@ urlpatterns = patterns('', url(r'^([^/]+)/repo/(?P[^/]+)/$', repo, name='repo'), url(r'^([^/]+)/repo/history/(?P[^/]+)/$', repo_history, name='org_repo_history'), - + ### Org admin ### url(r'^([^/]+)/seafadmin/$', org_seafadmin, name='org_seafadmin'), url(r'^([^/]+)/useradmin/$', org_useradmin, name='org_useradmin'), + url(r'^([^/]+)/useradmin/remove/(?P[^/]+)/$', org_user_remove, name='org_user_remove'), url(r'^([^/]+)/groupadmin/$', org_group_admin, name='org_groupadmin'), ) diff --git a/organizations/views.py b/organizations/views.py index 145dfed57d..62a6faf57b 100644 --- a/organizations/views.py +++ b/organizations/views.py @@ -1,20 +1,28 @@ # encoding: utf-8 import sys from django.core.urlresolvers import reverse +from django.contrib import messages +from django.core.mail import send_mail +from django.contrib.sites.models import Site, RequestSite from django.http import HttpResponse, HttpResponseRedirect, Http404 -from django.template import RequestContext from django.shortcuts import render_to_response +from django.template import Context, loader, RequestContext from auth.decorators import login_required from pysearpc import SearpcError from seaserv import ccnet_threaded_rpc, get_orgs_by_user, get_org_repos, \ - get_org_by_url_prefix, create_org, get_user_current_org + get_org_by_url_prefix, create_org, get_user_current_org, add_org_user, \ + get_ccnetuser, remove_org_user, get_org_groups from forms import OrgCreateForm from settings import ORG_CACHE_PREFIX from utils import set_org_ctx +from registration.models import RegistrationProfile +import seahub.settings as seahub_settings +from seahub.utils import go_error, go_permission_error, validate_group_name, \ + emails2list, gen_token from seahub.views import myhome -from seahub.utils import go_error, go_permission_error, validate_group_name + @login_required def create_org(request): @@ -95,9 +103,111 @@ def org_groups(request, url_prefix): error_msg = e.msg return go_error(request, error_msg) - groups = ccnet_threaded_rpc.get_org_groups(org.org_id, 0, sys.maxint) + groups = get_org_groups(org.org_id, 0, sys.maxint) return render_to_response('organizations/org_groups.html', { 'org': org, 'groups': groups, }, context_instance=RequestContext(request)) +def send_org_user_add_mail(request, email, password, org_name): + """ + Send email when add new user. + """ + use_https = request.is_secure() + domain = RequestSite(request).domain + + t = loader.get_template('organizations/org_user_add_email.html') + c = { + 'user': request.user.username, + 'org_name': org_name, + 'email': email, + 'password': password, + 'domain': domain, + 'protocol': use_https and 'https' or 'http', + } + + try: + send_mail(u'SeaCloud注册信息', t.render(Context(c)), + None, [email], fail_silently=False) + messages.add_message(request, messages.INFO, email) + except: + messages.add_message(request, messages.ERROR, email) + +@login_required +def org_useradmin(request, url_prefix): + """ + List and add org users. + """ + if not request.user.org['is_staff']: + raise Http404 + + if request.method == 'POST': + emails = request.POST.get('emails') + + email_list = emails2list(emails) + for email in email_list: + if not email or email.find('@') <= 0 : + continue + + org_id = request.user.org['org_id'] + if get_ccnetuser(username=email): + email = email.strip(' ') + org_id = request.user.org['org_id'] + add_org_user(org_id, email, 0) + else: + # User is not registered, just create account and + # add that account to org + password = gen_token(max_length=6) + if Site._meta.installed: + site = Site.objects.get_current() + else: + site = RequestSite(request) + RegistrationProfile.objects.create_active_user(\ + email, email, password, site, send_email=False) + add_org_user(org_id, email, 0) + if hasattr(seahub_settings, 'EMAIL_HOST'): + org_name = request.user.org['org_name'] + send_org_user_add_mail(request, email, password, org_name) + + # Make sure page request is an int. If not, deliver first page. + try: + current_page = int(request.GET.get('page', '1')) + per_page= int(request.GET.get('per_page', '25')) + except ValueError: + current_page = 1 + per_page = 25 + + url_prefix = request.user.org['url_prefix'] + users_plus_one = ccnet_threaded_rpc.get_org_emailusers(\ + url_prefix, per_page * (current_page - 1), per_page + 1) + if len(users_plus_one) == per_page + 1: + page_next = True + else: + page_next = False + + users = users_plus_one[:per_page] + for user in users: + if user.props.id == request.user.id: + user.is_self = True + + return render_to_response( + 'organizations/org_useradmin.html', { + 'users': users, + 'current_page': current_page, + 'prev_page': current_page-1, + 'next_page': current_page+1, + 'per_page': per_page, + 'page_next': page_next, + }, + context_instance=RequestContext(request)) + +@login_required +def org_user_remove(request, user): + """ + Remove org user + """ + org_id = request.user.org['org_id'] + url_prefix = request.user.org['url_prefix'] + remove_org_user(org_id, user) + + return HttpResponseRedirect(reverse('org_useradmin', args=[url_prefix])) diff --git a/templates/org_useradmin.html b/templates/org_useradmin.html deleted file mode 100644 index d78f7c6678..0000000000 --- a/templates/org_useradmin.html +++ /dev/null @@ -1,81 +0,0 @@ -{% extends "org_admin_base.html" %} - -{% block nav_useradmin_class %}class="cur"{% endblock %} -{% block left_panel %} -

操作

- -{% endblock %} - - -{% block right_panel %} -{% if messages %} -
    - {% for message in messages %} - {% if message.tags == 'info' %} -
  • 邮件发送成功。
  • - {% endif %} - {% if message.tags == 'error' %} -
  • 邮件发送失败。
  • - {% endif %} - {% endfor %} -
-{% endif %} - -

所有用户

- - - - - - - - {% for user in users %} - - - {% if user.props.is_active %} - - {% else %} - - {% endif %} - - - {% endfor %} -
邮箱是否激活操作
{{ user.props.email }}已激活 - {% if user.profile %} - - {% endif %} - {% if not user.is_self %} - - {% endif %} -
- -
-

的新角色 (即 MyClient 等):

-
- -
-{% endblock %} - -{% block extra_script %} - -{% endblock %} diff --git a/templates/sys_useradmin.html b/templates/sys_useradmin.html index 092cd0e119..bdbc6de54a 100644 --- a/templates/sys_useradmin.html +++ b/templates/sys_useradmin.html @@ -26,9 +26,8 @@

所有用户

- + - @@ -40,15 +39,7 @@ {% else %} {% endif %} - {% if user.is_org_user %} - - {% else %} - - {% endif %}
邮箱邮箱 是否激活是否企业帐号 操作
- {% if user.profile %} - - {% endif %} {% if not user.is_self %} {% endif %} @@ -57,11 +48,31 @@ {% endfor %}
-
-

的新角色 (即 MyClient 等):

-
- -
+
+ {% if current_page != 1 %} + 上一页 + {% endif %} + {% if page_next %} + 下一页 + {% endif %} + 每页: + {% if per_page == 25 %} + 25 + {% else %} + 25 + {% endif %} + {% if per_page == 50 %} + 50 + {% else %} + 50 + {% endif %} + {% if per_page == 100 %} + 100 + {% else %} + 100 + {% endif %} +
+ {% endblock %} {% block extra_script %} @@ -71,17 +82,8 @@ $('.activate').each(function(){ location.href = $(this).attr('data'); }); }); -$(".add-role-btn").each(function() { - $(this).click(function() { - var url = "{{ SITE_ROOT }}useradmin/" + $(this).attr("userid") + "/role/add/"; - $("#add-role-form").attr('action', url); - $("#user_email").html($(this).attr("email")); - $("#add-role-form").modal({appendTo: "#main"}); - }); -}); //delete confirm addConfirmTo($('.remove-user-btn')); -addConfirmTo($('.role-delete-btn')); {% endblock %} diff --git a/thirdpart/seaserv/__init__.py b/thirdpart/seaserv/__init__.py index 5979763fcf..2402608511 100644 --- a/thirdpart/seaserv/__init__.py +++ b/thirdpart/seaserv/__init__.py @@ -3,13 +3,13 @@ import service from service import ccnet_rpc, monitor_rpc, seafserv_rpc, \ seafserv_threaded_rpc, ccnet_threaded_rpc from service import send_command -from service import get_groups, get_group +from service import get_org_groups, get_personal_groups from service import get_repos, get_repo, get_commits, get_branches, get_org_repos from service import get_binding_peerids -from service import get_ccnetuser +from service import get_ccnetuser, get_emailusers from service import get_group_repoids, check_group_staff from service import create_org, get_orgs_by_user, get_org_by_url_prefix, \ - get_user_current_org + get_user_current_org, add_org_user, remove_org_user from service import CCNET_CONF_PATH diff --git a/thirdpart/seaserv/service.py b/thirdpart/seaserv/service.py index aaf6ead1da..441b554d35 100644 --- a/thirdpart/seaserv/service.py +++ b/thirdpart/seaserv/service.py @@ -84,30 +84,57 @@ def get_ccnetuser(username=None, userid=None): return ccnetuser -def get_groups(): - """Get group object list. """ - group_ids = ccnet_threaded_rpc.list_groups() - if not group_ids: - return [] - groups = [] - for group_id in group_ids.split("\n"): - # too handle the ending '\n' - if group_id == '': - continue - group = ccnet_threaded_rpc.get_group(group_id) - groups.append(group) +def get_emailusers(start, limit): + try: + users = ccnet_threaded_rpc.get_emailusers(start, limit) + except SearpcError: + users = [] + return users + +# def get_groups(): +# """Get group object list. """ +# group_ids = ccnet_threaded_rpc.list_groups() +# if not group_ids: +# return [] +# groups = [] +# for group_id in group_ids.split("\n"): +# # too handle the ending '\n' +# if group_id == '': +# continue +# group = ccnet_threaded_rpc.get_group(group_id) +# groups.append(group) +# return groups + + +# def get_group(group_id): +# group = ccnet_threaded_rpc.get_group(group_id) +# if not group: +# return None +# group.members = group.props.members.split(" ") +# group.followers = group.props.followers.split(" ") +# group.maintainers = group.props.maintainers.split(" ") +# return group + +def get_org_groups(org_id, start, limit): + try: + groups = ccnet_threaded_rpc.get_org_groups(org_id, 0, sys.maxint) + except SearpcError: + groups = [] return groups +def get_personal_groups(email): + try: + groups_all = ccnet_threaded_rpc.get_groups(email) + except SearpcError: + return [] -def get_group(group_id): - group = ccnet_threaded_rpc.get_group(group_id) - if not group: - return None - group.members = group.props.members.split(" ") - group.followers = group.props.followers.split(" ") - group.maintainers = group.props.maintainers.split(" ") - return group - + personal_groups = [] + for group in groups_all: + if not ccnet_threaded_rpc.is_org_group(group.id): + personal_groups.append(group) + + return personal_groups + def create_org(org_name, url_prefix, username): ccnet_threaded_rpc.create_org(org_name, url_prefix, username) @@ -133,6 +160,18 @@ def get_user_current_org(user, url_prefix): if org.url_prefix == url_prefix: return org return None + +def add_org_user(org_id, email, is_staff): + try: + ccnet_threaded_rpc.add_org_user(org_id, email, is_staff) + except SearpcError: + pass + +def remove_org_user(org_id, email): + try: + ccnet_threaded_rpc.remove_org_user(org_id, email) + except SearpcError: + pass def send_command(command): client = pool.get_client() diff --git a/urls.py b/urls.py index 9a39b4b2f0..4f93abd40a 100644 --- a/urls.py +++ b/urls.py @@ -4,7 +4,7 @@ from django.views.generic.simple import direct_to_template from seahub.views import root, myhome, \ repo, repo_history, modify_token, remove_repo, sys_seafadmin, sys_useradmin, \ - org_seafadmin, org_useradmin, org_group_admin, org_remove, \ + org_seafadmin, org_group_admin, org_remove, \ activate_user, user_add, user_remove, sys_group_admin, sys_org_admin, \ ownerhome, repo_history_revert, repo_file_get, \ user_info, repo_set_access_property, repo_access_file, \ diff --git a/utils.py b/utils.py index b1c65015ad..52d38235f1 100644 --- a/utils.py +++ b/utils.py @@ -284,3 +284,11 @@ def get_ccnet_server_addr_port(): return settings.CCNET_SERVER_ADDR, settings.CCNET_SERVER_PORT except: return None, None + +def emails2list(emails): + """ + Split email string contacted with diffent separator. + """ + email_str = emails.replace(';', ',').replace('\n', ',').replace('\r', ',') + return email_str.split(',') + diff --git a/views.py b/views.py index 17dff73035..14d8f38be5 100644 --- a/views.py +++ b/views.py @@ -27,10 +27,10 @@ from auth.forms import AuthenticationForm, PasswordResetForm, SetPasswordForm, \ PasswordChangeForm from auth.tokens import default_token_generator from share.models import FileShare -from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_groups, get_repos, \ +from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, get_emailusers, \ get_repo, get_commits, get_branches, \ seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, get_ccnetuser, \ - get_group_repoids, check_group_staff + get_group_repoids, check_group_staff, get_personal_groups from pysearpc import SearpcError from seahub.base.accounts import CcnetUser @@ -44,7 +44,7 @@ from utils import go_permission_error, go_error, list_to_string, \ calculate_repo_last_modify, valid_previewed_file, \ check_filename_with_rename, get_accessible_repos, EMPTY_SHA1, \ get_file_revision_id_size, get_ccnet_server_addr_port, \ - gen_file_get_url + gen_file_get_url, emails2list from seahub.profile.models import Profile from seahub.settings import FILE_PREVIEW_MAX_SIZE, CROCODOC_API_TOKEN @@ -705,7 +705,8 @@ def myhome(request): grpmsg_reply_list.append(n.detail) # my groups - groups = ccnet_threaded_rpc.get_groups(email) + groups = get_personal_groups(email) + groups_manage = [] groups_join = [] for group in groups: @@ -1234,36 +1235,32 @@ def sys_useradmin(request): if not request.user.is_staff: raise Http404 - users = ccnet_threaded_rpc.get_emailusers(-1,-1) - + # Make sure page request is an int. If not, deliver first page. + try: + current_page = int(request.GET.get('page', '1')) + per_page= int(request.GET.get('per_page', '25')) + except ValueError: + current_page = 1 + per_page = 25 + users_plus_one = get_emailusers(per_page * (current_page - 1), per_page + 1) + if len(users_plus_one) == per_page + 1: + page_next = True + else: + page_next = False + + users = users_plus_one[:per_page] for user in users: if user.props.id == request.user.id: user.is_self = True - # TODO: may add new is_org_user rpc - user.is_org_user = True if ccnet_threaded_rpc.get_org_by_user(user.email) else False return render_to_response( 'sys_useradmin.html', { 'users': users, - }, - context_instance=RequestContext(request)) - -@login_required -def org_useradmin(request, url_prefix): - if not request.user.org['is_staff']: - raise Http404 - - users = ccnet_threaded_rpc.get_org_emailusers(request.user.org['url_prefix'], - 0, sys.maxint) - - for user in users: - if user.props.id == request.user.id: - user.is_self = True - user.is_org_user = True - - return render_to_response( - 'org_useradmin.html', { - 'users': users, + 'current_page': current_page, + 'prev_page': current_page-1, + 'next_page': current_page+1, + 'per_page': per_page, + 'page_next': page_next, }, context_instance=RequestContext(request)) @@ -1960,18 +1957,14 @@ def send_shared_link(request): email = form.cleaned_data['email'] file_shared_link = form.cleaned_data['file_shared_link'] - # Handle the diffent separator - to_email_str = email.replace(';',',') - to_email_str = to_email_str.replace('\n',',') - to_email_str = to_email_str.replace('\r',',') - to_email_list = to_email_str.split(',') + to_email_list = emails2list(email) t = loader.get_template('shared_link_email.html') for to_email in to_email_list: - to_email = to_email.strip(' ') if not to_email: continue + to_email = to_email.strip(' ') c = { 'email': request.user.username,