def _decorated(request, repo_id, *args, **kwargs): if request.method != 'POST' or not request.is_ajax(): raise Http404 result = {} content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: result['error'] = _(u'Library does not exist.') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # permission checking username = request.user.username if check_repo_access_permission(repo.id, request.user) != 'rw': result['error'] = _('Permission denied') return HttpResponse(json.dumps(result), status=403, content_type=content_type) # arguments validation path = request.GET.get('path') obj_name = request.GET.get('obj_name') dst_repo_id = request.POST.get('dst_repo') dst_path = request.POST.get('dst_path') if not (path and obj_name and dst_repo_id and dst_path): result['error'] = _('Argument missing') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # check file path if len(dst_path + obj_name) > settings.MAX_PATH: result['error'] = _('Destination path is too long.') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # check whether user has write permission to dest repo if check_repo_access_permission(dst_repo_id, request.user) != 'rw': result['error'] = _('Permission denied') return HttpResponse(json.dumps(result), status=403, content_type=content_type) # do nothing when dst is the same as src if repo_id == dst_repo_id and path == dst_path: result['error'] = _('Invalid destination path') return HttpResponse(json.dumps(result), status=400, content_type=content_type) return func(repo_id, path, dst_repo_id, dst_path, obj_name, username)
def _decorated(request, repo_id, *args, **kwargs): if request.method != 'POST' or not request.is_ajax(): raise Http404 result = {} content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: result['error'] = _(u'Library does not exist.') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # permission checking username = request.user.username if check_repo_access_permission(repo.id, request.user) != 'rw': result['error'] = _('Permission denied') return HttpResponse(json.dumps(result), status=403, content_type=content_type) # arguments validation parent_dir = request.GET.get('parent_dir') obj_file_names = request.POST.getlist('file_names') obj_dir_names = request.POST.getlist('dir_names') dst_repo_id = request.POST.get('dst_repo') dst_path = request.POST.get('dst_path') if not (parent_dir and dst_repo_id and dst_path) and not (obj_file_names or obj_dir_names): result['error'] = _('Argument missing') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # check file path for obj_name in obj_file_names + obj_dir_names: if len(dst_path+obj_name) > settings.MAX_PATH: result['error'] = _('Destination path is too long for %s.') % obj_name return HttpResponse(json.dumps(result), status=400, content_type=content_type) # check whether user has write permission to dest repo if check_repo_access_permission(dst_repo_id, request.user) != 'rw': result['error'] = _('Permission denied') return HttpResponse(json.dumps(result), status=403, content_type=content_type) # when dst is the same as src if repo_id == dst_repo_id and parent_dir == dst_path: result['error'] = _('Invalid destination path') return HttpResponse(json.dumps(result), status=400, content_type=content_type) return func(repo_id, parent_dir, dst_repo_id, dst_path, obj_file_names, obj_dir_names, username)
def check_user_folder_perm_args(from_user, repo_id, path, to_user, perm=None): if not seafile_api.get_repo(repo_id): return {'error': _(u'Library does not exist.'), 'status': 400} if check_repo_access_permission(repo_id, from_user) != 'rw': return {'error': _('Permission denied'), 'status': 403} if perm is not None: # add or toggle folder perm if seafile_api.get_dir_id_by_path(repo_id, path) is None: return {'error': _('Invalid path'), 'status': 400} if perm != 'r' and perm != 'rw': return {'error': _('Invalid folder permission'), 'status': 400} if not path.startswith('/'): return {'error': _('Path should start with "/"'), 'status': 400} if path != '/' and path.endswith('/'): return {'error': _('Path should NOT ends with "/"'), 'status': 400} try: user = User.objects.get(email=to_user) except User.DoesNotExist: user = None if user is None: return { 'error': _('Invalid username, should be a user already registered'), 'status': 400 } return {'success': True}
def thumbnail_get(request, repo_id, obj_id, size=THUMBNAIL_DEFAULT_SIZE): # permission check token = request.GET.get('t', None) path = request.GET.get('p', None) if token and path: fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare or not path.startswith(fileshare.path) or \ fileshare.repo_id != repo_id: # check if is valid download link share token and # if is a valid repo/dir belonged to this file share return HttpResponse() else: if not request.user.is_authenticated(): return HttpResponse() elif check_repo_access_permission(repo_id, request.user) is None: return HttpResponse() thumbnail_file = os.path.join(THUMBNAIL_ROOT, size, obj_id) with open(thumbnail_file, 'rb') as f: file_content = f.read() # Prepare response content_type, content_encoding = mimetypes.guess_type(thumbnail_file) response = HttpResponse(content=file_content, mimetype=content_type) if content_encoding: response['Content-Encoding'] = content_encoding return response
def download_file(request, repo_id, obj_id): """Download file. Arguments: - `request`: - `repo_id`: - `obj_id`: """ username = request.user.username repo = get_repo(repo_id) if not repo: raise Http404 if repo.encrypted and not seafile_api.is_password_set(repo_id, username): return HttpResponseRedirect(reverse('repo', args=[repo_id])) # If vistor's file shared token in url params matches the token in db, # then we know the vistor is from file shared link. share_token = request.GET.get('t', '') fileshare = FileShare.objects.get( token=share_token) if share_token else None shared_by = None if fileshare: from_shared_link = True shared_by = fileshare.username else: from_shared_link = False if from_shared_link: # check whether owner's traffic over the limit if user_traffic_over_limit(fileshare.username): messages.error( request, _(u'Unable to access file: share link traffic is used up.')) next = request.META.get('HTTP_REFERER', settings.SITE_ROOT) return HttpResponseRedirect(next) # Permission check and generate download link path = request.GET.get('p', '') if check_repo_access_permission(repo_id, request.user) or \ get_file_access_permission(repo_id, path, username) or from_shared_link: # Get a token to access file token = seafserv_rpc.web_get_access_token(repo_id, obj_id, 'download', username) else: messages.error(request, _(u'Unable to download file')) next = request.META.get('HTTP_REFERER', settings.SITE_ROOT) return HttpResponseRedirect(next) # send stats message if from_shared_link: try: file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) send_message( 'seahub.stats', 'file-download\t%s\t%s\t%s\t%s' % (repo.id, shared_by, obj_id, file_size)) except Exception, e: logger.error('Error when sending file-download message: %s' % str(e))
def rename_dirent(request, repo_id): """ Rename a file/dir in a repo, with ajax """ if request.method != 'POST' or not request.is_ajax(): raise Http404 result = {} username = request.user.username content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: result['error'] = _(u'Library does not exist.') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # permission checking if check_repo_access_permission(repo.id, request.user) != 'rw': result['error'] = _('Permission denied') return HttpResponse(json.dumps(result), status=403, content_type=content_type) # form validation form = RepoRenameDirentForm(request.POST) if form.is_valid(): oldname = form.cleaned_data["oldname"] newname = form.cleaned_data["newname"] else: result['error'] = str(form.errors.values()[0]) return HttpResponse(json.dumps(result), status=400, content_type=content_type) if newname == oldname: return HttpResponse(json.dumps({'success': True}), content_type=content_type) # argument checking parent_dir = request.GET.get('parent_dir', None) if not parent_dir: result['error'] = _('Argument missing') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # rename duplicate name newname = check_filename_with_rename(repo_id, parent_dir, newname) # rename file/dir try: seafile_api.rename_file(repo_id, parent_dir, oldname, newname, username) except SearpcError, e: result['error'] = str(e) return HttpResponse(json.dumps(result), status=500, content_type=content_type)
def check_group_folder_perm_args(request_user, repo_id, path, group_id, perm=None): if not seafile_api.get_repo(repo_id): return {'error': _(u'Library does not exist.'), 'status': 400} if check_repo_access_permission(repo_id, request_user) != 'rw': return {'error': _('Permission denied'), 'status': 403} if perm is not None: # add or toggle folder perm if seafile_api.get_dir_id_by_path(repo_id, path) is None: return {'error': _('Invalid path'), 'status': 400} if perm != 'r' and perm != 'rw': return {'error': _('Invalid folder permission'), 'status': 400} if not path.startswith('/'): return {'error': _('Path should start with "/"'), 'status': 400} if path != '/' and path.endswith('/'): return {'error': _('Path should NOT ends with "/"'), 'status': 400} if group_id and not seaserv.get_group(group_id): return {'error': _('Invalid group'), 'status': 400} return {'success': True}
def get_file_content_by_commit_and_path(request, repo_id, commit_id, path, file_enc): try: obj_id = seafserv_threaded_rpc.get_file_id_by_commit_and_path( \ repo_id, commit_id, path) except: return None, 'bad path' if not obj_id or obj_id == EMPTY_SHA1: return '', None else: permission = check_repo_access_permission(repo_id, request.user) if permission: # Get a token to visit file token = seafserv_rpc.web_get_access_token(repo_id, obj_id, 'view', request.user.username) else: return None, 'permission denied' filename = os.path.basename(path) inner_path = gen_inner_file_get_url(token, filename) try: err, file_content, encoding = repo_file_get(inner_path, file_enc) except Exception, e: return None, 'error when read file from fileserver: %s' % e return file_content, err
def get_upload_url(request, repo_id): username = request.user.username if check_repo_access_permission(repo_id, request.user) == "rw": token = seafile_api.get_fileserver_access_token(repo_id, "dummy", "upload", username) return gen_file_upload_url(token, "upload") else: return ""
def check_group_folder_perm_args(from_user, repo_id, path, group_id, perm = None): if not seafile_api.get_repo(repo_id): return {'error': _(u'Library does not exist.'), 'status': 400} if check_repo_access_permission(repo_id, from_user) != 'rw': return {'error': _('Permission denied'), 'status': 403} if perm is not None: # add or toggle folder perm if seafile_api.get_dir_id_by_path(repo_id, path) is None: return {'error': _('Invalid path'), 'status': 400} if perm != 'r' and perm != 'rw': return {'error': _('Invalid folder permission'), 'status': 400} if not path.startswith('/'): return {'error': _('Path should start with "/"'), 'status': 400} if path != '/' and path.endswith('/'): return {'error': _('Path should NOT ends with "/"'), 'status': 400} if not seaserv.get_group(group_id): return {'error': _('Invalid group'), 'status': 400} return {'success': True}
def check_user_folder_perm_args(from_user, repo_id, path, to_user, perm=None): if not seafile_api.get_repo(repo_id): return {'error': _(u'Library does not exist.'), 'status': 400} if check_repo_access_permission(repo_id, from_user) != 'rw': return {'error': _('Permission denied'), 'status': 403} if perm is not None: # add or toggle folder perm if seafile_api.get_dir_id_by_path(repo_id, path) is None: return {'error': _('Invalid path'), 'status': 400} if perm != 'r' and perm != 'rw': return {'error': _('Invalid folder permission'), 'status': 400} if not path.startswith('/'): return {'error': _('Path should start with "/"'), 'status': 400} if path != '/' and path.endswith('/'): return {'error': _('Path should NOT ends with "/"'), 'status': 400} try: user = User.objects.get(email = to_user) except User.DoesNotExist: user = None if user is None: return {'error': _('Invalid username, should be a user already registered'), 'status': 400} return {'success': True}
def get_upload_url(request, repo_id): username = request.user.username if check_repo_access_permission(repo_id, request.user) == 'rw': token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'upload', username) return gen_file_upload_url(token, 'upload') else: return ''
def get_upload_url(request, repo_id): username = request.user.username if check_repo_access_permission(repo_id, request.user) == 'rw': token = seafile_api.get_fileserver_access_token( repo_id, 'dummy', 'upload', username) return gen_file_upload_url(token, 'upload') else: return ''
def repo_history_view(request, repo_id): """View repo in history. """ repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username path = get_path_from_request(request) user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: return render_error(request, _(u'Permission denied')) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not is_password_set(repo.id, username): return render_to_response('decrypt_repo_form.html', { 'repo': repo, 'next': get_next_url_from_request(request) or reverse('repo', args=[repo.id]), 'force_server_crypto': FORCE_SERVER_CRYPTO, }, context_instance=RequestContext(request)) commit_id = request.GET.get('commit_id', None) if commit_id is None: return HttpResponseRedirect(reverse('repo', args=[repo.id])) current_commit = get_commit(repo.id, repo.version, commit_id) if not current_commit: current_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id) file_list, dir_list, dirent_more = get_repo_dirents( request, repo, current_commit, path) zipped = get_nav_path(path, repo.name) repo_owner = seafile_api.get_repo_owner(repo.id) is_repo_owner = True if username == repo_owner else False return render_to_response('repo_history_view.html', { 'repo': repo, "is_repo_owner": is_repo_owner, 'user_perm': user_perm, 'current_commit': current_commit, 'dir_list': dir_list, 'file_list': file_list, 'path': path, 'zipped': zipped, }, context_instance=RequestContext(request))
def repo_history_view(request, repo_id): """View repo in history. """ repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username path = get_path_from_request(request) user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: return render_to_response("repo_access_deny.html", {"repo": repo}, context_instance=RequestContext(request)) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if ( repo.encrypted and (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) and not is_password_set(repo.id, username) ): return render_to_response( "decrypt_repo_form.html", { "repo": repo, "next": get_next_url_from_request(request) or reverse("repo", args=[repo.id]), "force_server_crypto": FORCE_SERVER_CRYPTO, }, context_instance=RequestContext(request), ) commit_id = request.GET.get("commit_id", None) if commit_id is None: return HttpResponseRedirect(reverse("repo", args=[repo.id])) current_commit = get_commit(repo.id, repo.version, commit_id) if not current_commit: current_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id) file_list, dir_list = get_repo_dirents(request, repo, current_commit, path) zipped = get_nav_path(path, repo.name) return render_to_response( "repo_history_view.html", { "repo": repo, "user_perm": user_perm, "current_commit": current_commit, "dir_list": dir_list, "file_list": file_list, "path": path, "zipped": zipped, }, context_instance=RequestContext(request), )
def get_ajax_update_url(request, repo_id): """Get file upload url for AJAX. """ username = request.user.username if check_repo_access_permission(repo_id, request.user) == 'rw': token = seafile_api.get_httpserver_access_token(repo_id, 'dummy', 'update', username) return gen_file_upload_url(token, 'update-aj') else: return ''
def get_shared_upload_link(request): """ Handle ajax request to generate dir upload link. """ content_type = 'application/json; charset=utf-8' repo_id = request.GET.get('repo_id', '') path = request.GET.get('p', '') use_passwd = True if int(request.POST.get('use_passwd', '0')) == 1 else False passwd = request.POST.get('passwd') if use_passwd else None if not (repo_id and path): err = _('Invalid arguments') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) if path == '/': # can not share root dir err = _('You cannot share the library in this way.') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) else: if path[-1] != '/': # append '/' at end of path path += '/' repo = seaserv.get_repo(repo_id) user_perm = check_repo_access_permission(repo.id, request.user) if user_perm == 'r': messages.error(request, _(u'Permission denied')) return HttpResponse(status=403, content_type=content_type) elif user_perm == 'rw': l = UploadLinkShare.objects.filter(repo_id=repo_id).filter( username=request.user.username).filter(path=path) if len(l) > 0: upload_link = l[0] token = upload_link.token else: username = request.user.username uls = UploadLinkShare.objects.create_upload_link_share( username, repo_id, path, passwd) token = uls.token shared_upload_link = gen_shared_upload_link(token) data = json.dumps({ 'token': token, 'shared_upload_link': shared_upload_link }) return HttpResponse(data, status=200, content_type=content_type) else: messages.error(request, _(u'Operation failed')) return HttpResponse(json.dumps(), status=500, content_type=content_type)
def download_file(request, repo_id, obj_id): """Download file. Arguments: - `request`: - `repo_id`: - `obj_id`: """ username = request.user.username repo = get_repo(repo_id) if not repo: raise Http404 if repo.encrypted and not seafile_api.is_password_set(repo_id, username): return HttpResponseRedirect(reverse("repo", args=[repo_id])) # If vistor's file shared token in url params matches the token in db, # then we know the vistor is from file shared link. share_token = request.GET.get("t", "") fileshare = FileShare.objects.get(token=share_token) if share_token else None shared_by = None if fileshare: from_shared_link = True shared_by = fileshare.username else: from_shared_link = False if from_shared_link: # check whether owner's traffic over the limit if user_traffic_over_limit(fileshare.username): messages.error(request, _(u"Unable to access file: share link traffic is used up.")) next = request.META.get("HTTP_REFERER", settings.SITE_ROOT) return HttpResponseRedirect(next) # Permission check and generate download link path = request.GET.get("p", "") if ( check_repo_access_permission(repo_id, request.user) or get_file_access_permission(repo_id, path, username) or from_shared_link ): # Get a token to access file token = seafserv_rpc.web_get_access_token(repo_id, obj_id, "download", username) else: messages.error(request, _(u"Unable to download file")) next = request.META.get("HTTP_REFERER", settings.SITE_ROOT) return HttpResponseRedirect(next) # send stats message if from_shared_link: try: file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) send_message("seahub.stats", "file-download\t%s\t%s\t%s\t%s" % (repo.id, shared_by, obj_id, file_size)) except Exception, e: logger.error("Error when sending file-download message: %s" % str(e))
def get_blks_update_url(request, repo_id): ''' Get update url for encrypted file (uploaded in blocks) ''' username = request.user.username if check_repo_access_permission(repo_id, request.user) == 'rw': token = seafile_api.get_httpserver_access_token(repo_id, 'dummy', 'update-blks', username) return gen_file_upload_url(token, 'update-blks-aj') else: return ''
def repo_history_view(request, repo_id): """View repo in history. """ repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username path = get_path_from_request(request) user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: return render_to_response('repo_access_deny.html', { 'repo': repo, }, context_instance=RequestContext(request)) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not is_password_set(repo.id, username): return render_to_response('decrypt_repo_form.html', { 'repo': repo, 'next': get_next_url_from_request(request) or \ reverse('repo', args=[repo.id]), 'force_server_crypto': FORCE_SERVER_CRYPTO, }, context_instance=RequestContext(request)) commit_id = request.GET.get('commit_id', None) if commit_id is None: return HttpResponseRedirect(reverse('repo', args=[repo.id])) current_commit = get_commit(repo.id, repo.version, commit_id) if not current_commit: current_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id) file_list, dir_list = get_repo_dirents(request, repo, current_commit, path) zipped = get_nav_path(path, repo.name) search_repo_id = None if repo.encrypted else repo.id return render_to_response('repo_history_view.html', { 'repo': repo, 'user_perm': user_perm, 'current_commit': current_commit, 'dir_list': dir_list, 'file_list': file_list, 'path': path, 'zipped': zipped, 'search_repo_id': search_repo_id, }, context_instance=RequestContext(request))
def thumbnail_get(request, repo_id, obj_id, size=THUMBNAIL_DEFAULT_SIZE): permission = check_repo_access_permission(repo_id, request.user) if permission is None: raise Http404 thumbnail_file = os.path.join(THUMBNAIL_ROOT, size, obj_id) try: with open(thumbnail_file, 'rb') as f: thumbnail = f.read() f.close() return HttpResponse(thumbnail, 'image/' + THUMBNAIL_EXTENSION) except IOError: return HttpResponse()
def get_current_commit(request, repo_id): if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) if new_merge_with_no_conflict(head_commit): head_commit = get_commit_before_new_merge(head_commit) ctx = {'repo': repo, 'current_commit': head_commit} html = render_to_string('snippets/current_commit.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({'html': html}), content_type=content_type)
def get_shared_upload_link(request): """ Handle ajax request to generate dir upload link. """ content_type = 'application/json; charset=utf-8' repo_id = request.GET.get('repo_id', '') path = request.GET.get('p', '') use_passwd = True if int(request.POST.get('use_passwd', '0')) == 1 else False passwd = request.POST.get('passwd') if use_passwd else None if not (repo_id and path): err = _('Invalid arguments') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) if path == '/': # can not share root dir err = _('You cannot share the library in this way.') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) else: if path[-1] != '/': # append '/' at end of path path += '/' repo = seaserv.get_repo(repo_id) user_perm = check_repo_access_permission(repo.id, request.user) if user_perm == 'r': messages.error(request, _(u'Permission denied')) return HttpResponse(status=403, content_type=content_type) elif user_perm == 'rw': l = UploadLinkShare.objects.filter(repo_id=repo_id).filter( username=request.user.username).filter(path=path) if len(l) > 0: upload_link = l[0] token = upload_link.token else: username = request.user.username uls = UploadLinkShare.objects.create_upload_link_share( username, repo_id, path, passwd) token = uls.token shared_upload_link = gen_shared_upload_link(token) data = json.dumps({'token': token, 'shared_upload_link': shared_upload_link}) return HttpResponse(data, status=200, content_type=content_type) else: messages.error(request, _(u'Operation failed')) return HttpResponse(json.dumps(), status=500, content_type=content_type)
def get_current_commit(request, repo_id): if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) if new_merge_with_no_conflict(head_commit): head_commit = get_commit_before_new_merge(head_commit) ctx = { 'repo': repo, 'current_commit': head_commit } html = render_to_string('snippets/current_commit.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({'html': html}), content_type=content_type)
def get_dirents(request, repo_id): """ Get dirents in a dir for file tree """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' username = request.user.username # permission checking user_perm = check_repo_access_permission(repo_id, request.user) if user_perm is None: err_msg = _(u"You don't have permission to access the library.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) path = request.GET.get('path', '') dir_only = request.GET.get('dir_only', False) all_dir = request.GET.get('all_dir', False) if not path: err_msg = _(u"No path.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=400, content_type=content_type) # get dirents for every path element if all_dir: all_dirents = [] path_eles = path.split('/')[:-1] for i, x in enumerate(path_eles): ele_path = '/'.join(path_eles[:i + 1]) + '/' try: ele_path_dirents = seafile_api.list_dir_by_path( repo_id, ele_path.encode('utf-8')) except SearpcError, e: ele_path_dirents = [] ds = [] for d in ele_path_dirents: if stat.S_ISDIR(d.mode): ds.append(d.obj_name) all_dirents.append(ds) return HttpResponse(json.dumps(all_dirents), content_type=content_type)
def _decorated(request, repo_id, *args, **kwargs): if request.method != 'POST' or not request.is_ajax(): raise Http404 result = {} content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: result['error'] = _(u'Library does not exist.') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # permission checking username = request.user.username if check_repo_access_permission(repo.id, request.user) != 'rw': result['error'] = _('Permission denied') return HttpResponse(json.dumps(result), status=403, content_type=content_type) # form validation form = RepoNewDirentForm(request.POST) if form.is_valid(): dirent_name = form.cleaned_data["dirent_name"] else: result['error'] = str(form.errors.values()[0]) return HttpResponse(json.dumps(result), status=400, content_type=content_type) # arguments checking parent_dir = request.GET.get('parent_dir', None) if not parent_dir: result['error'] = _('Argument missing') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # rename duplicate name dirent_name = check_filename_with_rename(repo.id, parent_dir, dirent_name) return func(repo.id, parent_dir, dirent_name, username)
def delete_dirent(request, repo_id): """ Delete a file/dir with ajax. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) # permission checking username = request.user.username if check_repo_access_permission(repo.id, request.user) != 'rw': err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) # argument checking parent_dir = request.GET.get("parent_dir", None) dirent_name = request.GET.get("name", None) if not (parent_dir and dirent_name): err_msg = _(u'Argument missing.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) # delete file/dir try: seafile_api.del_file(repo_id, parent_dir, dirent_name, username) return HttpResponse(json.dumps({'success': True}), content_type=content_type) except SearpcError, e: logger.error(e) err_msg = _(u'Internal error. Failed to delete %s.') % dirent_name return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type)
def delete_dirents(request, repo_id): """ Delete multi files/dirs with ajax. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) # permission checking username = request.user.username if check_repo_access_permission(repo.id, request.user) != 'rw': err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) # argument checking parent_dir = request.GET.get("parent_dir") dirents_names = request.POST.getlist('dirents_names') if not (parent_dir and dirents_names): err_msg = _(u'Argument missing.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) deleted = [] undeleted = [] for dirent_name in dirents_names: try: seafile_api.del_file(repo_id, parent_dir, dirent_name, username) deleted.append(dirent_name) except SearpcError, e: logger.error(e) undeleted.append(dirent_name)
def get_dirents(request, repo_id): """ Get dirents in a dir for file tree """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' username = request.user.username # permission checking user_perm = check_repo_access_permission(repo_id, request.user) if user_perm is None: err_msg = _(u"You don't have permission to access the library.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) path = request.GET.get('path', '') dir_only = request.GET.get('dir_only', False) all_dir = request.GET.get('all_dir', False) if not path: err_msg = _(u"No path.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=400, content_type=content_type) # get dirents for every path element if all_dir: all_dirents = [] path_eles = path.split('/')[:-1] for i, x in enumerate(path_eles): ele_path = '/'.join(path_eles[:i+1]) + '/' try: ele_path_dirents = seafile_api.list_dir_by_path(repo_id, ele_path.encode('utf-8')) except SearpcError, e: ele_path_dirents = [] ds = [] for d in ele_path_dirents: if stat.S_ISDIR(d.mode): ds.append(d.obj_name) all_dirents.append(ds) return HttpResponse(json.dumps(all_dirents), content_type=content_type)
def get_file_view_path_and_perm(request, repo_id, obj_id, path): """ Get path and the permission to view file. Returns: outer fileserver file url, inner fileserver file url, permission """ username = request.user.username filename = os.path.basename(path) # user_perm = get_file_access_permission(repo_id, path, username) or \ # get_repo_access_permission(repo_id, username) user_perm = check_repo_access_permission(repo_id, request.user) if user_perm is None: return ('', '', user_perm) else: # Get a token to visit file token = web_get_access_token(repo_id, obj_id, 'view', username) outer_url = gen_file_get_url(token, filename) inner_url = gen_inner_file_get_url(token, filename) return (outer_url, inner_url, user_perm)
def thumbnail_get(request, repo_id, obj_id, size=THUMBNAIL_DEFAULT_SIZE): # permission check token = request.GET.get('t', None) path = request.GET.get('p', None) if token and path: fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare or fileshare.repo_id != repo_id: # check if is valid download link share token and # if is a valid repo/dir belonged to this file share return HttpResponse() else: if not request.user.is_authenticated(): return HttpResponse() elif check_repo_access_permission(repo_id, request.user) is None: return HttpResponse() thumbnail_file = os.path.join(THUMBNAIL_ROOT, size, obj_id) with open(thumbnail_file, 'rb') as f: file_content = f.read() return HttpResponse(content=file_content, mimetype='image/' + THUMBNAIL_EXTENSION)
def thumbnail_create(request, repo_id): content_type = 'application/json; charset=utf-8' result = {} if not request.is_ajax(): err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) if not ENABLE_THUMBNAIL: err_msg = _(u"Thumbnail function is not enabled.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) repo = get_repo(repo_id) if not repo: err_msg = _(u"Library does not exist.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) if repo.encrypted: err_msg = _(u"Image thumbnail is not supported in encrypted libraries.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) path = request.GET.get('path', None) obj_id = get_file_id_by_path(repo_id, path) if path is None or obj_id is None: err_msg = _(u"Wrong path.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) # permission check token = request.GET.get('t', None) if token: fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare or not path.startswith(fileshare.path) or \ fileshare.repo_id != repo_id: # check if is valid download link share token and # if is a valid repo/dir belonged to this file share err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) else: if not request.user.is_authenticated(): err_msg = _(u"Please login first.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) elif check_repo_access_permission(repo_id, request.user) is None: err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) # get image file from url size = request.GET.get('size', THUMBNAIL_DEFAULT_SIZE) file_name = os.path.basename(path) access_token = seafile_api.get_fileserver_access_token(repo_id, obj_id, 'view', request.user.username) raw_path = gen_file_get_url(access_token, file_name) open_file = urllib2.urlopen(raw_path) file_size = int(open_file.info()['Content-Length']) # image file size limit check if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2: err_msg = _(u"Image file is too large.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=520, content_type=content_type) thumbnail_dir = os.path.join(THUMBNAIL_ROOT, size) if not os.path.exists(thumbnail_dir): os.makedirs(thumbnail_dir) thumbnail_file = os.path.join(thumbnail_dir, obj_id) if not os.path.exists(thumbnail_file): try: f = StringIO(open_file.read()) image = Image.open(f) if image.mode not in ["1", "L", "P", "RGB", "RGBA"]: image = image.convert("RGB") image.thumbnail((int(size), int(size)), Image.ANTIALIAS) image.save(thumbnail_file, THUMBNAIL_EXTENSION) except Exception as e: logger.error(e) err_msg = _('Failed to create thumbnail.') return HttpResponse(json.dumps({'err_msg': err_msg}), status=500, content_type=content_type) result['thumbnail_src'] = get_thumbnail_src(repo_id, obj_id, size) return HttpResponse(json.dumps(result), content_type=content_type)
def file_edit_submit(request, repo_id): content_type = "application/json; charset=utf-8" def error_json(error_msg=_(u"Internal Error"), op=None): return HttpResponse(json.dumps({"error": error_msg, "op": op}), status=400, content_type=content_type) username = request.user.username if check_repo_access_permission(repo_id, request.user) != "rw": return error_json(_(u"Permission denied")) repo = get_repo(repo_id) if not repo: return error_json(_(u"The library does not exist.")) if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, username) if not repo.password_set: return error_json(_(u"The library is encrypted."), "decrypt") content = request.POST.get("content") encoding = request.POST.get("encoding") path = request.GET.get("p") if content is None or not path or encoding not in ["gbk", "utf-8"]: return error_json(_(u"Invalid arguments")) head_id = request.GET.get("head", None) content = content.encode(encoding) # first dump the file content to a tmp file, then update the file fd, tmpfile = mkstemp() def remove_tmp_file(): try: os.remove(tmpfile) except: pass try: bytesWritten = os.write(fd, content) except: bytesWritten = -1 finally: os.close(fd) if bytesWritten != len(content): remove_tmp_file() return error_json() req_from = request.GET.get("from", "") if req_from == "wiki_page_edit" or req_from == "wiki_page_new": try: gid = int(request.GET.get("gid", 0)) except ValueError: gid = 0 wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse("group_wiki", args=[gid, wiki_name]) elif req_from == "personal_wiki_page_edit" or req_from == "personal_wiki_page_new": wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse("personal_wiki", args=[wiki_name]) else: next = reverse("repo_view_file", args=[repo_id]) + "?p=" + urlquote(path) parent_dir = os.path.dirname(path).encode("utf-8") filename = os.path.basename(path).encode("utf-8") try: seafserv_threaded_rpc.put_file(repo_id, tmpfile, parent_dir, filename, username, head_id) remove_tmp_file() return HttpResponse(json.dumps({"href": next}), content_type=content_type) except SearpcError, e: remove_tmp_file() return error_json(str(e))
def file_edit(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 if request.method == "POST": return file_edit_submit(request, repo_id) if check_repo_access_permission(repo_id, request.user) != "rw": return render_permission_error(request, _(u"Unable to edit file")) path = request.GET.get("p", "/") if path[-1] == "/": path = path[:-1] u_filename = os.path.basename(path) filename = urllib2.quote(u_filename.encode("utf-8")) head_id = repo.head_cmmt_id obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u"The file does not exist.")) token = web_get_access_token(repo_id, obj_id, "view", request.user.username) # generate path and link zipped = gen_path_link(path, repo.name) filetype, fileext = get_file_type_and_ext(filename) op = None err = "" file_content = None encoding = None file_encoding_list = FILE_ENCODING_LIST if filetype == TEXT or filetype == MARKDOWN or filetype == SF: if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, request.user.username) if not repo.password_set: op = "decrypt" if not op: inner_path = gen_inner_file_get_url(token, filename) file_enc = request.GET.get("file_enc", "auto") if not file_enc in FILE_ENCODING_LIST: file_enc = "auto" err, file_content, encoding = repo_file_get(inner_path, file_enc) if encoding and encoding not in FILE_ENCODING_LIST: file_encoding_list.append(encoding) else: err = _(u"Edit online is not offered for this type of file.") # Redirect to different place according to from page when user click # cancel button on file edit page. cancel_url = reverse("repo_view_file", args=[repo.id]) + "?p=" + urlquote(path) page_from = request.GET.get("from", "") gid = request.GET.get("gid", "") wiki_name = os.path.splitext(u_filename)[0] if page_from == "wiki_page_edit" or page_from == "wiki_page_new": cancel_url = reverse("group_wiki", args=[gid, wiki_name]) elif page_from == "personal_wiki_page_edit" or page_from == "personal_wiki_page_new": cancel_url = reverse("personal_wiki", args=[wiki_name]) return render_to_response( "file_edit.html", { "repo": repo, "u_filename": u_filename, "wiki_name": wiki_name, "path": path, "zipped": zipped, "filetype": filetype, "fileext": fileext, "op": op, "err": err, "file_content": file_content, "encoding": encoding, "file_encoding_list": file_encoding_list, "head_id": head_id, "from": page_from, "gid": gid, "cancel_url": cancel_url, }, context_instance=RequestContext(request), )
def render_repo(request, repo): """Steps to show repo page: If user has permission to view repo If repo is encrypt and password is not set on server return decrypt repo page If repo is not encrypt or password is set on server Show repo direntries based on requested path If user does not have permission to view repo return permission deny page """ username = request.user.username path = get_path_from_request(request) user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: return render_to_response('repo_access_deny.html', { 'repo': repo, }, context_instance=RequestContext(request)) sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username) server_crypto = False if repo.encrypted: try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: return render_to_response('options/set_user_options.html', { }, context_instance=RequestContext(request)) if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not is_password_set(repo.id, username): return render_to_response('decrypt_repo_form.html', { 'repo': repo, 'next': get_next_url_from_request(request) or \ reverse('repo', args=[repo.id]), 'force_server_crypto': FORCE_SERVER_CRYPTO, }, context_instance=RequestContext(request)) # query context args applet_root = get_ccnetapplet_root() httpserver_root = get_httpserver_root() max_upload_file_size = get_max_upload_file_size() protocol = request.is_secure() and 'https' or 'http' domain = RequestSite(request).domain contacts = Contact.objects.get_contacts_by_user(username) joined_groups = get_personal_groups_by_user(request.user.username) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: raise Http404 repo_size = get_repo_size(repo.id) no_quota = is_no_quota(repo.id) search_repo_id = None if repo.encrypted else repo.id repo_owner = seafile_api.get_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False more_start = None file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset=0, limit=100) if dirent_more: more_start = 100 zipped = get_nav_path(path, repo.name) repo_groups = get_shared_groups_by_repo_and_user(repo.id, username) if len(repo_groups) > 1: repo_group_str = render_to_string("snippets/repo_group_list.html", {'groups': repo_groups}) else: repo_group_str = '' upload_url = get_upload_url(request, repo.id) if repo.encrypted and repo.enc_version == 2 and not server_crypto: ajax_upload_url = get_blks_upload_url(request, repo.id) ajax_update_url = get_blks_update_url(request, repo.id) else: ajax_upload_url = get_ajax_upload_url(request, repo.id) ajax_update_url = get_ajax_update_url(request, repo.id) fileshare = get_fileshare(repo.id, username, path) dir_shared_link = get_dir_share_link(fileshare) uploadlink = get_uploadlink(repo.id, username, path) dir_shared_upload_link = get_dir_shared_upload_link(uploadlink) return render_to_response('repo.html', { 'repo': repo, 'user_perm': user_perm, 'repo_owner': repo_owner, 'is_repo_owner': is_repo_owner, 'current_commit': head_commit, 'password_set': True, 'repo_size': repo_size, 'dir_list': dir_list, 'file_list': file_list, 'dirent_more': dirent_more, 'more_start': more_start, 'path': path, 'zipped': zipped, 'applet_root': applet_root, 'groups': repo_groups, 'joined_groups': joined_groups, 'repo_group_str': repo_group_str, 'no_quota': no_quota, 'max_upload_file_size': max_upload_file_size, 'upload_url': upload_url, 'ajax_upload_url': ajax_upload_url, 'ajax_update_url': ajax_update_url, 'httpserver_root': httpserver_root, 'protocol': protocol, 'domain': domain, 'contacts': contacts, 'fileshare': fileshare, 'dir_shared_link': dir_shared_link, 'uploadlink': uploadlink, 'dir_shared_upload_link': dir_shared_upload_link, 'search_repo_id': search_repo_id, 'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY, 'server_crypto': server_crypto, "sub_lib_enabled": sub_lib_enabled, }, context_instance=RequestContext(request))
def render_repo(request, repo): """Steps to show repo page: If user has permission to view repo If repo is encrypt and password is not set on server return decrypt repo page If repo is not encrypt or password is set on server Show repo direntries based on requested path If user does not have permission to view repo return permission deny page """ username = request.user.username path = get_path_from_request(request) user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: return render_error(request, _(u'Permission denied')) sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username) server_crypto = False if repo.encrypted: try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: return render_to_response('options/set_user_options.html', {}, context_instance=RequestContext(request)) if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not is_password_set(repo.id, username): return render_to_response('decrypt_repo_form.html', { 'repo': repo, 'next': get_next_url_from_request(request) or reverse('repo', args=[repo.id]), 'force_server_crypto': FORCE_SERVER_CRYPTO, }, context_instance=RequestContext(request)) # query context args fileserver_root = get_fileserver_root() max_upload_file_size = get_max_upload_file_size() protocol = request.is_secure() and 'https' or 'http' domain = RequestSite(request).domain for g in request.user.joined_groups: g.avatar = grp_avatar(g.id, 20) head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id) if not head_commit: raise Http404 if new_merge_with_no_conflict(head_commit): info_commit = get_commit_before_new_merge(head_commit) else: info_commit = head_commit repo_size = get_repo_size(repo.id) no_quota = is_no_quota(repo.id) 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) is_repo_owner = True if repo_owner == username else False if is_repo_owner and not repo.is_virtual: show_repo_settings = True else: show_repo_settings = False file_list, dir_list, dirent_more = get_repo_dirents_with_perm(request, repo, head_commit, path, offset=0, limit=100) more_start = None if dirent_more: more_start = 100 zipped = get_nav_path(path, repo.name) repo_groups = get_shared_groups_by_repo_and_user(repo.id, username) if len(repo_groups) > 1: repo_group_str = render_to_string("snippets/repo_group_list.html", {'groups': repo_groups}) else: repo_group_str = '' fileshare = get_fileshare(repo.id, username, path) dir_shared_link = get_dir_share_link(fileshare) uploadlink = get_uploadlink(repo.id, username, path) dir_shared_upload_link = get_dir_shared_upload_link(uploadlink) for f in file_list: file_path = posixpath.join(path, f.obj_name) if allow_generate_thumbnail(request, repo.id, file_path): f.allow_generate_thumbnail = True if os.path.exists( os.path.join(THUMBNAIL_ROOT, str(THUMBNAIL_DEFAULT_SIZE), f.obj_id)): src = get_thumbnail_src(repo.id, THUMBNAIL_DEFAULT_SIZE, file_path) f.encoded_thumbnail_src = urlquote(src) return render_to_response('repo.html', { 'repo': repo, 'user_perm': user_perm, 'repo_owner': repo_owner, 'is_repo_owner': is_repo_owner, 'show_repo_settings': show_repo_settings, 'current_commit': head_commit, 'info_commit': info_commit, 'password_set': True, 'repo_size': repo_size, 'dir_list': dir_list, 'file_list': file_list, 'dirent_more': dirent_more, 'more_start': more_start, 'path': path, 'zipped': zipped, 'groups': repo_groups, 'repo_group_str': repo_group_str, 'no_quota': no_quota, 'max_upload_file_size': max_upload_file_size, 'fileserver_root': fileserver_root, 'protocol': protocol, 'domain': domain, 'fileshare': fileshare, 'dir_shared_link': dir_shared_link, 'uploadlink': uploadlink, 'dir_shared_upload_link': dir_shared_upload_link, 'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY, 'server_crypto': server_crypto, 'sub_lib_enabled': sub_lib_enabled, 'enable_upload_folder': ENABLE_UPLOAD_FOLDER, 'ENABLE_THUMBNAIL': ENABLE_THUMBNAIL, }, context_instance=RequestContext(request))
def render_repo(request, repo): """Steps to show repo page: If user has permission to view repo If repo is encrypt and password is not set on server return decrypt repo page If repo is not encrypt or password is set on server Show repo direntries based on requested path If user does not have permission to view repo return permission deny page """ username = request.user.username path = get_path_from_request(request) user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: return render_to_response('repo_access_deny.html', { 'repo': repo, }, context_instance=RequestContext(request)) sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username) server_crypto = False if repo.encrypted: try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: return render_to_response('options/set_user_options.html', { }, context_instance=RequestContext(request)) if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not is_password_set(repo.id, username): return render_to_response('decrypt_repo_form.html', { 'repo': repo, 'next': get_next_url_from_request(request) or \ reverse('repo', args=[repo.id]), 'force_server_crypto': FORCE_SERVER_CRYPTO, }, context_instance=RequestContext(request)) # query context args fileserver_root = get_fileserver_root() max_upload_file_size = get_max_upload_file_size() protocol = request.is_secure() and 'https' or 'http' domain = RequestSite(request).domain for g in request.user.joined_groups: g.avatar = grp_avatar(g.id, 20) head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id) if not head_commit: raise Http404 if new_merge_with_no_conflict(head_commit): info_commit = get_commit_before_new_merge(head_commit) else: info_commit = head_commit repo_size = get_repo_size(repo.id) no_quota = is_no_quota(repo.id) 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) is_repo_owner = True if repo_owner == username else False if is_repo_owner and not repo.is_virtual: show_repo_settings = True else: show_repo_settings = False more_start = None file_list, dir_list, dirent_more = get_repo_dirents(request, repo, head_commit, path, offset=0, limit=100) if dirent_more: more_start = 100 zipped = get_nav_path(path, repo.name) repo_groups = get_shared_groups_by_repo_and_user(repo.id, username) if len(repo_groups) > 1: repo_group_str = render_to_string("snippets/repo_group_list.html", {'groups': repo_groups}) else: repo_group_str = '' upload_url = get_upload_url(request, repo.id) fileshare = get_fileshare(repo.id, username, path) dir_shared_link = get_dir_share_link(fileshare) uploadlink = get_uploadlink(repo.id, username, path) dir_shared_upload_link = get_dir_shared_upload_link(uploadlink) return render_to_response('repo.html', { 'repo': repo, 'user_perm': user_perm, 'repo_owner': repo_owner, 'is_repo_owner': is_repo_owner, 'show_repo_settings': show_repo_settings, 'current_commit': head_commit, 'info_commit': info_commit, 'password_set': True, 'repo_size': repo_size, 'dir_list': dir_list, 'file_list': file_list, 'dirent_more': dirent_more, 'more_start': more_start, 'path': path, 'zipped': zipped, 'groups': repo_groups, 'repo_group_str': repo_group_str, 'no_quota': no_quota, 'max_upload_file_size': max_upload_file_size, 'upload_url': upload_url, 'fileserver_root': fileserver_root, 'protocol': protocol, 'domain': domain, 'fileshare': fileshare, 'dir_shared_link': dir_shared_link, 'uploadlink': uploadlink, 'dir_shared_upload_link': dir_shared_upload_link, 'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY, 'server_crypto': server_crypto, "sub_lib_enabled": sub_lib_enabled, }, context_instance=RequestContext(request))
def list_dir_more(request, repo_id): """ List 'more' entries in a directory with AJAX. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) path = request.GET.get('p', '/') if path[-1] != '/': path = path + '/' offset = int(request.GET.get('start')) if not offset: err_msg = _(u'Argument missing') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) more_start = None file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset, limit=100) if dirent_more: more_start = offset + 100 ctx = { 'repo': repo, 'user_perm': user_perm, 'path': path, 'server_crypto': server_crypto, 'dir_list': dir_list, 'file_list': file_list, 'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY, "sub_lib_enabled": sub_lib_enabled, } html = render_to_string('snippets/repo_dirents.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({ 'html': html, 'dirent_more': dirent_more, 'more_start': more_start }), content_type=content_type)
def file_edit_submit(request, repo_id): content_type = 'application/json; charset=utf-8' def error_json(error_msg=_(u'Internal Error'), op=None): return HttpResponse(json.dumps({ 'error': error_msg, 'op': op }), status=400, content_type=content_type) username = request.user.username if check_repo_access_permission(repo_id, request.user) != 'rw': return error_json(_(u'Permission denied')) repo = get_repo(repo_id) if not repo: return error_json(_(u'The library does not exist.')) if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, username) if not repo.password_set: return error_json(_(u'The library is encrypted.'), 'decrypt') content = request.POST.get('content') encoding = request.POST.get('encoding') path = request.GET.get('p') if content is None or not path or encoding not in ["gbk", "utf-8"]: return error_json(_(u'Invalid arguments')) head_id = request.GET.get('head', None) content = content.encode(encoding) # first dump the file content to a tmp file, then update the file fd, tmpfile = mkstemp() def remove_tmp_file(): try: os.remove(tmpfile) except: pass try: bytesWritten = os.write(fd, content) except: bytesWritten = -1 finally: os.close(fd) if bytesWritten != len(content): remove_tmp_file() return error_json() req_from = request.GET.get('from', '') if req_from == 'wiki_page_edit' or req_from == 'wiki_page_new': try: gid = int(request.GET.get('gid', 0)) except ValueError: gid = 0 wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse('group_wiki', args=[gid, wiki_name]) elif req_from == 'personal_wiki_page_edit' or req_from == 'personal_wiki_page_new': wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse('personal_wiki', args=[wiki_name]) else: next = reverse('repo_view_file', args=[repo_id ]) + '?p=' + urlquote(path) parent_dir = os.path.dirname(path).encode('utf-8') filename = os.path.basename(path).encode('utf-8') try: seafserv_threaded_rpc.put_file(repo_id, tmpfile, parent_dir, filename, username, head_id) remove_tmp_file() return HttpResponse(json.dumps({'href': next}), content_type=content_type) except SearpcError, e: remove_tmp_file() return error_json(str(e))
def file_edit(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 if request.method == 'POST': return file_edit_submit(request, repo_id) if check_repo_access_permission(repo_id, request.user) != 'rw': return render_permission_error(request, _(u'Unable to edit file')) path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) filename = urllib2.quote(u_filename.encode('utf-8')) head_id = repo.head_cmmt_id obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'The file does not exist.')) token = web_get_access_token(repo_id, obj_id, 'view', request.user.username) # generate path and link zipped = gen_path_link(path, repo.name) filetype, fileext = get_file_type_and_ext(filename) op = None err = '' file_content = None encoding = None file_encoding_list = FILE_ENCODING_LIST if filetype == TEXT or filetype == MARKDOWN or filetype == SF: if repo.encrypted: repo.password_set = seafile_api.is_password_set( repo_id, request.user.username) if not repo.password_set: op = 'decrypt' if not op: inner_path = gen_inner_file_get_url(token, filename) file_enc = request.GET.get('file_enc', 'auto') if not file_enc in FILE_ENCODING_LIST: file_enc = 'auto' err, file_content, encoding = repo_file_get(inner_path, file_enc) if encoding and encoding not in FILE_ENCODING_LIST: file_encoding_list.append(encoding) else: err = _(u'Edit online is not offered for this type of file.') # Redirect to different place according to from page when user click # cancel button on file edit page. cancel_url = reverse('repo_view_file', args=[repo.id ]) + '?p=' + urlquote(path) page_from = request.GET.get('from', '') gid = request.GET.get('gid', '') wiki_name = os.path.splitext(u_filename)[0] if page_from == 'wiki_page_edit' or page_from == 'wiki_page_new': cancel_url = reverse('group_wiki', args=[gid, wiki_name]) elif page_from == 'personal_wiki_page_edit' or page_from == 'personal_wiki_page_new': cancel_url = reverse('personal_wiki', args=[wiki_name]) return render_to_response('file_edit.html', { 'repo': repo, 'u_filename': u_filename, 'wiki_name': wiki_name, 'path': path, 'zipped': zipped, 'filetype': filetype, 'fileext': fileext, 'op': op, 'err': err, 'file_content': file_content, 'encoding': encoding, 'file_encoding_list': file_encoding_list, 'head_id': head_id, 'from': page_from, 'gid': gid, 'cancel_url': cancel_url, }, context_instance=RequestContext(request))
def thumbnail_create(request, repo_id): content_type = 'application/json; charset=utf-8' result = {} if not request.is_ajax(): err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) if not ENABLE_THUMBNAIL: err_msg = _(u"Thumbnail function is not enabled.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) repo = get_repo(repo_id) if not repo: err_msg = _(u"Library does not exist.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) if repo.encrypted: err_msg = _( u"Image thumbnail is not supported in encrypted libraries.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) path = request.GET.get('path', None) obj_id = get_file_id_by_path(repo_id, path) if path is None or obj_id is None: err_msg = _(u"Wrong path.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) # permission check token = request.GET.get('t', None) if token: fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare or not path.startswith(fileshare.path) or \ fileshare.repo_id != repo_id: # check if is valid download link share token and # if is a valid repo/dir belonged to this file share err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) else: if not request.user.is_authenticated(): err_msg = _(u"Please login first.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) elif check_repo_access_permission(repo_id, request.user) is None: err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) # get image file from url size = request.GET.get('size', THUMBNAIL_DEFAULT_SIZE) file_name = os.path.basename(path) access_token = seafile_api.get_fileserver_access_token( repo_id, obj_id, 'view', request.user.username) raw_path = gen_file_get_url(access_token, file_name) open_file = urllib2.urlopen(raw_path) file_size = int(open_file.info()['Content-Length']) # image file size limit check if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2: err_msg = _(u"Image file is too large.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=520, content_type=content_type) thumbnail_dir = os.path.join(THUMBNAIL_ROOT, size) if not os.path.exists(thumbnail_dir): os.makedirs(thumbnail_dir) thumbnail_file = os.path.join(thumbnail_dir, obj_id) if not os.path.exists(thumbnail_file): try: f = StringIO(open_file.read()) image = Image.open(f) if image.mode not in ["1", "L", "P", "RGB", "RGBA"]: image = image.convert("RGB") image.thumbnail((int(size), int(size)), Image.ANTIALIAS) image.save(thumbnail_file, THUMBNAIL_EXTENSION) except Exception as e: logger.error(e) err_msg = _('Failed to create thumbnail.') return HttpResponse(json.dumps({'err_msg': err_msg}), status=500, content_type=content_type) result['thumbnail_src'] = get_thumbnail_src(repo_id, obj_id, size) return HttpResponse(json.dumps(result), content_type=content_type)
def render_repo(request, repo): """Steps to show repo page: If user has permission to view repo If repo is encrypt and password is not set on server return decrypt repo page If repo is not encrypt or password is set on server Show repo direntries based on requested path If user does not have permission to view repo return permission deny page """ username = request.user.username path = get_path_from_request(request) user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: return render_to_response("repo_access_deny.html", {"repo": repo}, context_instance=RequestContext(request)) sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username) server_crypto = False if repo.encrypted: try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: return render_to_response("options/set_user_options.html", {}, context_instance=RequestContext(request)) if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) and not is_password_set( repo.id, username ): return render_to_response( "decrypt_repo_form.html", { "repo": repo, "next": get_next_url_from_request(request) or reverse("repo", args=[repo.id]), "force_server_crypto": FORCE_SERVER_CRYPTO, }, context_instance=RequestContext(request), ) # query context args fileserver_root = get_fileserver_root() max_upload_file_size = get_max_upload_file_size() protocol = request.is_secure() and "https" or "http" domain = RequestSite(request).domain for g in request.user.joined_groups: g.avatar = grp_avatar(g.id, 20) head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id) if not head_commit: raise Http404 if new_merge_with_no_conflict(head_commit): info_commit = get_commit_before_new_merge(head_commit) else: info_commit = head_commit repo_size = get_repo_size(repo.id) no_quota = is_no_quota(repo.id) 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) is_repo_owner = True if repo_owner == username else False if is_repo_owner and not repo.is_virtual: show_repo_settings = True else: show_repo_settings = False more_start = None file_list, dir_list, dirent_more = get_repo_dirents(request, repo, head_commit, path, offset=0, limit=100) if dirent_more: more_start = 100 zipped = get_nav_path(path, repo.name) repo_groups = get_shared_groups_by_repo_and_user(repo.id, username) if len(repo_groups) > 1: repo_group_str = render_to_string("snippets/repo_group_list.html", {"groups": repo_groups}) else: repo_group_str = "" upload_url = get_upload_url(request, repo.id) fileshare = get_fileshare(repo.id, username, path) dir_shared_link = get_dir_share_link(fileshare) uploadlink = get_uploadlink(repo.id, username, path) dir_shared_upload_link = get_dir_shared_upload_link(uploadlink) return render_to_response( "repo.html", { "repo": repo, "user_perm": user_perm, "repo_owner": repo_owner, "is_repo_owner": is_repo_owner, "show_repo_settings": show_repo_settings, "current_commit": head_commit, "info_commit": info_commit, "password_set": True, "repo_size": repo_size, "dir_list": dir_list, "file_list": file_list, "dirent_more": dirent_more, "more_start": more_start, "path": path, "zipped": zipped, "groups": repo_groups, "repo_group_str": repo_group_str, "no_quota": no_quota, "max_upload_file_size": max_upload_file_size, "upload_url": upload_url, "fileserver_root": fileserver_root, "protocol": protocol, "domain": domain, "fileshare": fileshare, "dir_shared_link": dir_shared_link, "uploadlink": uploadlink, "dir_shared_upload_link": dir_shared_upload_link, "ENABLE_SUB_LIBRARY": ENABLE_SUB_LIBRARY, "server_crypto": server_crypto, "sub_lib_enabled": sub_lib_enabled, }, context_instance=RequestContext(request), )
def list_dir_more(request, repo_id): """ List 'more' entries in a directory with AJAX. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) path = request.GET.get('p', '/') if path[-1] != '/': path = path + '/' offset = int(request.GET.get('start')) if not offset: err_msg = _(u'Argument missing') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) more_start = None file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset, limit=100) if dirent_more: more_start = offset + 100 ctx = { 'repo': repo, 'user_perm': user_perm, 'path': path, 'server_crypto': server_crypto, 'dir_list': dir_list, 'file_list': file_list, 'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY, "sub_lib_enabled": sub_lib_enabled, } html = render_to_string('snippets/repo_dirents.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({'html': html, 'dirent_more': dirent_more, 'more_start': more_start}), content_type=content_type)
def file_edit_submit(request, repo_id): content_type = 'application/json; charset=utf-8' def error_json(error_msg=_(u'Internal Error'), op=None): return HttpResponse(json.dumps({'error': error_msg, 'op': op}), status=400, content_type=content_type) username = request.user.username if check_repo_access_permission(repo_id, request.user) != 'rw': return error_json(_(u'Permission denied')) repo = get_repo(repo_id) if not repo: return error_json(_(u'The library does not exist.')) if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, username) if not repo.password_set: return error_json(_(u'The library is encrypted.'), 'decrypt') content = request.POST.get('content') encoding = request.POST.get('encoding') path = request.GET.get('p') if content is None or not path or encoding not in ["gbk", "utf-8"]: return error_json(_(u'Invalid arguments')) head_id = request.GET.get('head', None) content = content.encode(encoding) # first dump the file content to a tmp file, then update the file fd, tmpfile = mkstemp() def remove_tmp_file(): try: os.remove(tmpfile) except: pass try: bytesWritten = os.write(fd, content) except: bytesWritten = -1 finally: os.close(fd) if bytesWritten != len(content): remove_tmp_file() return error_json() req_from = request.GET.get('from', '') if req_from == 'wiki_page_edit' or req_from == 'wiki_page_new': try: gid = int(request.GET.get('gid', 0)) except ValueError: gid = 0 wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse('group_wiki', args=[gid, wiki_name]) elif req_from == 'personal_wiki_page_edit' or req_from == 'personal_wiki_page_new': wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse('personal_wiki', args=[wiki_name]) else: next = reverse('repo_view_file', args=[repo_id]) + '?p=' + urlquote(path) parent_dir = os.path.dirname(path).encode('utf-8') filename = os.path.basename(path).encode('utf-8') try: seafserv_threaded_rpc.put_file(repo_id, tmpfile, parent_dir, filename, username, head_id) remove_tmp_file() return HttpResponse(json.dumps({'href': next}), content_type=content_type) except SearpcError, e: remove_tmp_file() return error_json(str(e))
def file_edit(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 if request.method == 'POST': return file_edit_submit(request, repo_id) if check_repo_access_permission(repo_id, request.user) != 'rw': return render_permission_error(request, _(u'Unable to edit file')) path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) filename = urllib2.quote(u_filename.encode('utf-8')) head_id = repo.head_cmmt_id obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'The file does not exist.')) token = web_get_access_token(repo_id, obj_id, 'view', request.user.username) # generate path and link zipped = gen_path_link(path, repo.name) filetype, fileext = get_file_type_and_ext(filename) op = None err = '' file_content = None encoding = None file_encoding_list = FILE_ENCODING_LIST if filetype == TEXT or filetype == MARKDOWN or filetype == SF: if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, request.user.username) if not repo.password_set: op = 'decrypt' if not op: inner_path = gen_inner_file_get_url(token, filename) file_enc = request.GET.get('file_enc', 'auto') if not file_enc in FILE_ENCODING_LIST: file_enc = 'auto' err, file_content, encoding = repo_file_get(inner_path, file_enc) if encoding and encoding not in FILE_ENCODING_LIST: file_encoding_list.append(encoding) else: err = _(u'Edit online is not offered for this type of file.') # Redirect to different place according to from page when user click # cancel button on file edit page. cancel_url = reverse('repo_view_file', args=[repo.id]) + '?p=' + urlquote(path) page_from = request.GET.get('from', '') gid = request.GET.get('gid', '') wiki_name = os.path.splitext(u_filename)[0] if page_from == 'wiki_page_edit' or page_from == 'wiki_page_new': cancel_url = reverse('group_wiki', args=[gid, wiki_name]) elif page_from == 'personal_wiki_page_edit' or page_from == 'personal_wiki_page_new': cancel_url = reverse('personal_wiki', args=[wiki_name]) return render_to_response('file_edit.html', { 'repo':repo, 'u_filename':u_filename, 'wiki_name': wiki_name, 'path':path, 'zipped':zipped, 'filetype':filetype, 'fileext':fileext, 'op':op, 'err':err, 'file_content':file_content, 'encoding': encoding, 'file_encoding_list':file_encoding_list, 'head_id': head_id, 'from': page_from, 'gid': gid, 'cancel_url': cancel_url, }, context_instance=RequestContext(request))