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

enable sysadmin view user's repo

This commit is contained in:
lian
2015-10-20 16:35:54 +08:00
parent df1ff9e0f6
commit c41ff45ea2
7 changed files with 236 additions and 10 deletions

View File

@@ -222,6 +222,9 @@ LOGIN_REDIRECT_URL = '/profile/'
ACCOUNT_ACTIVATION_DAYS = 7 ACCOUNT_ACTIVATION_DAYS = 7
# allow seafile amdin view user's repo
ENABLE_SYS_ADMIN_VIEW_REPO = False
# show traffic on the UI # show traffic on the UI
SHOW_TRAFFIC = True SHOW_TRAFFIC = True

View File

@@ -0,0 +1,94 @@
{% extends "myhome_base.html" %}
{% load seahub_tags avatar_tags i18n upload_tags %}
{% block sub_title %}{{repo.name}} - {% endblock %}
{% block extra_style %}
<style type="text/css">
#footer { display:none; }
</style>
{% endblock %}
{% block main_panel %}
<div id="repo-top">
<h2 class="hd">{{repo.props.name}}</h2>
</div>
<div id="repo-file-list">
<div class="repo-file-list-topbar">
<p class="path fleft">
{% for name, link in zipped %}
{% if forloop.first or not forloop.last %}
<a href="{% url 'sys_admin_repo' repo.id %}?p={{link|urlencode}}" class="dir-link normal">{{ name }}</a> /
{% else %}
<span id="cur-dir-name">{{ name }}</span> /
{% endif %}
{% endfor %}
</p>
<div id="repo-latest-commit" class="clear">
</div>
</div>
<table class="repo-file-list">
<tr>
<th class="dirent-icon"></th>
<th><span class="dirent-name">{% trans "Name"%}</span></th>
<th class="dirent-size">{% trans "Size"%}</th>
<th class="dirent-update">{% trans "Last Update" %}</th>
<th class="dirent-op">{% trans "Operations"%}</th>
</tr>
{% for dirent in dir_list %}
<tr class="dir-item">
<td class="dirent-icon"><img src="{{ MEDIA_URL }}img/folder-24.png" alt="{% trans "Directory icon"%}" /></td>
<td>
<span class="dirent-name"><a href="?p={{path|urlencode}}{{ dirent.obj_name|urlencode }}" class="dir-link">{{ dirent.obj_name }}</a></span>
</td>
<td class="dirent-size"></td>
<td class="dirent-update">
{{ dirent.last_modified|translate_seahub_time }}
</td>
<td class="dirent-op">
</td>
</tr>
{% endfor %}
{% for dirent in file_list %}
<tr class="file-item">
<td class="dirent-icon">
<img src="{{ MEDIA_URL }}img/file/{{ dirent.obj_name|file_icon_filter }}" alt="{% trans "File"%}" />
</td>
<td>
<span class="dirent-name">{{ dirent.obj_name }}</span>
</td>
<td class="dirent-size">{{ dirent.file_size|filesizeformat }}</td>
<td class="dirent-update">
{{ dirent.last_modified|translate_seahub_time }}
</td>
<td class="dirent-op">
<div class="repo-file-op vh">
<div class="displayed-op">
<a class="op file-download" href="{% url 'sys_admin_repo_download_file' repo.id %}?p={{path|urlencode}}{{ dirent.obj_name|urlencode }}" title="{% trans "Download"%}">
<img src="{{MEDIA_URL}}img/download.png" alt="" />
</a>
</div>
</div>
</td>
</tr>
{% endfor %}
</table>
</div>
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
$('.dir-item, .file-item').unbind().hover( // remove previously binded hover handler at first
function() {
$(this).addClass('hl').find('.repo-file-op').removeClass('vh');
},
function() {
$(this).removeClass('hl').find('.repo-file-op').addClass('vh');
}
);
</script>
{% endblock %}

View File

@@ -11,10 +11,17 @@
<tr> <tr>
{% if repo.encrypted %} {% if repo.encrypted %}
<td><img src="{{MEDIA_URL}}img/sync-folder-encrypt-20.png" title="{% trans "Encrypted"%}" alt="{% trans "directory icon" %}" /></td> <td><img src="{{MEDIA_URL}}img/sync-folder-encrypt-20.png" title="{% trans "Encrypted"%}" alt="{% trans "directory icon" %}" /></td>
<td>{{ repo.props.name }}</td>
{% else %} {% else %}
<td><img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write"%}" alt="{% trans "directory icon" %}" /></td> <td><img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write"%}" alt="{% trans "directory icon" %}" /></td>
{% endif %} {% if repo.is_default_repo %}
<td><a href="{% url 'repo' repo.id %}">{{ repo.props.name }}</a></td>
{% elif enable_sys_admin_view_repo %}
<td><a href="{% url 'sys_admin_repo' repo.id %}">{{ repo.props.name }}</a></td>
{% else %}
<td>{{ repo.props.name }}</td> <td>{{ repo.props.name }}</td>
{% endif %}
{% endif %}
<td style="font-size:11px;">{{ repo.id }}</td> <td style="font-size:11px;">{{ repo.id }}</td>
<td> <td>
{% if repo.owner %} {% if repo.owner %}

View File

@@ -52,7 +52,13 @@
{% else %} {% else %}
<td><img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write" %}" alt="{% trans "library icon" %}" /></td> <td><img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write" %}" alt="{% trans "library icon" %}" /></td>
{% endif %} {% endif %}
<td><a href="{% url 'view_common_lib_dir' repo.id '' %}">{{ repo.name }}</a></td> {% if repo.encrypted %}
<td>{{ repo.name }}</td>
{% elif enable_sys_admin_view_repo %}
<td><a href="{% url 'sys_admin_repo' repo.id %}">{{ repo.name }}</a></td>
{% else %}
<td>{{ repo.name }}</td>
{% endif %}
<td>{{ repo.size|filesizeformat }}</td> <td>{{ repo.size|filesizeformat }}</td>
<td><a href="{% url 'user_info' repo.user %}">{{ repo.user }}</a></td> <td><a href="{% url 'user_info' repo.user %}">{{ repo.user }}</a></td>
<td data-id="{{ repo.id }}" data-name="{{repo.name}}"> <td data-id="{{ repo.id }}" data-name="{{repo.name}}">

View File

@@ -89,7 +89,13 @@
{% else %} {% else %}
<td><img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write" %}" alt="{% trans "library icon" %}" /></td> <td><img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write" %}" alt="{% trans "library icon" %}" /></td>
{% endif %} {% endif %}
<td><a href="{% url 'view_common_lib_dir' repo.id '' %}">{{ repo.props.name }}</a></td> {% if repo.encrypted %}
<td>{{ repo.name }}</td>
{% elif enable_sys_admin_view_repo %}
<td><a href="{% url 'sys_admin_repo' repo.id %}">{{ repo.name }}</a></td>
{% else %}
<td>{{ repo.name }}</td>
{% endif %}
<td>{{ repo.size|filesizeformat }}</td> <td>{{ repo.size|filesizeformat }}</td>
<td>{{ repo.last_modify|translate_seahub_time }}</td> <td>{{ repo.last_modify|translate_seahub_time }}</td>
<td data-id="{{ repo.props.id }}" data-name="{{repo.name}}"> <td data-id="{{ repo.props.id }}" data-name="{{repo.name}}">
@@ -123,7 +129,11 @@
{% else %} {% else %}
<td><img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write" %}" alt="{% trans "library icon" %}" /></td> <td><img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write" %}" alt="{% trans "library icon" %}" /></td>
{% endif %} {% endif %}
<td><a href="{% url 'view_common_lib_dir' repo.id '' %}">{{ repo.props.repo_name }}</a></td> {% if enable_sys_admin_view_repo %}
<td><a href="{% url 'sys_admin_repo' repo.id %}">{{ repo.name }}</a></td>
{% else %}
<td>{{ repo.name }}</td>
{% endif %}
<td>{{ repo.props.user }}</td> <td>{{ repo.props.user }}</td>
<td>{{ repo.size|filesizeformat }}</td> <td>{{ repo.size|filesizeformat }}</td>
<td>{{ repo.last_modify|translate_seahub_time }}</td> <td>{{ repo.last_modify|translate_seahub_time }}</td>

View File

@@ -207,6 +207,8 @@ urlpatterns = patterns(
url(r'^sys/info/$', sys_info, name='sys_info'), url(r'^sys/info/$', sys_info, name='sys_info'),
url(r'^sys/settings/$', sys_settings, name='sys_settings'), url(r'^sys/settings/$', sys_settings, name='sys_settings'),
url(r'^sys/seafadmin/$', sys_repo_admin, name='sys_repo_admin'), url(r'^sys/seafadmin/$', sys_repo_admin, name='sys_repo_admin'),
url(r'^sys/seafadmin/repo/(?P<repo_id>[-0-9a-f]{36})/$', sys_admin_repo, name='sys_admin_repo'),
url(r'^sys/seafadmin/repo/(?P<repo_id>[-0-9a-f]{36})/download-file/$', sys_admin_repo_download_file, name='sys_admin_repo_download_file'),
url(r'^sys/seafadmin/system/$', sys_list_system, name='sys_list_system'), url(r'^sys/seafadmin/system/$', sys_list_system, name='sys_list_system'),
url(r'^sys/seafadmin/repo-trash/$', sys_repo_trash, name='sys_repo_trash'), url(r'^sys/seafadmin/repo-trash/$', sys_repo_trash, name='sys_repo_trash'),
url(r'^sys/seafadmin/repo-trash/clear/$', sys_repo_trash_clear, name="sys_repo_trash_clear"), url(r'^sys/seafadmin/repo-trash/clear/$', sys_repo_trash_clear, name="sys_repo_trash_clear"),
@@ -255,7 +257,6 @@ urlpatterns = patterns(
url(r'^useradmin/batchadduser/$', batch_add_user, name='batch_add_user'), url(r'^useradmin/batchadduser/$', batch_add_user, name='batch_add_user'),
url(r'^client-login/$', client_token_login, name='client_token_login'), url(r'^client-login/$', client_token_login, name='client_token_login'),
) )
from seahub.utils import EVENTS_ENABLED from seahub.utils import EVENTS_ENABLED

View File

@@ -6,6 +6,7 @@ import logging
import json import json
import re import re
import datetime import datetime
import stat
import csv, chardet, StringIO import csv, chardet, StringIO
from constance import config from constance import config
@@ -18,7 +19,8 @@ from django.utils import timezone
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from seaserv import ccnet_threaded_rpc, seafserv_threaded_rpc, get_emailusers, \ from seaserv import ccnet_threaded_rpc, seafserv_threaded_rpc, get_emailusers, \
CALC_SHARE_USAGE, seafile_api, get_group, get_group_members CALC_SHARE_USAGE, seafile_api, get_group, get_group_members, get_repo, \
get_file_size
from pysearpc import SearpcError from pysearpc import SearpcError
from seahub.base.accounts import User from seahub.base.accounts import User
@@ -31,21 +33,22 @@ from seahub.constants import GUEST_USER, DEFAULT_USER
from seahub.utils import IS_EMAIL_CONFIGURED, string2list, is_valid_username, \ from seahub.utils import IS_EMAIL_CONFIGURED, string2list, is_valid_username, \
is_pro_version, send_html_email, get_user_traffic_list, get_server_id, \ is_pro_version, send_html_email, get_user_traffic_list, get_server_id, \
clear_token clear_token, gen_file_get_url, is_org_context
from seahub.utils.rpc import mute_seafile_api from seahub.utils.rpc import mute_seafile_api
from seahub.utils.licenseparse import parse_license from seahub.utils.licenseparse import parse_license
from seahub.utils.sysinfo import get_platform_name from seahub.utils.sysinfo import get_platform_name
from seahub.views import get_system_default_repo_id
from seahub.views.ajax import (get_related_users_by_org_repo, from seahub.views.ajax import (get_related_users_by_org_repo,
get_related_users_by_repo) get_related_users_by_repo)
from seahub.views import get_system_default_repo_id, gen_path_link
from seahub.forms import SetUserQuotaForm, AddUserForm, BatchAddUserForm from seahub.forms import SetUserQuotaForm, AddUserForm, BatchAddUserForm
from seahub.profile.models import Profile, DetailedProfile from seahub.profile.models import Profile, DetailedProfile
from seahub.signals import repo_deleted from seahub.signals import repo_deleted
from seahub.share.models import FileShare, UploadLinkShare from seahub.share.models import FileShare, UploadLinkShare
import seahub.settings as settings import seahub.settings as settings
from seahub.settings import INIT_PASSWD, SITE_NAME, CONSTANCE_CONFIG, \ from seahub.settings import INIT_PASSWD, SITE_NAME, \
SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, SEND_EMAIL_ON_RESETTING_USER_PASSWD SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, SEND_EMAIL_ON_RESETTING_USER_PASSWD, \
ENABLE_SYS_ADMIN_VIEW_REPO
try: try:
from seahub.settings import ENABLE_TRIAL_ACCOUNT from seahub.settings import ENABLE_TRIAL_ACCOUNT
except: except:
@@ -155,7 +158,9 @@ def sys_repo_admin(request):
else: else:
page_next = False page_next = False
default_repo_id = get_system_default_repo_id()
for repo in repos: for repo in repos:
repo.is_default_repo = True if repo.id == default_repo_id else False
try: try:
repo.owner = seafile_api.get_repo_owner(repo.id) repo.owner = seafile_api.get_repo_owner(repo.id)
except: except:
@@ -163,6 +168,7 @@ def sys_repo_admin(request):
return render_to_response( return render_to_response(
'sysadmin/sys_repo_admin.html', { 'sysadmin/sys_repo_admin.html', {
'enable_sys_admin_view_repo': ENABLE_SYS_ADMIN_VIEW_REPO,
'repos': repos, 'repos': repos,
'current_page': current_page, 'current_page': current_page,
'prev_page': current_page-1, 'prev_page': current_page-1,
@@ -172,6 +178,102 @@ def sys_repo_admin(request):
}, },
context_instance=RequestContext(request)) context_instance=RequestContext(request))
@login_required
@sys_staff_required
def sys_admin_repo_download_file(request, repo_id):
"""
"""
repo = get_repo(repo_id)
path = request.GET.get('p', '')
obj_id = seafile_api.get_file_id_by_path(repo_id, path)
next = request.META.get('HTTP_REFERER', None)
if not next:
next = reverse('sys_admin_repo')
if not repo or repo.encrypted or not is_pro_version() \
or not ENABLE_SYS_ADMIN_VIEW_REPO or not obj_id:
messages.error(request, _(u'Unable to download file'))
return HttpResponseRedirect(next)
try:
token = seafile_api.get_fileserver_access_token(repo_id, obj_id,
'download', request.user.username)
except SearpcError as e:
logger.error(e)
messages.error(request, _(u'Unable to view library'))
return HttpResponseRedirect(next)
file_name = os.path.basename(path.rstrip('/'))
redirect_url = gen_file_get_url(token, file_name)
return HttpResponseRedirect(redirect_url)
@login_required
@sys_staff_required
def sys_admin_repo(request, repo_id):
next = request.META.get('HTTP_REFERER', None)
if not next:
next = reverse('sys_repo_admin')
if not is_pro_version() or not ENABLE_SYS_ADMIN_VIEW_REPO:
messages.error(request, _(u'Unable to view library, this feature is not enabled.'))
return HttpResponseRedirect(next)
repo = get_repo(repo_id)
if not repo:
messages.error(request, _(u'Library does not exist'))
return HttpResponseRedirect(next)
if repo.encrypted:
messages.error(request, _(u'Library is encrypted'))
return HttpResponseRedirect(next)
path = request.GET.get('p', '/')
if path[-1] != '/':
path = path + '/'
dir_id = seafile_api.get_dir_id_by_path(repo_id, path)
if not dir_id:
messages.error(request, _(u'Unable to view library, wrong folder path.'))
return HttpResponseRedirect(next)
if is_org_context(request):
repo_owner = seafile_api.get_org_repo_owner(repo_id)
else:
repo_owner = seafile_api.get_repo_owner(repo_id)
try:
dirs = seafserv_threaded_rpc.list_dir_with_perm(repo_id, path,
dir_id, repo_owner,
-1, -1)
except SearpcError as e:
logger.error(e)
messages.error(request, _(u'Unable to view library'))
return HttpResponseRedirect(next)
file_list, dir_list = [], []
for dirent in dirs:
dirent.last_modified = dirent.mtime
if stat.S_ISDIR(dirent.props.mode):
dir_list.append(dirent)
else:
if repo.version == 0:
dirent.file_size = get_file_size(repo.store_id, repo.version, dirent.obj_id)
else:
dirent.file_size = dirent.size
file_list.append(dirent)
zipped = gen_path_link(path, repo.name)
return render_to_response('sysadmin/admin_repo_view.html', {
'repo': repo,
'repo_owner': repo_owner,
'dir_list': dir_list,
'file_list': file_list,
'path': path,
'zipped': zipped,
}, context_instance=RequestContext(request))
@login_required @login_required
@sys_staff_required @sys_staff_required
def sys_list_system(request): def sys_list_system(request):
@@ -332,6 +434,7 @@ def sys_repo_search(request):
'repos': repos, 'repos': repos,
'name': repo_name, 'name': repo_name,
'owner': owner, 'owner': owner,
'enable_sys_admin_view_repo': ENABLE_SYS_ADMIN_VIEW_REPO,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
def _populate_user_quota_usage(user): def _populate_user_quota_usage(user):
@@ -723,6 +826,7 @@ def user_info(request, email):
'd_profile': d_profile, 'd_profile': d_profile,
'org_name': org_name, 'org_name': org_name,
'user_shared_links': user_shared_links, 'user_shared_links': user_shared_links,
'enable_sys_admin_view_repo': ENABLE_SYS_ADMIN_VIEW_REPO,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
@login_required_ajax @login_required_ajax
@@ -1171,6 +1275,7 @@ def sys_admin_group_info(request, group_id):
'group': group, 'group': group,
'repos': repos, 'repos': repos,
'members': members, 'members': members,
'enable_sys_admin_view_repo': ENABLE_SYS_ADMIN_VIEW_REPO,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
@login_required @login_required