1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-16 07:08:55 +00:00

Add context switch decorator

This commit is contained in:
xiez
2012-08-31 17:28:50 +08:00
parent 0e3482e228
commit 5ad09999c7
14 changed files with 90 additions and 91 deletions

View File

@@ -14,10 +14,20 @@ def base(request):
Add seahub base configure to the context.
"""
try:
org = request.user.org
except AttributeError:
org = None
try:
base_template = request.base_template
except AttributeError:
base_template = None
return {
'seafile_version': SEAFILE_VERSION,
'seahub_title': SEAHUB_TITLE,
'cloud_mode': request.cloud_mode,
'org': org,
'base_template': base_template,
# 'account_type': settings.ACCOUNT_TYPE,
}

View File

@@ -1,5 +1,7 @@
from django.http import Http404
from seahub.utils import check_and_get_org_by_repo, check_and_get_org_by_group
def sys_staff_required(func):
"""
Decorator for views that checks the user is system staff.
@@ -10,3 +12,26 @@ def sys_staff_required(func):
raise Http404
return _decorated
def ctx_switch_required(func):
"""
Decorator for views to change navigation bar automatically that render
same template when both in org context and personal context.
"""
def _decorated(request, *args, **kwargs):
repo_id = kwargs.get('repo_id', '')
group_id = kwargs.get('group_id', '')
if repo_id and group_id:
return func(request, *args, **kwargs)
user = request.user.username
if repo_id:
org, base_template = check_and_get_org_by_repo(repo_id, user)
if group_id:
org, base_template = check_and_get_org_by_group(int(group_id), user)
request.user.org = org
request.base_template = base_template
return func(request, *args, **kwargs)
return _decorated

View File

@@ -19,6 +19,7 @@ from pysearpc import SearpcError
from models import GroupMessage, MessageReply, MessageAttachment
from forms import MessageForm, MessageReplyForm, GroupRecommendForm
from signals import grpmsg_added, grpmsg_reply_added
from base.decorators import ctx_switch_required
from seahub.contacts.models import Contact
from seahub.contacts.signals import mail_sended
from seahub.notifications.models import UserNotification
@@ -139,9 +140,6 @@ def render_group_info(request, group_id, form):
except ValueError:
return HttpResponseRedirect(reverse('group_list', args=[]))
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_group(group_id_int)
# Check whether user belong to the group or admin
joined = False
groups = ccnet_threaded_rpc.get_groups(request.user.username)
@@ -176,6 +174,7 @@ def render_group_info(request, group_id, form):
else:
common_members.append(member)
org = request.user.org
if org:
repos = get_org_group_repos(org.org_id, group_id_int,
request.user.username)
@@ -252,8 +251,6 @@ def render_group_info(request, group_id, form):
'per_page': per_page,
'page_next': page_next,
'url': reverse('create_group_repo', args=[group_id]),
'org': org,
'base_template': base_template,
}, context_instance=RequestContext(request));
@login_required
@@ -354,6 +351,7 @@ def msg_reply_new(request):
}, context_instance=RequestContext(request))
@login_required
@ctx_switch_required
def group_info(request, group_id):
if request.method == 'POST':
form = MessageForm(request.POST)
@@ -386,6 +384,7 @@ def group_info(request, group_id):
return render_group_info(request, group_id, form)
@login_required
@ctx_switch_required
def group_members(request, group_id):
try:
group_id_int = int(group_id)
@@ -443,15 +442,10 @@ def group_members(request, group_id):
members = ccnet_threaded_rpc.get_group_members(group_id_int)
contacts = Contact.objects.filter(user_email=request.user.username)
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_group(group_id_int)
return render_to_response('group/group_manage.html', {
'group' : group,
'members': members,
'contacts': contacts,
'org': org,
'base_template': base_template,
}, context_instance=RequestContext(request))
@login_required

View File

@@ -13,6 +13,7 @@ def org_staff_required(func):
url_prefix = kwargs.get('url_prefix', '')
org = get_user_current_org(user, url_prefix)
if org and org.is_staff:
request.user.org = org._dict
return func(request, *args, **kwargs)
return HttpResponseRedirect(reverse('myhome'))
return _decorated

View File

@@ -1,4 +1,4 @@
{% extends base_template %}
{% extends 'myhome_base.html' %}
{% load seahub_tags avatar_tags %}
{% block main_panel %}

View File

@@ -15,7 +15,7 @@
</tr>
{% for group in groups %}
<tr>
<td><a href="{{ SITE_ROOT }}group/{{ group.props.id }}/">{{ group.props.group_name }}</a></td>
<td><a href="{{ SITE_ROOT }}group/{{ group.props.id }}/" target="_blank">{{ group.props.group_name }}</a></td>
<td>{{ group.props.creator_name }}</td>
<td>{{ group.props.timestamp|tsstr_sec }}</td>
<td><button data="{{ SITE_ROOT}}organizations/{{ org.url_prefix }}/group/remove/{{ group.id }}/" class="group-remove-btn">删除</button></td>

View File

@@ -1,4 +1,4 @@
{% extends base_template %}
{% extends "org_admin_base.html" %}
{% block nav_seafadmin_class %}class="cur"{% endblock %}
{% block right_panel %}
@@ -12,7 +12,7 @@
</tr>
{% for repo in repos %}
<tr>
<td><a href="{{ SITE_ROOT }}repo/{{ repo.props.id }}/">{{ repo.props.name }}</a></td>
<td><a href="{{ SITE_ROOT }}repo/{{ repo.props.id }}/" target="_blank">{{ repo.props.name }}</a></td>
<td>{{ repo.props.desc }}</td>
<td><button data="{{ SITE_ROOT }}repo/remove/{{ repo.props.id }}/?next={{ request.path }}" class="repo-delete-btn">删除</button></td>
</tr>

View File

@@ -1,4 +1,5 @@
{% extends "org_admin_base.html" %}
{% load url from future %}
{% block nav_useradmin_class %}class="cur"{% endblock %}
{% block left_panel %}
@@ -32,10 +33,10 @@
{% for user in users %}
<tr>
<td><a href="{% url user_profile user.email %}">{{ user.props.email }}</a></td>
<td><a href="{% url 'user_profile' user.email %}">{{ user.props.email }}</a></td>
<td>
{% if not user.is_self %}
<button class="remove-user-btn" data="{% url org_user_remove request.user.org.url_prefix user.email %}">删除</button>
<button class="remove-user-btn" data="{% url 'org_user_remove' request.user.org.url_prefix user.email %}">删除</button>
{% endif %}
</td>
</tr>

View File

@@ -214,14 +214,6 @@ def org_useradmin(request, url_prefix):
"""
List and add org users.
"""
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponseRedirect(reverse(myhome))
# ctx_dict = {'base_template': 'org_admin_base.html',
# 'org_dict': request.user.org}
# set_cur_ctx(request, ctx_dict)
if request.method == 'POST':
emails = request.POST.get('added-member-name')
@@ -264,7 +256,6 @@ def org_useradmin(request, url_prefix):
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:

View File

@@ -9,6 +9,7 @@
<link rel="icon" type="image/png" href="{{ MEDIA_URL }}img/favicon.jpg" />
{% block extra_style %}{% endblock %}
{% load seahub_tags avatar_tags %}
{% load url from future %}
</head>
<body>
@@ -32,11 +33,11 @@
{% if org %} {{ org.org_name }} {% else %} 个人帐号 {% endif %}
<span class="bg"></span></a>
<ul class="hide" id="account-context-selector">
<li><a href="{% url myhome %}">个人帐号</a></li>
<li><a href="{% url 'myhome' %}">个人帐号</a></li>
{% for org in request.user.orgs %}
<li><a href="{% url org_info org.url_prefix %}">{{ org.org_name }}</a></li>
<li><a href="{% url 'org_info' org.url_prefix %}">{{ org.org_name }}</a></li>
{% endfor %}
<li><a href="{% url create_org %}">新建团体</a></li>
<li><a href="{% url 'create_org' %}">新建团体</a></li>
</ul>
{% endif %}
{% endif %}
@@ -46,15 +47,15 @@
<a href="{{ SITE_ROOT }}home/my/"{% block top_bar_myaccount_class %}{% endblock %}>个人工作台</a>
{% endif %}
{% if request.user.org.is_staff %}
<a href="{% url org_useradmin request.user.org.url_prefix %}"{% block top_bar_org_manager_class %}{% endblock %}>管理员工作台</a>
<a href="{% url organizations.views.org_info request.user.org.url_prefix %}"{% block top_bar_org_myaccount_class %}{% endblock %}>个人工作台</a>
{% if org.is_staff %}
<a href="{% url 'org_useradmin' org.url_prefix %}"{% block top_bar_org_manager_class %}{% endblock %}>管理员工作台</a>
<a href="{% url 'organizations.views.org_info' org.url_prefix %}"{% block top_bar_org_myaccount_class %}{% endblock %}>个人工作台</a>
{% endif %}
</div>
<div class="account fright">
{% if request.user.is_authenticated %}
<span>欢迎,</span> <a href="{% url avatar_add %}" class="avatar-link">{% avatar request.user 16 %}</a> <span>{{ request.user }}</span>
<span>欢迎,</span> <a href="{% url 'avatar_add' %}" class="avatar-link">{% avatar request.user 16 %}</a> <span>{{ request.user }}</span>
<a href="{{ SITE_ROOT }}profile/">设置</a>
<a href="{{ SITE_ROOT }}accounts/logout/">退出</a>
{% else %}

View File

@@ -14,7 +14,7 @@ from service import get_repos, get_repo, get_commits, get_branches, \
from service import get_binding_peerids, is_valid_filename, check_permission
from service import create_org, get_orgs_by_user, get_org_by_url_prefix, \
get_user_current_org, add_org_user, remove_org_user, get_org_by_id, \
get_org_id_by_repo_id
get_org_id_by_repo_id, is_org_staff
from service import CCNET_CONF_PATH, CCNET_SERVER_ADDR, CCNET_SERVER_PORT

View File

@@ -224,6 +224,16 @@ def remove_org_user(org_id, email):
except SearpcError:
pass
def is_org_staff(org_id, user):
"""
Check whether user is staff of a org.
"""
try:
ret = ccnet_threaded_rpc.is_org_staff(org_id, user)
except SearpcError:
ret = -1
return True if ret == 1 else False
def send_command(command):
client = pool.get_client()
client.send_cmd(command)

View File

@@ -10,12 +10,13 @@ from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.hashcompat import sha_constructor
from django.core.files.uploadhandler import FileUploadHandler, StopFutureHandlers, StopUpload
from django.core.files.uploadhandler import FileUploadHandler, StopUpload, \
StopFutureHandlers
from django.core.cache import cache
from seaserv import seafserv_rpc, ccnet_threaded_rpc, seafserv_threaded_rpc, \
get_repo, get_commits, get_group_repoids, CCNET_SERVER_ADDR, \
CCNET_SERVER_PORT, get_org_id_by_repo_id, get_org_by_id, \
CCNET_SERVER_PORT, get_org_id_by_repo_id, get_org_by_id, is_org_staff, \
get_org_id_by_group
try:
from settings import CROCODOC_API_TOKEN
@@ -344,7 +345,7 @@ def string2list(string):
# request.session['current_context'] = ctx_dict
# request.user.org = ctx_dict.get('org_dict', None)
def check_and_get_org_by_repo(repo_id):
def check_and_get_org_by_repo(repo_id, user):
"""
Check whether repo is org repo, get org info if it is, and set
base template.
@@ -353,6 +354,8 @@ def check_and_get_org_by_repo(repo_id):
if org_id > 0:
# this repo is org repo, get org info
org = get_org_by_id(org_id)
org.is_staff = is_org_staff(org_id, user)
org.email = user
base_template = 'org_base.html'
else:
org = None
@@ -360,7 +363,7 @@ def check_and_get_org_by_repo(repo_id):
return org, base_template
def check_and_get_org_by_group(group_id):
def check_and_get_org_by_group(group_id, user):
"""
Check whether repo is org repo, get org info if it is, and set
base template.
@@ -369,6 +372,8 @@ def check_and_get_org_by_group(group_id):
if org_id > 0:
# this repo is org repo, get org info
org = get_org_by_id(org_id)
org.is_staff = is_org_staff(org_id, user)
org.email = user
base_template = 'org_base.html'
else:
org = None

View File

@@ -36,7 +36,7 @@ from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, get_emailusers, \
from pysearpc import SearpcError
from base.accounts import User
from base.decorators import sys_staff_required
from base.decorators import sys_staff_required, ctx_switch_required
from seahub.base.models import UuidObjidMap, FileComment
from seahub.contacts.models import Contact
from seahub.contacts.signals import mail_sended
@@ -133,9 +133,6 @@ def render_repo(request, repo_id, error=''):
if not repo:
return render_error(request, u'该同步目录不存在')
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
# query whether set password if repo is encrypted
password_set = False
if repo.props.encrypted:
@@ -224,17 +221,13 @@ def render_repo(request, repo_id, error=''):
"accessible_repos": accessible_repos,
"applet_root": get_ccnetapplet_root(),
"groups": groups,
"org": org,
"base_template": base_template,
}, context_instance=RequestContext(request))
@login_required
@ctx_switch_required
def repo_upload_file(request, repo_id):
repo = get_repo(repo_id)
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
if request.method == 'GET':
parent_dir = request.GET.get('p', '/')
zipped = gen_path_link (parent_dir, repo.name)
@@ -263,17 +256,13 @@ def repo_upload_file(request, repo_id):
"zipped": zipped,
"max_upload_file_size": settings.MAX_UPLOAD_FILE_SIZE,
"no_quota": no_quota,
"base_template": base_template,
"org": org,
}, context_instance=RequestContext(request))
@login_required
@ctx_switch_required
def repo_update_file(request, repo_id):
repo = get_repo(repo_id)
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
if request.method == 'GET':
target_file = request.GET.get('p')
if not target_file:
@@ -304,8 +293,6 @@ def repo_update_file(request, repo_id):
"zipped": zipped,
"max_upload_file_size": settings.MAX_UPLOAD_FILE_SIZE,
"no_quota": no_quota,
"org": org,
"base_template": base_template,
}, context_instance=RequestContext(request))
def upload_error_msg (code):
@@ -324,10 +311,8 @@ def upload_error_msg (code):
err_msg = u'文件传输出错'
return err_msg
@ctx_switch_required
def upload_file_error(request, repo_id):
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
if request.method == 'GET':
repo = get_repo(repo_id)
parent_dir = request.GET.get('p')
@@ -346,14 +331,10 @@ def upload_file_error(request, repo_id):
'zipped': zipped,
'filename': filename,
'err_msg': err_msg,
'org': org,
'base_template': base_template,
}, context_instance=RequestContext(request))
@ctx_switch_required
def update_file_error(request, repo_id):
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
if request.method == 'GET':
repo = get_repo(repo_id)
target_file = request.GET.get('p')
@@ -370,8 +351,6 @@ def update_file_error(request, repo_id):
'repo': repo,
'zipped': zipped,
'err_msg': err_msg,
'org': org,
'base_template': base_template,
}, context_instance=RequestContext(request))
def get_subdir(request):
@@ -418,6 +397,7 @@ def get_subdir(request):
return HttpResponse(json.dumps(subdirs),
content_type=content_type)
@ctx_switch_required
def repo(request, repo_id):
if request.method == 'GET':
return render_repo(request, repo_id)
@@ -443,6 +423,7 @@ def repo(request, repo_id):
return render_repo(request, repo_id)
@login_required
@ctx_switch_required
def repo_history(request, repo_id):
"""
View repo history.
@@ -452,9 +433,6 @@ def repo_history(request, repo_id):
repo = get_repo(repo_id)
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
password_set = False
if repo.props.encrypted:
try:
@@ -497,8 +475,6 @@ def repo_history(request, repo_id):
'per_page': per_page,
'page_next': page_next,
'is_owner': is_owner,
'org': org,
'base_template': base_template,
}, context_instance=RequestContext(request))
@login_required
@@ -617,9 +593,6 @@ def remove_repo(request, repo_id):
# FIXME: no org in request.user, check whether repo is org repo, and then
# check permission
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
if not validate_owner(request, repo_id) and not request.user.is_staff \
and not request.user.org['is_staff']:
err_msg = u'删除同步目录失败, 只有管理员或目录创建者有权删除目录。'
@@ -786,13 +759,11 @@ def repo_del_file(request, repo_id):
url = reverse('repo', args=[repo_id]) + ('?p=%s' % parent_dir)
return HttpResponseRedirect(url)
@ctx_switch_required
def repo_view_file(request, repo_id):
"""
Preview file on web, including files in current worktree and history.
"""
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
if request.method == 'POST':
# handle post request to leave comment on file
path = request.GET.get('p', '/')
@@ -951,8 +922,6 @@ def repo_view_file(request, repo_id):
'next_page': current_page+1,
'per_page': per_page,
'page_next': page_next,
'org': org,
'base_template': base_template,
}, context_instance=RequestContext(request))
def repo_file_get(raw_path):
@@ -1064,13 +1033,11 @@ def update_file_after_edit(request, repo_id):
@login_required
@ctx_switch_required
def repo_file_edit(request, repo_id):
if request.method == 'POST':
return update_file_after_edit(request, repo_id)
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
path = request.GET.get('p', '/')
if path[-1] == '/':
path = path[:-1]
@@ -1115,8 +1082,6 @@ def repo_file_edit(request, repo_id):
'file_content':file_content,
'encoding': encoding,
'newline_mode': newline_mode,
'org': org,
'base_template': base_template,
}, context_instance=RequestContext(request))
@@ -1792,9 +1757,6 @@ def render_file_revisions (request, repo_id):
zipped = gen_path_link(path, repo.name)
# change navigator when user in diffent context
org, base_template = check_and_get_org_by_repo(repo_id)
return render_to_response('file_revisions.html', {
'repo': repo,
'path': path,
@@ -1802,8 +1764,6 @@ def render_file_revisions (request, repo_id):
'zipped': zipped,
'commits': commits,
'is_owner': is_owner,
'org': org,
'base_template': base_template,
}, context_instance=RequestContext(request))
@login_required
@@ -1831,6 +1791,7 @@ def repo_revert_file (request, repo_id):
return HttpResponseRedirect(url)
@login_required
@ctx_switch_required
def file_revisions(request, repo_id):
if request.method != 'GET':
return render_error(request)