mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-15 14:49:09 +00:00
Add org repo create and clean code.
This commit is contained in:
54
forms.py
54
forms.py
@@ -1,8 +1,9 @@
|
|||||||
|
# encoding: utf-8
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from seaserv import ccnet_rpc, ccnet_threaded_rpc
|
from seaserv import ccnet_rpc, ccnet_threaded_rpc, is_valid_filename
|
||||||
|
|
||||||
class AddUserForm(forms.Form):
|
class AddUserForm(forms.Form):
|
||||||
"""
|
"""
|
||||||
@@ -41,4 +42,55 @@ class FileLinkShareForm(forms.Form):
|
|||||||
email = forms.CharField(max_length=512)
|
email = forms.CharField(max_length=512)
|
||||||
file_shared_link = forms.CharField(max_length=40)
|
file_shared_link = forms.CharField(max_length=40)
|
||||||
|
|
||||||
|
class RepoCreateForm(forms.Form):
|
||||||
|
"""
|
||||||
|
Form for creating repo and org repo.
|
||||||
|
"""
|
||||||
|
repo_name = forms.CharField(max_length=15, error_messages={
|
||||||
|
'required': '目录名不能为空',
|
||||||
|
'max_length': '目录名太长,不超过50个字符'
|
||||||
|
})
|
||||||
|
repo_desc = forms.CharField(max_length=100, error_messages={
|
||||||
|
'required': '描述不能为空',
|
||||||
|
'max_length': '描述太长,不超过100个字符'
|
||||||
|
})
|
||||||
|
encryption = forms.CharField(max_length=1)
|
||||||
|
passwd = forms.CharField(min_length=3, max_length=15, required=False,
|
||||||
|
error_messages={
|
||||||
|
'min_length': '密码太短',
|
||||||
|
'max_length': '密码太长',
|
||||||
|
})
|
||||||
|
passwd_again = forms.CharField(min_length=3, max_length=15, required=False,
|
||||||
|
error_messages={
|
||||||
|
'min_length': '密码太短',
|
||||||
|
'max_length': '密码太长',
|
||||||
|
})
|
||||||
|
|
||||||
|
def clean_repo_name(self):
|
||||||
|
repo_name = self.cleaned_data['repo_name']
|
||||||
|
if not is_valid_filename(repo_name):
|
||||||
|
error_msg = u"您输入的目录名 %s 包含非法字符" % repo_name
|
||||||
|
raise forms.ValidationError(error_msg)
|
||||||
|
else:
|
||||||
|
return repo_name
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
"""
|
||||||
|
Verifiy that the values entered into the two password fields
|
||||||
|
match.
|
||||||
|
"""
|
||||||
|
if 'passwd' in self.cleaned_data and 'passwd_again' in self.cleaned_data:
|
||||||
|
encryption = self.cleaned_data['encryption']
|
||||||
|
if int(encryption) == 0:
|
||||||
|
# This prevents the case that form has passwords but the
|
||||||
|
# encryption checkbox is not selected.
|
||||||
|
self.cleaned_data['passwd'] = None
|
||||||
|
self.cleaned_data['passwd_again'] = None
|
||||||
|
return self.cleaned_data
|
||||||
|
else:
|
||||||
|
passwd = self.cleaned_data['passwd']
|
||||||
|
passwd_again = self.cleaned_data['passwd_again']
|
||||||
|
if passwd != passwd_again:
|
||||||
|
raise forms.ValidationError("两次输入的密码不一致")
|
||||||
|
return self.cleaned_data
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
<label for="id_org_name">团体名称:</label>
|
<label for="id_org_name">团体名称:</label>
|
||||||
{{ form.org_name}}
|
{{ form.org_name}}
|
||||||
<lable for="id_url_prefix">域名前缀:</label>
|
<lable for="id_url_prefix">个性域名:</label>
|
||||||
{{ form.url_prefix }}
|
{{ form.url_prefix }}
|
||||||
<p class="error hide"></p>
|
<p class="error hide"></p>
|
||||||
{{ form.url_prefix.errors }}
|
{{ form.url_prefix.errors }}
|
||||||
|
@@ -9,9 +9,9 @@ urlpatterns = patterns('',
|
|||||||
url(r'^messages/$', org_msg, name='org_msg'),
|
url(r'^messages/$', org_msg, name='org_msg'),
|
||||||
url(r'^(?P<url_prefix>[^/]+)/$', org_info, name='org_info'),
|
url(r'^(?P<url_prefix>[^/]+)/$', org_info, name='org_info'),
|
||||||
url(r'^(?P<url_prefix>[^/]+)/groups/$', org_groups, name='org_groups'),
|
url(r'^(?P<url_prefix>[^/]+)/groups/$', org_groups, name='org_groups'),
|
||||||
url(r'^([^/]+)/repo/(?P<repo_id>[^/]+)/$', repo, name='repo'),
|
|
||||||
url(r'^([^/]+)/repo/history/(?P<repo_id>[^/]+)/$', repo_history, name='org_repo_history'),
|
|
||||||
url(r'^([^/]+)/repo/create/$', org_repo_create, name='org_repo_create'),
|
url(r'^([^/]+)/repo/create/$', org_repo_create, name='org_repo_create'),
|
||||||
|
url(r'^([^/]+)/repo/history/(?P<repo_id>[^/]+)/$', repo_history, name='org_repo_history'),
|
||||||
|
url(r'^([^/]+)/repo/(?P<repo_id>[^/]+)/$', repo, name='repo'),
|
||||||
|
|
||||||
### Org admin ###
|
### Org admin ###
|
||||||
url(r'^([^/]+)/seafadmin/$', org_seafadmin, name='org_seafadmin'),
|
url(r'^([^/]+)/seafadmin/$', org_seafadmin, name='org_seafadmin'),
|
||||||
|
@@ -2,18 +2,32 @@ import sys
|
|||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from settings import ORG_CACHE_PREFIX
|
from settings import ORG_CACHE_PREFIX
|
||||||
|
|
||||||
|
from seaserv import get_org_id_by_repo_id
|
||||||
|
|
||||||
def clear_org_ctx(request):
|
def clear_org_ctx(request):
|
||||||
"""
|
"""
|
||||||
|
Clear current context.
|
||||||
"""
|
"""
|
||||||
cache.delete(ORG_CACHE_PREFIX + request.user.username)
|
cache.delete(ORG_CACHE_PREFIX + request.user.username)
|
||||||
request.user.org = None
|
request.user.org = None
|
||||||
|
|
||||||
def set_org_ctx(request, org_dict):
|
def set_org_ctx(request, org_dict):
|
||||||
"""
|
"""
|
||||||
|
Set current context to org.
|
||||||
"""
|
"""
|
||||||
cache.set(ORG_CACHE_PREFIX + request.user.username, org_dict, sys.maxint)
|
cache.set(ORG_CACHE_PREFIX + request.user.username, org_dict, sys.maxint)
|
||||||
request.user.org = org_dict
|
request.user.org = org_dict
|
||||||
|
|
||||||
|
def access_org_repo(request, repo_id):
|
||||||
|
"""
|
||||||
|
Check whether user can view org repo.
|
||||||
|
Arguments:
|
||||||
|
- `request`: request must has org dict.
|
||||||
|
- `repo_id`: repo id
|
||||||
|
"""
|
||||||
|
cur_org_id = request.user.org['org_id']
|
||||||
|
org_id = get_org_id_by_repo_id(repo_id)
|
||||||
|
return True if cur_org_id == org_id else False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
import simplejson as json
|
||||||
import sys
|
import sys
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
from django.contrib.sites.models import Site, RequestSite
|
from django.contrib.sites.models import Site, RequestSite
|
||||||
from django.http import HttpResponse, HttpResponseRedirect, Http404
|
from django.http import HttpResponse, HttpResponseBadRequest, Http404, \
|
||||||
|
HttpResponseRedirect
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from django.template import Context, loader, RequestContext
|
from django.template import Context, loader, RequestContext
|
||||||
|
|
||||||
@@ -12,7 +14,8 @@ from auth.decorators import login_required
|
|||||||
from pysearpc import SearpcError
|
from pysearpc import SearpcError
|
||||||
from seaserv import ccnet_threaded_rpc, get_orgs_by_user, get_org_repos, \
|
from seaserv import ccnet_threaded_rpc, get_orgs_by_user, get_org_repos, \
|
||||||
get_org_by_url_prefix, create_org, get_user_current_org, add_org_user, \
|
get_org_by_url_prefix, create_org, get_user_current_org, add_org_user, \
|
||||||
get_ccnetuser, remove_org_user, get_org_groups, is_valid_filename
|
get_ccnetuser, remove_org_user, get_org_groups, is_valid_filename, \
|
||||||
|
create_org_repo
|
||||||
|
|
||||||
from forms import OrgCreateForm
|
from forms import OrgCreateForm
|
||||||
from signals import org_user_added
|
from signals import org_user_added
|
||||||
@@ -20,6 +23,7 @@ from settings import ORG_CACHE_PREFIX
|
|||||||
from utils import set_org_ctx
|
from utils import set_org_ctx
|
||||||
from notifications.models import UserNotification
|
from notifications.models import UserNotification
|
||||||
from registration.models import RegistrationProfile
|
from registration.models import RegistrationProfile
|
||||||
|
from seahub.forms import RepoCreateForm
|
||||||
import seahub.settings as seahub_settings
|
import seahub.settings as seahub_settings
|
||||||
from seahub.utils import go_error, go_permission_error, validate_group_name, \
|
from seahub.utils import go_error, go_permission_error, validate_group_name, \
|
||||||
emails2list, gen_token
|
emails2list, gen_token
|
||||||
@@ -230,58 +234,34 @@ def org_msg(request):
|
|||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request))
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def org_repo_create(request):
|
def org_repo_create(request, url_prefix):
|
||||||
'''
|
'''
|
||||||
Handle ajax post to create org repo.
|
Handle ajax post to create org repo.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
if request.method != 'POST':
|
if not request.is_ajax() or request.method != 'POST':
|
||||||
return Http404
|
return Http404
|
||||||
repo_name = request.POST.get("repo_name")
|
|
||||||
repo_desc = request.POST.get("repo_desc")
|
|
||||||
encrypted = int(request.POST.get("encryption"))
|
|
||||||
passwd = request.POST.get("passwd")
|
|
||||||
passwd_again = request.POST.get("passwd_again")
|
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
content_type = 'application/json; charset=utf-8'
|
content_type = 'application/json; charset=utf-8'
|
||||||
|
|
||||||
error_msg = ""
|
form = RepoCreateForm(request.POST)
|
||||||
if not repo_name:
|
if form.is_valid():
|
||||||
error_msg = u"目录名不能为空"
|
repo_name = form.cleaned_data['repo_name']
|
||||||
elif len(repo_name) > 50:
|
repo_desc = form.cleaned_data['repo_desc']
|
||||||
error_msg = u"目录名太长"
|
encrypted = form.cleaned_data['encryption']
|
||||||
elif not is_valid_filename(repo_name):
|
passwd = form.cleaned_data['passwd']
|
||||||
error_msg = (u"您输入的目录名 %s 包含非法字符" % repo_name)
|
passwd_again = form.cleaned_data['passwd_again']
|
||||||
elif not repo_desc:
|
|
||||||
error_msg = u"描述不能为空"
|
|
||||||
elif len(repo_desc) > 100:
|
|
||||||
error_msg = u"描述太长"
|
|
||||||
elif encrypted == 1:
|
|
||||||
if not passwd:
|
|
||||||
error_msg = u"密码不能为空"
|
|
||||||
elif not passwd_again:
|
|
||||||
error_msg = u"确认密码不能为空"
|
|
||||||
elif len(passwd) < 3:
|
|
||||||
error_msg = u"密码太短"
|
|
||||||
elif len(passwd) > 15:
|
|
||||||
error_msg = u"密码太长"
|
|
||||||
elif passwd != passwd_again:
|
|
||||||
error_msg = u"两次输入的密码不相同"
|
|
||||||
|
|
||||||
if error_msg:
|
|
||||||
result['error'] = error_msg
|
|
||||||
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
||||||
|
|
||||||
try:
|
|
||||||
user = request.user.username
|
user = request.user.username
|
||||||
org_id = request.user.org['org_id']
|
org_id = request.user.org['org_id']
|
||||||
|
|
||||||
repo_id = create_org_repo(repo_name, repo_desc, user, passwd, org_id)
|
repo_id = create_org_repo(repo_name, repo_desc, user, passwd, org_id)
|
||||||
result['success'] = True
|
|
||||||
except:
|
|
||||||
result['error'] = u"创建目录失败"
|
|
||||||
else:
|
|
||||||
if not repo_id:
|
if not repo_id:
|
||||||
result['error'] = u"创建目录失败"
|
result['error'] = u"创建目录失败"
|
||||||
|
else:
|
||||||
|
result['success'] = True
|
||||||
return HttpResponse(json.dumps(result), content_type=content_type)
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
||||||
|
else:
|
||||||
|
return HttpResponseBadRequest(json.dumps(form.errors),
|
||||||
|
content_type=content_type)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
{% extends "myhome_base.html" %}
|
{% extends base_template %}
|
||||||
{% load seahub_tags %}
|
{% load seahub_tags %}
|
||||||
|
|
||||||
{% block info_bar_message %}
|
{% block info_bar_message %}
|
||||||
|
@@ -1,129 +0,0 @@
|
|||||||
$(function() {
|
|
||||||
//repo-share-form share-list autocomplete
|
|
||||||
var share_list = [];
|
|
||||||
{% for contact in contacts %}
|
|
||||||
share_list.push('{{ contact.contact_email }}');
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% for group in groups %}
|
|
||||||
share_list.push('{{ group.props.group_name }} <{{ group.props.creator_name }}>');
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
$(".repo-share-btn").click(function() {
|
|
||||||
$("#repo_id").val($(this).attr("data"));
|
|
||||||
$("#repo-share-form").modal({appendTo: "#main"});
|
|
||||||
addAutocomplete('#email_or_group', '#repo-share-form', share_list);
|
|
||||||
});
|
|
||||||
|
|
||||||
//check before post
|
|
||||||
$('#share-submit-btn').click(function() {
|
|
||||||
if (!$.trim($('#email_or_group').attr('value'))) {
|
|
||||||
$('#repo-share-form .error').removeClass('hide');
|
|
||||||
$('#simplemodal-container').css('height', $('#repo-share-form').height());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addConfirmTo($('.repo-delete-btn'));
|
|
||||||
|
|
||||||
addConfirmTo($('.unshare-btn'), '确定要取消共享?');
|
|
||||||
|
|
||||||
$(".download-btn").click(function() {
|
|
||||||
window.open('{{ SITE_ROOT }}seafile_access_check/?repo_id=' + $(this).attr('data'));
|
|
||||||
});
|
|
||||||
|
|
||||||
//show op images when mouse hover on
|
|
||||||
$("table tr:gt(0)").hover(
|
|
||||||
function() {
|
|
||||||
$(this).find('img').css('cursor', 'pointer').removeClass('vh');
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
$(this).find('img').addClass('vh');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
//repo-create-form
|
|
||||||
$('#repo-create').hover(
|
|
||||||
function() {
|
|
||||||
$(this).css({'background-color': '#fff', 'cursor': 'pointer'});
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
$(this).css('background-color', '#f5f5f5');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
$('#repo-create').click(function() {
|
|
||||||
$('#repo-create-form').modal({appendTo: '#main', autoResize: true});
|
|
||||||
});
|
|
||||||
$('#encrypt-switch').click(function () {
|
|
||||||
if ($(this).attr('checked')) {
|
|
||||||
$('#repo-create-form input[type="password"]').attr('disabled', false).removeClass('input-disabled');
|
|
||||||
} else {
|
|
||||||
$('#repo-create-form input[type="password"]').attr('disabled', true).addClass('input-disabled');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
function showError(err) {
|
|
||||||
$('#repo-create-form .error').html(err).attr('class','error');
|
|
||||||
$('#simplemodal-container').css('height', $('#repo-create-form').height());
|
|
||||||
}
|
|
||||||
$('#repo-create-submit').click(function() {
|
|
||||||
var passwd = $('#repo-create-form input[name="passwd"]'),
|
|
||||||
passwd_again = $('#repo-create-form input[name="passwd_again"]');
|
|
||||||
|
|
||||||
if (!$('#repo-name').val()) {
|
|
||||||
showError('目录名不能为空。');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!$('#repo-desc').val()) {
|
|
||||||
showError('描述不能为空。');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($('#encrypt-switch').attr('checked')) {
|
|
||||||
if (!passwd.val()) {
|
|
||||||
showError('密码不能为空。');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!passwd_again.val()) {
|
|
||||||
showError('请确认密码。');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (passwd.val().length < 3) {
|
|
||||||
showError('密码太短。');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (passwd.val().length > 15) {
|
|
||||||
showError('密码太长。');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (passwd.val() != passwd_again.val()) {
|
|
||||||
showError('两次输入的密码不一致。');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: '{{ url }}',
|
|
||||||
type: 'POST',
|
|
||||||
dataType: 'json',
|
|
||||||
cache: 'false',
|
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
beforeSend: prepareCSRFToken,
|
|
||||||
data: {
|
|
||||||
'repo_name': $('#repo-name').val(),
|
|
||||||
'repo_desc': $('#repo-desc').val(),
|
|
||||||
'encryption': $('#encrypt-switch').attr('checked') ? 1 : 0,
|
|
||||||
'passwd': passwd.val(),
|
|
||||||
'passwd_again': passwd_again.val()
|
|
||||||
},
|
|
||||||
success: function(data) {
|
|
||||||
if (data['success']) {
|
|
||||||
location.reload(true);
|
|
||||||
} else {
|
|
||||||
showError(data['error']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
@@ -1,4 +1,4 @@
|
|||||||
{% extends "myhome_base.html" %}
|
{% extends base_template %}
|
||||||
{% load seahub_tags %}
|
{% load seahub_tags %}
|
||||||
|
|
||||||
{% block left_panel %}
|
{% block left_panel %}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
{% extends "myhome_base.html" %}
|
{% extends base_template %}
|
||||||
{% load seahub_tags %}
|
{% load seahub_tags %}
|
||||||
|
|
||||||
{% block info_bar_message %}
|
{% block info_bar_message %}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
{% extends "myhome_base.html" %}
|
{% extends base_template %}
|
||||||
{% load seahub_tags %}
|
{% load seahub_tags %}
|
||||||
|
|
||||||
{% block info_bar_message %}
|
{% block info_bar_message %}
|
||||||
|
@@ -69,7 +69,7 @@ function showError(err) {
|
|||||||
$('#repo-create-submit').click(function() {
|
$('#repo-create-submit').click(function() {
|
||||||
var passwd = $('#repo-create-form input[name="passwd"]'),
|
var passwd = $('#repo-create-form input[name="passwd"]'),
|
||||||
passwd_again = $('#repo-create-form input[name="passwd_again"]');
|
passwd_again = $('#repo-create-form input[name="passwd_again"]');
|
||||||
|
/*
|
||||||
if (!$('#repo-name').val()) {
|
if (!$('#repo-name').val()) {
|
||||||
showError('目录名不能为空。');
|
showError('目录名不能为空。');
|
||||||
return false;
|
return false;
|
||||||
@@ -78,7 +78,6 @@ $('#repo-create-submit').click(function() {
|
|||||||
showError('描述不能为空。');
|
showError('描述不能为空。');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($('#encrypt-switch').attr('checked')) {
|
if ($('#encrypt-switch').attr('checked')) {
|
||||||
if (!passwd.val()) {
|
if (!passwd.val()) {
|
||||||
showError('密码不能为空。');
|
showError('密码不能为空。');
|
||||||
@@ -101,13 +100,12 @@ $('#repo-create-submit').click(function() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '{{ url }}',
|
url: '{{ url }}',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
cache: 'false',
|
cache: 'false',
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
beforeSend: prepareCSRFToken,
|
beforeSend: prepareCSRFToken,
|
||||||
data: {
|
data: {
|
||||||
'repo_name': $('#repo-name').val(),
|
'repo_name': $('#repo-name').val(),
|
||||||
@@ -117,12 +115,17 @@ $('#repo-create-submit').click(function() {
|
|||||||
'passwd_again': passwd_again.val()
|
'passwd_again': passwd_again.val()
|
||||||
},
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
alert(data);
|
|
||||||
if (data['success']) {
|
if (data['success']) {
|
||||||
location.reload(true);
|
location.reload(true);
|
||||||
} else {
|
} else {
|
||||||
showError(data['error']);
|
showError(data['error']);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
error: function(data, textStatus, jqXHR) {
|
||||||
|
var errors = $.parseJSON(data.responseText);
|
||||||
|
$.each(errors, function(index, value) {
|
||||||
|
showError(value[0]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -3,14 +3,15 @@ import service
|
|||||||
from service import ccnet_rpc, monitor_rpc, seafserv_rpc, \
|
from service import ccnet_rpc, monitor_rpc, seafserv_rpc, \
|
||||||
seafserv_threaded_rpc, ccnet_threaded_rpc
|
seafserv_threaded_rpc, ccnet_threaded_rpc
|
||||||
from service import send_command
|
from service import send_command
|
||||||
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, get_emailusers
|
from service import get_ccnetuser, get_emailusers
|
||||||
from service import get_group_repoids, check_group_staff
|
from service import get_org_groups, get_personal_groups, get_group_repoids, \
|
||||||
|
check_group_staff
|
||||||
|
from service import get_repos, get_repo, get_commits, get_branches, \
|
||||||
|
get_org_repos, is_repo_owner, create_org_repo
|
||||||
|
from service import get_binding_peerids, is_valid_filename
|
||||||
from service import create_org, get_orgs_by_user, get_org_by_url_prefix, \
|
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_user_current_org, add_org_user, remove_org_user, get_org_by_id, \
|
||||||
is_valid_filename
|
get_org_id_by_repo_id
|
||||||
|
|
||||||
from service import CCNET_CONF_PATH
|
from service import CCNET_CONF_PATH
|
||||||
|
|
||||||
|
@@ -220,6 +220,7 @@ def create_org_repo(repo_name, repo_desc, user, passwd, org_id):
|
|||||||
|
|
||||||
def get_org_repos(org_id, start, limit):
|
def get_org_repos(org_id, start, limit):
|
||||||
"""
|
"""
|
||||||
|
List repos created in org.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
repos = seafserv_threaded_rpc.get_org_repo_list(org_id, start, limit)
|
repos = seafserv_threaded_rpc.get_org_repo_list(org_id, start, limit)
|
||||||
@@ -228,9 +229,29 @@ def get_org_repos(org_id, start, limit):
|
|||||||
|
|
||||||
return repos
|
return repos
|
||||||
|
|
||||||
|
def get_org_id_by_repo_id(repo_id):
|
||||||
|
"""
|
||||||
|
Get org id according repo id.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
org_id = seafserv_threaded_rpc.get_org_id_by_repo_id(repo_id)
|
||||||
|
except SearpcError:
|
||||||
|
org_id = ''
|
||||||
|
return org_id
|
||||||
|
|
||||||
def get_repo(repo_id):
|
def get_repo(repo_id):
|
||||||
return seafserv_threaded_rpc.get_repo(repo_id)
|
return seafserv_threaded_rpc.get_repo(repo_id)
|
||||||
|
|
||||||
|
def is_repo_owner(user, repo_id):
|
||||||
|
"""
|
||||||
|
Check whether user is repo owner.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
ret = seafserv_threaded_rpc.is_repo_owner(user, repo_id)
|
||||||
|
except SearpcError:
|
||||||
|
ret = 0
|
||||||
|
return ret
|
||||||
|
|
||||||
def get_commits(repo_id, offset, limit):
|
def get_commits(repo_id, offset, limit):
|
||||||
"""Get commit lists."""
|
"""Get commit lists."""
|
||||||
return seafserv_threaded_rpc.get_commit_list(repo_id, offset, limit)
|
return seafserv_threaded_rpc.get_commit_list(repo_id, offset, limit)
|
||||||
|
161
views.py
161
views.py
@@ -14,7 +14,8 @@ from django.contrib import messages
|
|||||||
from django.contrib.sites.models import Site, RequestSite
|
from django.contrib.sites.models import Site, RequestSite
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from django.http import HttpResponse, HttpResponseRedirect, Http404
|
from django.http import HttpResponse, HttpResponseBadRequest, Http404, \
|
||||||
|
HttpResponseRedirect
|
||||||
from django.shortcuts import render_to_response, redirect
|
from django.shortcuts import render_to_response, redirect
|
||||||
from django.template import Context, loader, RequestContext
|
from django.template import Context, loader, RequestContext
|
||||||
from django.views.decorators.csrf import csrf_protect
|
from django.views.decorators.csrf import csrf_protect
|
||||||
@@ -30,15 +31,15 @@ from share.models import FileShare
|
|||||||
from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, get_emailusers, \
|
from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, get_emailusers, \
|
||||||
get_repo, get_commits, get_branches, is_valid_filename, \
|
get_repo, get_commits, get_branches, is_valid_filename, \
|
||||||
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, get_ccnetuser, \
|
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, get_ccnetuser, \
|
||||||
get_group_repoids, check_group_staff, get_personal_groups
|
get_group_repoids, check_group_staff, get_personal_groups, is_repo_owner
|
||||||
from pysearpc import SearpcError
|
from pysearpc import SearpcError
|
||||||
|
|
||||||
from seahub.base.accounts import CcnetUser
|
from seahub.base.accounts import CcnetUser
|
||||||
from seahub.base.models import UuidOjbidMap
|
from seahub.base.models import UuidOjbidMap
|
||||||
from seahub.contacts.models import Contact
|
from seahub.contacts.models import Contact
|
||||||
from seahub.notifications.models import UserNotification
|
from seahub.notifications.models import UserNotification
|
||||||
from seahub.organizations.utils import clear_org_ctx
|
from seahub.organizations.utils import clear_org_ctx, access_org_repo
|
||||||
from forms import AddUserForm, FileLinkShareForm
|
from forms import AddUserForm, FileLinkShareForm, RepoCreateForm
|
||||||
from utils import go_permission_error, go_error, list_to_string, \
|
from utils import go_permission_error, go_error, list_to_string, \
|
||||||
get_httpserver_root, get_ccnetapplet_root, gen_token, \
|
get_httpserver_root, get_ccnetapplet_root, gen_token, \
|
||||||
calculate_repo_last_modify, valid_previewed_file, \
|
calculate_repo_last_modify, valid_previewed_file, \
|
||||||
@@ -52,26 +53,18 @@ from seahub.settings import FILE_PREVIEW_MAX_SIZE, CROCODOC_API_TOKEN
|
|||||||
def root(request):
|
def root(request):
|
||||||
return HttpResponseRedirect(reverse(myhome))
|
return HttpResponseRedirect(reverse(myhome))
|
||||||
|
|
||||||
|
|
||||||
def validate_owner(request, repo_id):
|
def validate_owner(request, repo_id):
|
||||||
"""
|
"""
|
||||||
Check whether email in the request own the repo
|
Check whether user in the request owns the repo.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
ret = is_repo_owner(request.user.username, repo_id)
|
||||||
ret = seafserv_threaded_rpc.is_repo_owner(request.user.username,
|
|
||||||
repo_id)
|
|
||||||
except:
|
|
||||||
ret = 0
|
|
||||||
|
|
||||||
if ret == 0 or ret is None:
|
return True if ret else False
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def validate_emailuser(emailuser):
|
def validate_emailuser(emailuser):
|
||||||
"""
|
"""
|
||||||
check whether emailuser is in the database
|
Check whether user is registerd.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@@ -120,13 +113,14 @@ def access_to_repo(request, repo_id, repo_ap):
|
|||||||
Check whether user in the request can access to repo, which means user can
|
Check whether user in the request can access to repo, which means user can
|
||||||
view directory entries on repo page. Only repo owner or person who is shared
|
view directory entries on repo page. Only repo owner or person who is shared
|
||||||
can access to repo.
|
can access to repo.
|
||||||
|
NOTE: `repo_ap` may be used in future.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if repo_ap == 'own' and not validate_owner(request, repo_id) \
|
if validate_owner(request, repo_id) or check_shared_repo(request, repo_id)\
|
||||||
and not check_shared_repo(request, repo_id):
|
or access_org_repo(request, repo_id):
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def gen_path_link(path, repo_name):
|
def gen_path_link(path, repo_name):
|
||||||
"""
|
"""
|
||||||
@@ -153,18 +147,8 @@ def gen_path_link(path, repo_name):
|
|||||||
return zipped
|
return zipped
|
||||||
|
|
||||||
def render_repo(request, repo_id, error=''):
|
def render_repo(request, repo_id, error=''):
|
||||||
# get repo web access property, if no repo access property in db, then
|
|
||||||
# assume repo ap is 'own'
|
|
||||||
# repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
|
||||||
# if not repo_ap:
|
|
||||||
# repo_ap = 'own'
|
|
||||||
|
|
||||||
# Since repo web access property is removed since 0.9.4, we assume all repo
|
|
||||||
# is 'own' for compatibility
|
|
||||||
repo_ap = 'own'
|
|
||||||
|
|
||||||
# Check whether user can view repo page
|
# Check whether user can view repo page
|
||||||
can_access = access_to_repo(request, repo_id, repo_ap)
|
can_access = access_to_repo(request, repo_id, '')
|
||||||
if not can_access:
|
if not can_access:
|
||||||
return go_permission_error(request, '无法访问该同步目录')
|
return go_permission_error(request, '无法访问该同步目录')
|
||||||
|
|
||||||
@@ -250,7 +234,6 @@ def render_repo(request, repo_id, error=''):
|
|||||||
"view_history": view_history,
|
"view_history": view_history,
|
||||||
"is_owner": is_owner,
|
"is_owner": is_owner,
|
||||||
"password_set": password_set,
|
"password_set": password_set,
|
||||||
"repo_ap": repo_ap,
|
|
||||||
"repo_size": repo_size,
|
"repo_size": repo_size,
|
||||||
"dir_list": dir_list,
|
"dir_list": dir_list,
|
||||||
"file_list": file_list,
|
"file_list": file_list,
|
||||||
@@ -482,11 +465,7 @@ def repo_history(request, repo_id):
|
|||||||
"""
|
"""
|
||||||
View repo history
|
View repo history
|
||||||
"""
|
"""
|
||||||
repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
if not access_to_repo(request, repo_id, ''):
|
||||||
if not repo_ap:
|
|
||||||
repo_ap = 'own'
|
|
||||||
|
|
||||||
if not access_to_repo(request, repo_id, repo_ap):
|
|
||||||
return go_permission_error(request, u'无法浏览该同步目录修改历史')
|
return go_permission_error(request, u'无法浏览该同步目录修改历史')
|
||||||
|
|
||||||
repo = get_repo(repo_id)
|
repo = get_repo(repo_id)
|
||||||
@@ -607,11 +586,7 @@ def repo_history_changes(request, repo_id):
|
|||||||
changes = {}
|
changes = {}
|
||||||
content_type = 'application/json; charset=utf-8'
|
content_type = 'application/json; charset=utf-8'
|
||||||
|
|
||||||
repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
if not access_to_repo(request, repo_id, ''):
|
||||||
if repo_ap == None:
|
|
||||||
repo_ap = 'own'
|
|
||||||
|
|
||||||
if not access_to_repo(request, repo_id, repo_ap):
|
|
||||||
return HttpResponse(json.dumps(changes),
|
return HttpResponse(json.dumps(changes),
|
||||||
content_type=content_type)
|
content_type=content_type)
|
||||||
|
|
||||||
@@ -657,8 +632,10 @@ def modify_token(request, repo_id):
|
|||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def remove_repo(request, repo_id):
|
def remove_repo(request, repo_id):
|
||||||
if not validate_owner(request, repo_id) and not request.user.is_staff:
|
if not validate_owner(request, repo_id) and not request.user.is_staff \
|
||||||
return go_permission_error(request, u'删除同步目录失败')
|
and not request.user.org['is_staff']:
|
||||||
|
err_msg = u'删除同步目录失败, 只有管理员或目录创建者有权删除目录。'
|
||||||
|
return go_permission_error(request, err_msg)
|
||||||
|
|
||||||
seafserv_threaded_rpc.remove_repo(repo_id)
|
seafserv_threaded_rpc.remove_repo(repo_id)
|
||||||
next = request.GET.get('next', '/')
|
next = request.GET.get('next', '/')
|
||||||
@@ -816,24 +793,14 @@ def repo_view_file(request, repo_id):
|
|||||||
if not repo:
|
if not repo:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
# if a repo is shared to me, then I can view and download file no mater whether
|
|
||||||
# repo's access property is 'own' or 'public'
|
|
||||||
if check_shared_repo(request, repo_id):
|
|
||||||
share_to_me = True
|
|
||||||
else:
|
|
||||||
share_to_me = False
|
|
||||||
|
|
||||||
token = ''
|
token = ''
|
||||||
# people who is owner or this repo is shared to him, can visit the repo;
|
if access_to_repo(request, repo_id, ''):
|
||||||
# others, just go to 404 page
|
# Get a token to visit file
|
||||||
if validate_owner(request, repo_id) or share_to_me:
|
|
||||||
# owner should get a token to visit repo
|
|
||||||
token = gen_token()
|
token = gen_token()
|
||||||
# put token into memory in seaf-server
|
|
||||||
seafserv_rpc.web_save_access_token(token, repo_id, obj_id,
|
seafserv_rpc.web_save_access_token(token, repo_id, obj_id,
|
||||||
'view', request.user.username)
|
'view', request.user.username)
|
||||||
else:
|
else:
|
||||||
raise Http404
|
go_permission_error(request, '无法查看该文件')
|
||||||
|
|
||||||
# generate path and link
|
# generate path and link
|
||||||
zipped = gen_path_link(path, repo.name)
|
zipped = gen_path_link(path, repo.name)
|
||||||
@@ -974,19 +941,6 @@ def repo_access_file(request, repo_id, obj_id):
|
|||||||
if op == 'del':
|
if op == 'del':
|
||||||
return repo_del_file(request, repo_id)
|
return repo_del_file(request, repo_id)
|
||||||
|
|
||||||
# if a repo doesn't have access property in db, then assume it's 'own'
|
|
||||||
# repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
|
||||||
# if not repo_ap:
|
|
||||||
# repo_ap = 'own'
|
|
||||||
repo_ap = 'own'
|
|
||||||
|
|
||||||
# if a repo is shared to me, then I can view and download file no mater whether
|
|
||||||
# repo's access property is 'own' or 'public'
|
|
||||||
if check_shared_repo(request, repo_id):
|
|
||||||
share_to_me = True
|
|
||||||
else:
|
|
||||||
share_to_me = False
|
|
||||||
|
|
||||||
# If vistor's file shared token in url params matches the token in db,
|
# If vistor's file shared token in url params matches the token in db,
|
||||||
# then we know the vistor is from file shared link.
|
# then we know the vistor is from file shared link.
|
||||||
share_token = request.GET.get('t', '')
|
share_token = request.GET.get('t', '')
|
||||||
@@ -997,17 +951,13 @@ def repo_access_file(request, repo_id, obj_id):
|
|||||||
from_shared_link = False
|
from_shared_link = False
|
||||||
|
|
||||||
token = ''
|
token = ''
|
||||||
if repo_ap == 'own':
|
if access_to_repo(request, repo_id, '') or from_shared_link:
|
||||||
# people who is owner or this repo is shared to him, can visit the repo;
|
# Get a token to access file
|
||||||
# others, just go to 404 page
|
|
||||||
if validate_owner(request, repo_id) or share_to_me or from_shared_link:
|
|
||||||
# owner should get a token to visit repo
|
|
||||||
token = gen_token()
|
token = gen_token()
|
||||||
# put token into memory in seaf-server
|
|
||||||
seafserv_rpc.web_save_access_token(token, repo_id, obj_id,
|
seafserv_rpc.web_save_access_token(token, repo_id, obj_id,
|
||||||
op, request.user.username)
|
op, request.user.username)
|
||||||
else:
|
else:
|
||||||
raise Http404
|
go_permission_error(request, '无法访问文件')
|
||||||
|
|
||||||
redirect_url = gen_file_get_url(token, file_name)
|
redirect_url = gen_file_get_url(token, file_name)
|
||||||
return HttpResponseRedirect(redirect_url)
|
return HttpResponseRedirect(redirect_url)
|
||||||
@@ -1667,55 +1617,34 @@ def repo_create(request):
|
|||||||
Handle ajax post.
|
Handle ajax post.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
if request.method == 'POST':
|
if not request.is_ajax() or request.method != 'POST':
|
||||||
repo_name = request.POST.get("repo_name")
|
return Http404
|
||||||
repo_desc = request.POST.get("repo_desc")
|
|
||||||
encrypted = int(request.POST.get("encryption"))
|
|
||||||
passwd = request.POST.get("passwd")
|
|
||||||
passwd_again = request.POST.get("passwd_again")
|
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
content_type = 'application/json; charset=utf-8'
|
content_type = 'application/json; charset=utf-8'
|
||||||
|
|
||||||
error_msg = ""
|
form = RepoCreateForm(request.POST)
|
||||||
if not repo_name:
|
if form.is_valid():
|
||||||
error_msg = u"目录名不能为空"
|
repo_name = form.cleaned_data['repo_name']
|
||||||
elif len(repo_name) > 50:
|
repo_desc = form.cleaned_data['repo_desc']
|
||||||
error_msg = u"目录名太长"
|
encrypted = form.cleaned_data['encryption']
|
||||||
elif not is_valid_filename(repo_name):
|
passwd = form.cleaned_data['passwd']
|
||||||
error_msg = (u"您输入的目录名 %s 包含非法字符" % repo_name)
|
passwd_again = form.cleaned_data['passwd_again']
|
||||||
elif not repo_desc:
|
user = request.user.username
|
||||||
error_msg = u"描述不能为空"
|
|
||||||
elif len(repo_desc) > 100:
|
|
||||||
error_msg = u"描述太长"
|
|
||||||
elif encrypted == 1:
|
|
||||||
if not passwd:
|
|
||||||
error_msg = u"密码不能为空"
|
|
||||||
elif not passwd_again:
|
|
||||||
error_msg = u"确认密码不能为空"
|
|
||||||
elif len(passwd) < 3:
|
|
||||||
error_msg = u"密码太短"
|
|
||||||
elif len(passwd) > 15:
|
|
||||||
error_msg = u"密码太长"
|
|
||||||
elif passwd != passwd_again:
|
|
||||||
error_msg = u"两次输入的密码不相同"
|
|
||||||
|
|
||||||
if error_msg:
|
|
||||||
result['error'] = error_msg
|
|
||||||
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
repo_id = seafserv_threaded_rpc.create_repo(repo_name, repo_desc, request.user.username, passwd)
|
repo_id = seafserv_threaded_rpc.create_repo(repo_name, repo_desc,
|
||||||
result['success'] = True
|
user, passwd)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
result['error'] = u"创建目录失败"
|
repo_id = None
|
||||||
|
|
||||||
else:
|
|
||||||
if not repo_id:
|
if not repo_id:
|
||||||
result['error'] = u"创建目录失败"
|
result['error'] = u"创建目录失败"
|
||||||
|
else:
|
||||||
|
result['success'] = True
|
||||||
return HttpResponse(json.dumps(result), content_type=content_type)
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
||||||
|
else:
|
||||||
|
return HttpResponseBadRequest(json.dumps(form.errors),
|
||||||
|
content_type=content_type)
|
||||||
|
|
||||||
def render_file_revisions (request, repo_id):
|
def render_file_revisions (request, repo_id):
|
||||||
"""List all history versions of a file."""
|
"""List all history versions of a file."""
|
||||||
|
Reference in New Issue
Block a user