1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-06-28 16:08:25 +00:00
seahub/organizations/views.py

601 lines
22 KiB
Python
Raw Normal View History

2012-07-26 09:08:31 +00:00
# encoding: utf-8
2012-09-03 04:03:06 +00:00
import os
2012-07-30 02:25:46 +00:00
import simplejson as json
2012-07-26 09:08:31 +00:00
import sys
from django.core.urlresolvers import reverse
2012-07-27 03:39:55 +00:00
from django.contrib import messages
from django.core.mail import send_mail
from django.contrib.sites.models import Site, RequestSite
2012-07-30 02:25:46 +00:00
from django.http import HttpResponse, HttpResponseBadRequest, Http404, \
HttpResponseRedirect
2012-07-26 09:08:31 +00:00
from django.shortcuts import render_to_response
2012-07-27 03:39:55 +00:00
from django.template import Context, loader, RequestContext
2012-07-26 09:08:31 +00:00
from auth.decorators import login_required
from pysearpc import SearpcError
2012-09-03 04:03:06 +00:00
from seaserv import ccnet_threaded_rpc, seafserv_threaded_rpc, get_repo, \
get_orgs_by_user, get_org_repos, list_org_inner_pub_repos, \
2012-07-27 03:39:55 +00:00
get_org_by_url_prefix, create_org, get_user_current_org, add_org_user, \
remove_org_user, get_org_groups, is_valid_filename, org_user_exists, \
create_org_repo, get_org_id_by_group, get_org_groups_by_user, \
2012-09-03 04:03:06 +00:00
get_org_users_by_url_prefix, list_org_shared_repos, is_personal_repo
2012-07-26 09:08:31 +00:00
2012-08-03 08:37:36 +00:00
from decorators import org_staff_required
2012-07-26 09:08:31 +00:00
from forms import OrgCreateForm
2012-07-27 09:54:07 +00:00
from signals import org_user_added
from utils import validate_org_repo_owner
2012-07-27 09:54:07 +00:00
from notifications.models import UserNotification
2012-09-03 04:03:06 +00:00
from share.models import FileShare
from share.forms import RepoShareForm
2012-07-27 03:39:55 +00:00
from registration.models import RegistrationProfile
from seahub.base.accounts import User
2012-08-03 09:04:15 +00:00
from seahub.contacts import Contact
2012-07-30 02:25:46 +00:00
from seahub.forms import RepoCreateForm
2012-07-27 03:39:55 +00:00
import seahub.settings as seahub_settings
from seahub.utils import render_error, render_permission_error, gen_token, \
2012-09-01 05:35:27 +00:00
validate_group_name, string2list, calculate_repo_last_modify, MAX_INT
2012-07-26 09:08:31 +00:00
from seahub.views import myhome
2012-07-27 03:39:55 +00:00
2012-07-26 09:08:31 +00:00
@login_required
def create_org(request):
"""
Create org account.
2012-07-26 09:08:31 +00:00
"""
if request.method == 'POST':
form = OrgCreateForm(request.POST)
if form.is_valid():
org_name = form.cleaned_data['org_name']
url_prefix = form.cleaned_data['url_prefix']
username = request.user.username
try:
# create_org(org_name, url_prefix, username)
ccnet_threaded_rpc.create_org(org_name, url_prefix, username)
return HttpResponseRedirect(\
reverse(org_info, args=[url_prefix]))
except SearpcError, e:
2012-08-31 11:37:22 +00:00
return render_error(request, e.msg, extra_ctx={
'base_template': 'myhome_base.html',
})
2012-07-26 09:08:31 +00:00
else:
form = OrgCreateForm()
return render_to_response('organizations/create_org.html', {
'form': form,
}, context_instance=RequestContext(request))
@login_required
def org_info(request, url_prefix):
"""
Show org info page, list org inner pub repos.
2012-07-26 09:08:31 +00:00
"""
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponseRedirect(reverse(myhome))
org_members = get_org_users_by_url_prefix(url_prefix, 0, MAX_INT)
repos = list_org_inner_pub_repos(org.org_id)
2012-07-26 09:08:31 +00:00
return render_to_response('organizations/org_info.html', {
'org': org,
'org_users': org_members,
'repos': repos,
}, context_instance=RequestContext(request))
@login_required
def org_personal(request, url_prefix):
"""
Show org personal page.
"""
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponseRedirect(reverse(myhome))
user = request.user.username
# Org repos that I own
owned_repos = seafserv_threaded_rpc.list_org_repos_by_owner(org.org_id,
user)
calculate_repo_last_modify(owned_repos)
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
2012-09-03 04:03:06 +00:00
# Org repos others shared to me
in_repos = list_org_shared_repos(user,'to_email', -1, -1)
# Org groups user created
groups = get_org_groups_by_user(org.org_id, user)
2012-09-03 04:03:06 +00:00
# Org members used in auto complete
contacts = []
org_members = get_org_users_by_url_prefix(org.url_prefix, 0, MAX_INT)
2012-09-03 04:03:06 +00:00
for m in org_members:
if m.email == user: # shouldn' show my'email in auto complete
continue
m.contact_email = m.email
contacts.append(m)
2012-08-30 13:15:41 +00:00
return render_to_response('organizations/personal.html', {
'owned_repos': owned_repos,
2012-09-03 04:03:06 +00:00
"in_repos": in_repos,
'org': org,
2012-08-30 13:15:41 +00:00
'groups': groups,
2012-09-03 04:03:06 +00:00
'contacts': contacts,
}, context_instance=RequestContext(request))
@login_required
def org_inner_pub_repo_create(request, url_prefix):
"""
Handle ajax post to create org inner pub repo, this repo is accessiable by
all org members.
"""
if not request.is_ajax() or request.method != 'POST':
return Http404
result = {}
content_type = 'application/json; charset=utf-8'
form = RepoCreateForm(request.POST)
if form.is_valid():
repo_name = form.cleaned_data['repo_name']
repo_desc = form.cleaned_data['repo_desc']
passwd = form.cleaned_data['passwd']
user = request.user.username
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponse(json.dumps(u'创建目录失败:未加入该团体'),
content_type=content_type)
try:
# create a org repo
repo_id = create_org_repo(repo_name, repo_desc, user, passwd,
org.org_id)
# set org inner pub
seafserv_threaded_rpc.set_org_inner_pub_repo(org.org_id, repo_id)
except:
repo_id = None
if not repo_id:
result['error'] = u"创建目录失败"
else:
result['success'] = True
return HttpResponse(json.dumps(result), content_type=content_type)
else:
return HttpResponseBadRequest(json.dumps(form.errors),
content_type=content_type)
2012-07-26 09:08:31 +00:00
@login_required
def org_groups(request, url_prefix):
"""
List org groups and add org group.
2012-07-26 09:08:31 +00:00
"""
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponseRedirect(reverse(myhome))
if request.method == 'POST':
group_name = request.POST.get('group_name')
if not validate_group_name(group_name):
return render_error(request, u'小组名称只能包含中英文字符,数字及下划线',
extra_ctx={
'org': org,
'base_template': 'org_base.html',
})
2012-07-26 09:08:31 +00:00
try:
group_id = ccnet_threaded_rpc.create_group(group_name.encode('utf-8'),
request.user.username)
ccnet_threaded_rpc.add_org_group(org.org_id, group_id)
except SearpcError, e:
error_msg = e.msg
return render_error(request, error_msg, extra_ctx={
'org': org,
'base_template': 'org_base.html',
})
2012-07-26 09:08:31 +00:00
2012-08-04 09:11:57 +00:00
groups = get_org_groups(org.org_id, 0, MAX_INT)
2012-07-26 09:08:31 +00:00
return render_to_response('organizations/org_groups.html', {
'org': org,
'groups': groups,
}, context_instance=RequestContext(request))
2012-07-27 03:39:55 +00:00
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
2012-08-03 08:37:36 +00:00
@org_staff_required
2012-07-27 03:39:55 +00:00
def org_useradmin(request, url_prefix):
"""
List and add org users.
"""
if request.method == 'POST':
2012-07-27 09:54:07 +00:00
emails = request.POST.get('added-member-name')
2012-07-27 03:39:55 +00:00
2012-08-10 13:16:55 +00:00
email_list = string2list(emails)
2012-07-27 03:39:55 +00:00
for email in email_list:
if not email or email.find('@') <= 0 :
continue
org_id = request.user.org['org_id']
try:
User.objects.get(email=email)
2012-07-27 03:39:55 +00:00
email = email.strip(' ')
org_id = request.user.org['org_id']
add_org_user(org_id, email, 0)
2012-07-27 09:54:07 +00:00
# send signal
org_user_added.send(sender=None, org_id=org_id,
from_email=request.user.username,
to_email=email)
except User.DoesNotExist:
2012-07-27 03:39:55 +00:00
# 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
users_plus_one = get_org_users_by_url_prefix(
2012-07-27 03:39:55 +00:00
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
2012-08-03 09:04:15 +00:00
# My contacts
contacts = Contact.objects.filter(user_email=request.user.username)
2012-07-27 03:39:55 +00:00
return render_to_response(
'organizations/org_useradmin.html', {
'users': users,
2012-08-03 09:04:15 +00:00
'contacts': contacts,
2012-07-27 03:39:55 +00:00
'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
2012-08-03 08:37:36 +00:00
@org_staff_required
def org_user_remove(request, url_prefix, user):
2012-07-27 03:39:55 +00:00
"""
2012-08-03 08:37:36 +00:00
Remove org user.
2012-07-27 03:39:55 +00:00
"""
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]))
2012-07-27 09:54:07 +00:00
def org_msg(request):
"""
2012-08-03 08:37:36 +00:00
Show organization user added messages.
2012-07-27 09:54:07 +00:00
"""
orgmsg_list = []
notes = UserNotification.objects.filter(to_user=request.user.username)
for n in notes:
if n.msg_type == 'org_msg':
orgmsg_list.append(n.detail)
# remove new org msg notification
UserNotification.objects.filter(to_user=request.user.username,
msg_type='org_msg').delete()
2012-07-27 09:54:07 +00:00
return render_to_response('organizations/new_msg.html', {
'orgmsg_list': orgmsg_list,
}, context_instance=RequestContext(request))
@login_required
2012-07-30 02:25:46 +00:00
def org_repo_create(request, url_prefix):
"""
Handle ajax post to create org repo, this repo is only accessiable by owner.
"""
2012-07-30 02:25:46 +00:00
if not request.is_ajax() or request.method != 'POST':
return Http404
result = {}
content_type = 'application/json; charset=utf-8'
2012-07-30 02:25:46 +00:00
form = RepoCreateForm(request.POST)
if form.is_valid():
repo_name = form.cleaned_data['repo_name']
repo_desc = form.cleaned_data['repo_desc']
encrypted = form.cleaned_data['encryption']
passwd = form.cleaned_data['passwd']
passwd_again = form.cleaned_data['passwd_again']
user = request.user.username
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponse(json.dumps(u'创建目录失败:未加入该团体'),
content_type=content_type)
2012-07-30 02:25:46 +00:00
repo_id = create_org_repo(repo_name, repo_desc, user, passwd,
org.org_id)
if not repo_id:
result['error'] = u"创建目录失败"
2012-07-30 02:25:46 +00:00
else:
result['success'] = True
return HttpResponse(json.dumps(result), content_type=content_type)
else:
return HttpResponseBadRequest(json.dumps(form.errors),
content_type=content_type)
@login_required
2012-08-03 08:37:36 +00:00
@org_staff_required
def org_seafadmin(request, url_prefix):
# 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
repos_all = get_org_repos(request.user.org['org_id'],
per_page * (current_page -1),
per_page + 1)
repos = repos_all[:per_page]
if len(repos_all) == per_page + 1:
page_next = True
else:
page_next = False
return render_to_response(
'organizations/org_seafadmin.html', {
'repos': repos,
'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))
2012-08-03 08:37:36 +00:00
@login_required
@org_staff_required
def org_group_admin(request, url_prefix):
# 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
groups_plus_one = get_org_groups (request.user.org['org_id'],
per_page * (current_page -1),
per_page +1)
groups = groups_plus_one[:per_page]
if len(groups_plus_one) == per_page + 1:
page_next = True
else:
page_next = False
return render_to_response('organizations/org_group_admin.html', {
'groups': groups,
'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))
2012-08-04 03:00:04 +00:00
@login_required
@org_staff_required
def org_group_remove(request, url_prefix, group_id):
# Request header may missing HTTP_REFERER, we need to handle that case.
next = request.META.get('HTTP_REFERER', None)
if not next:
next = seahub_settings.SITE_ROOT
try:
group_id_int = int(group_id)
except ValueError:
return HttpResponseRedirect(next)
# Check whether is the org group.
2012-08-04 03:47:00 +00:00
org_id = get_org_id_by_group(group_id_int)
2012-08-04 03:00:04 +00:00
if request.user.org['org_id'] != org_id:
2012-08-31 11:37:22 +00:00
return render_permission_error(request, '该小组不属于当前团体',
extra_ctx={'org': request.user.org,
'base_template': 'org_base.html'})
2012-08-04 03:00:04 +00:00
try:
ccnet_threaded_rpc.remove_group(group_id_int, request.user.username)
seafserv_threaded_rpc.remove_repo_group(group_id_int, None)
ccnet_threaded_rpc.remove_org_group(org_id, group_id_int)
except SearpcError, e:
2012-08-31 11:37:22 +00:00
return render_error(request, e.msg, extra_ctx={
'org': request.user.org,
'base_template': 'org_base.html',
})
2012-08-04 03:00:04 +00:00
return HttpResponseRedirect(next)
@login_required
def org_repo_share(request, url_prefix):
"""
Share org repo to members in current org.
"""
if request.method != 'POST':
raise Http404
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponseRedirect(reverse(myhome))
form = RepoShareForm(request.POST)
if not form.is_valid():
# TODO: may display error msg on form
raise Http404
email_or_group = form.cleaned_data['email_or_group']
repo_id = form.cleaned_data['repo_id']
from_email = request.user.username
# Test whether user is the repo owner
if not validate_org_repo_owner(org.org_id, repo_id, request.user.username):
return render_permission_error(request, u'只有目录拥有者有权共享目录',
extra_ctx={
'org': org,
'base_template': 'org_base.html',
})
2012-09-03 04:03:06 +00:00
share_to_list = string2list(email_or_group)
for share_to in share_to_list:
# if share_to is user name, the format is: 'example@mail.com';
# if share_to is group, the format is 'group_name <creator@mail.com>'
if (share_to.split(' ')[0].find('@') == -1):
''' Share repo to group '''
# TODO: if we know group id, then we can simplly call group_share_repo
if len(share_to.split(' ')) < 2:
msg = u'共享给 %s 失败。' % share_to
messages.add_message(request, messages.ERROR, msg)
continue
group_name = share_to.split(' ')[0]
group_creator = share_to.split(' ')[1]
# get org groups the user joined
groups = get_org_groups_by_user(org.org_id, from_email)
find = False
for group in groups:
# for every group that user joined, if group name and
# group creator matchs, then has finded the group
if group.props.group_name == group_name and \
group_creator.find(group.props.creator_name) >= 0:
seafserv_threaded_rpc.add_org_group_repo(repo_id,
org.org_id,
group.id,
from_email,
'rw')
find = True
msg = u'共享到 %s 成功,请前往<a href="%s">共享管理</a>查看。' % \
(group_name, reverse('org_shareadmin', args=[org.url_prefix]))
messages.add_message(request, messages.INFO, msg)
break
if not find:
msg = u'共享到 %s 失败。' % group_name
messages.add_message(request, messages.ERROR, msg)
else:
''' Share repo to user '''
2012-09-03 04:03:06 +00:00
# Test whether share_to is in this org
if not org_user_exists(org.org_id, share_to):
msg = u'共享给 %s 失败:团体中不存在该用户。' % share_to
messages.add_message(request, messages.ERROR, msg)
continue
# Record share info to db.
try:
2012-09-03 04:03:06 +00:00
seafserv_threaded_rpc.add_share(repo_id, from_email, share_to,
'rw')
msg = u'共享给 %s 成功,请前往<a href="%s">共享管理</a>查看。' % \
2012-09-03 04:03:06 +00:00
(share_to, reverse('org_shareadmin', args=[org.url_prefix]))
messages.add_message(request, messages.INFO, msg)
except SearpcError, e:
2012-09-03 04:03:06 +00:00
msg = u'共享给 %s 失败。' % share_to
messages.add_message(request, messages.ERROR, msg)
continue
return HttpResponseRedirect(reverse(org_personal, args=[org.url_prefix]))
2012-09-03 04:03:06 +00:00
@login_required
def org_shareadmin(request, url_prefix):
"""
List personal repos I share to others, include groups and users.
"""
username = request.user.username
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponseRedirect(reverse(myhome))
# Org repos that are shared to others.
2012-09-03 04:03:06 +00:00
out_repos = list_org_shared_repos(username, 'from_email', -1, -1)
# Org repos that are shared to groups.
group_repos = seafserv_threaded_rpc.get_org_group_repos_by_owner(org.org_id,
username)
for group_repo in group_repos:
repo_id = group_repo.props.repo_id
if not repo_id:
continue
repo = get_repo(repo_id)
if not repo:
continue
group_id = group_repo.props.group_id
group = ccnet_threaded_rpc.get_group(int(group_id))
if not group:
continue
repo.props.shared_email = group.props.group_name
repo.gid = group_id
out_repos.append(repo)
2012-09-03 04:03:06 +00:00
# File shared links
fileshares = FileShare.objects.filter(username=request.user.username)
o_fileshares = [] # shared files in org repos
for fs in fileshares:
if not is_personal_repo(fs.repo_id):
# only list files in org repos
fs.filename = os.path.basename(fs.path)
fs.repo = get_repo(fs.repo_id)
o_fileshares.append(fs)
return render_to_response('organizations/share_admin.html', {
"org": org,
"out_repos": out_repos,
"fileshares": o_fileshares,
"protocol": request.is_secure() and 'https' or 'http',
"domain": RequestSite(request).domain,
}, context_instance=RequestContext(request))