def group_wiki_pages(request, group): """ List wiki pages in group. """ username = request.user.username try: repo = get_group_wiki_repo(group, username) pages = get_wiki_pages(repo) except SearpcError: return render_error(request, _("Internal Server Error")) except WikiDoesNotExist: return render_error(request, _("Wiki does not exists.")) repo_perm = seafile_api.check_repo_access_permission(repo.id, username) mods_available = get_available_mods_by_group(group.id) mods_enabled = get_enabled_mods_by_group(group.id) return render_to_response( "group/group_wiki_pages.html", { "group": group, "pages": pages, "is_staff": group.is_staff, "repo_id": repo.id, "search_repo_id": repo.id, "search_wiki": True, "repo_perm": repo_perm, "mods_enabled": mods_enabled, "mods_available": mods_available, }, context_instance=RequestContext(request), )
def personal_wiki_page_new(request, page_name="home"): if request.method == 'POST': page_name = request.POST.get('page_name', '') if not page_name: return HttpResponseRedirect(request.META.get('HTTP_REFERER')) page_name = clean_page_name(page_name) try: repo = get_personal_wiki_repo(request.user.username) except WikiDoesNotExist: return render_error(request, _('Wiki is not found.')) filename = page_name + ".md" filepath = "/" + page_name + ".md" # check whether file exists if seaserv.get_file_id_by_path(repo.id, filepath): return render_error(request, _('Page "%s" already exists.') % filename) if not seaserv.post_empty_file(repo.id, "/", filename, request.user.username): return render_error(request, _('Failed to create wiki page. Please retry later.')) url = "%s?p=%s&from=personal_wiki_page_new" % ( reverse('file_edit', args=[repo.id]), urlquote(filepath.encode('utf-8'))) return HttpResponseRedirect(url)
def group_wiki_page_new(request, group, page_name="home"): if group.view_perm == "pub": raise Http404 if request.method == "POST": form = MessageForm(request.POST) page_name = request.POST.get("page_name", "") if not page_name: return HttpResponseRedirect(request.META.get("HTTP_REFERER")) page_name = clean_page_name(page_name) try: repo = get_group_wiki_repo(group, request.user.username) except WikiDoesNotExist: return render_error(request, _("Wiki is not found.")) filename = page_name + ".md" filepath = "/" + page_name + ".md" # check whether file exists if get_file_id_by_path(repo.id, filepath): return render_error(request, _('Page "%s" already exists.') % filename) if not post_empty_file(repo.id, "/", filename, request.user.username): return render_error(request, _("Failed to create wiki page. Please retry later.")) url = "%s?p=%s&from=wiki_page_new&gid=%s" % ( reverse("file_edit", args=[repo.id]), urllib2.quote(filepath.encode("utf-8")), group.id, ) return HttpResponseRedirect(url)
def personal_wiki_pages(request): """ List personal wiki pages. """ username = request.user.username if request.cloud_mode and request.user.org is not None: org_id = request.user.org.org_id joined_groups = seaserv.get_org_groups_by_user(org_id, username) else: joined_groups = seaserv.get_personal_groups_by_user(username) if joined_groups: joined_groups.sort(lambda x, y: cmp(x.group_name.lower(), y.group_name.lower())) try: repo = get_personal_wiki_repo(username) pages = get_wiki_pages(repo) except SearpcError: return render_error(request, _('Internal Server Error')) except WikiDoesNotExist: return render_error(request, _('Wiki does not exists.')) return render_to_response("wiki/personal_wiki_pages.html", { "pages": pages, "repo_id": repo.id, "search_repo_id": repo.id, "search_wiki": True, "grps": joined_groups, }, context_instance=RequestContext(request))
def group_wiki_pages(request, group): """ List wiki pages in group. """ username = request.user.username try: repo = get_group_wiki_repo(group, username) pages = get_wiki_pages(repo) except SearpcError: return render_error(request, _('Internal Server Error')) except WikiDoesNotExist: return render_error(request, _('Wiki does not exists.')) if is_registered_user(username): repo_perm = seafile_api.check_permission_by_path(repo.id, '/', username) else: # when anonymous user visit public group wiki, set permission as 'r' repo_perm = 'r' mods_available = get_available_mods_by_group(group.id) mods_enabled = get_enabled_mods_by_group(group.id) return render_to_response("group/group_wiki_pages.html", { "group": group, "pages": pages, "is_staff": group.is_staff, "repo_id": repo.id, "search_repo_id": repo.id, "search_wiki": True, "repo_perm": repo_perm, "mods_enabled": mods_enabled, "mods_available": mods_available, }, context_instance=RequestContext(request))
def render_file_revisions (request, repo_id): """List all history versions of a file.""" days_str = request.GET.get('days', '') try: days = int(days_str) except ValueError: days = 7 path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) if not path: return render_error(request) repo = get_repo(repo_id) if not repo: error_msg = _(u"Library does not exist") return render_error(request, error_msg) filetype = get_file_type_and_ext(u_filename)[0].lower() if filetype == 'text' or filetype == 'markdown': can_compare = True else: can_compare = False try: commits = seafile_api.get_file_revisions(repo_id, path, -1, -1, days) except SearpcError, e: logger.error(e.msg) return render_error(request, e.msg)
def group_quit(request, group_id): try: group_id_int = int(group_id) except ValueError: return render_error(request, _(u"group id is not a valid argument.")) try: ccnet_threaded_rpc.quit_group(group_id_int, request.user.username) seafserv_threaded_rpc.remove_repo_group(group_id_int, request.user.username) except SearpcError, e: return render_error(request, e.msg)
def repo_remove_share(request): """ If repo is shared from one person to another person, only these two peson can remove share. If repo is shared from one person to a group, then only the one share the repo and group staff can remove share. """ repo_id = request.GET.get('repo_id', '') group_id = request.GET.get('gid', '') from_email = request.GET.get('from', '') if not is_valid_username(from_email): return render_error(request, _(u'Argument is not valid')) username = request.user.username # if request params don't have 'gid', then remove repos that share to # to other person; else, remove repos that share to groups if not group_id: to_email = request.GET.get('to', '') if not is_valid_username(to_email): return render_error(request, _(u'Argument is not valid')) if username != from_email and username != to_email: return render_permission_error(request, _(u'Failed to remove share')) if is_org_context(request): org_id = request.user.org.org_id org_remove_share(org_id, repo_id, from_email, to_email) else: seaserv.remove_share(repo_id, from_email, to_email) else: try: group_id = int(group_id) except: return render_error(request, _(u'group id is not valid')) group = seaserv.get_group(group_id) if not group: return render_error(request, _(u"Failed to unshare: the group doesn't exist.")) if not seaserv.check_group_staff(group_id, username) \ and username != from_email: return render_permission_error(request, _(u'Failed to remove share')) if is_org_group(group_id): org_id = get_org_id_by_group(group_id) del_org_group_repo(repo_id, org_id, group_id) else: seafile_api.unset_group_repo(repo_id, group_id, from_email) messages.success(request, _('Successfully removed share')) next = request.META.get('HTTP_REFERER', SITE_ROOT) return HttpResponseRedirect(next)
def group_share_repo(request, repo_id, group_id, from_email, permission): """ Share a repo to a group. """ # Check whether group exists group = get_group(group_id) if not group: return render_error(request, _(u"Failed to share: the group doesn't exist.")) if seafserv_threaded_rpc.group_share_repo(repo_id, group_id, from_email, permission) != 0: return render_error(request, _(u"Failed to share: internal error."))
def personal_wiki_pages(request): """ List personal wiki pages. """ try: repo = get_personal_wiki_repo(request.user.username) pages = get_wiki_pages(repo) except SearpcError: return render_error(request, _("Internal Server Error")) except WikiDoesNotExist: return render_error(request, _("Wiki does not exists.")) return render_to_response( "wiki/personal_wiki_pages.html", {"pages": pages, "repo_id": repo.id}, context_instance=RequestContext(request) )
def repo_remove_share(request): """ If repo is shared from one person to another person, only these two peson can remove share. If repo is shared from one person to a group, then only the one share the repo and group staff can remove share. """ repo_id = request.GET.get('repo_id', '') group_id = request.GET.get('gid', '') from_email = request.GET.get('from', '') if not is_valid_username(from_email): return render_error(request, _(u'Argument is not valid')) # if request params don't have 'gid', then remove repos that share to # to other person; else, remove repos that share to groups if not group_id: to_email = request.GET.get('to', '') if not is_valid_username(to_email): return render_error(request, _(u'Argument is not valid')) if request.user.username != from_email and \ request.user.username != to_email: return render_permission_error(request, _(u'Failed to remove share')) remove_share(repo_id, from_email, to_email) else: try: group_id_int = int(group_id) except: return render_error(request, _(u'group id is not valid')) if not check_group_staff(group_id_int, request.user.username) \ and request.user.username != from_email: return render_permission_error(request, _(u'Failed to remove share')) if is_org_group(group_id_int): org_id = get_org_id_by_group(group_id_int) del_org_group_repo(repo_id, org_id, group_id_int) else: from seahub.group.views import group_unshare_repo group_unshare_repo(request, repo_id, group_id_int, from_email) messages.success(request, _('Successfully removed share')) next = request.META.get('HTTP_REFERER', None) if not next: next = SITE_ROOT return HttpResponseRedirect(next)
def group_dismiss(request, group_id): """ Dismiss a group, only group staff can perform this operation. """ next = request.META.get('HTTP_REFERER', None) if not next: next = SITE_ROOT try: group_id_int = int(group_id) except ValueError: return HttpResponseRedirect(next) # Check whether user is group staff user = request.user.username if not ccnet_threaded_rpc.check_group_staff(group_id_int, user): return render_permission_error(request, _(u'Only administrators can dismiss the group')) try: ccnet_threaded_rpc.remove_group(group_id_int, user) seafserv_threaded_rpc.remove_repo_group(group_id_int, None) if request.user.org: org_id = request.user.org['org_id'] url_prefix = request.user.org['url_prefix'] ccnet_threaded_rpc.remove_org_group(org_id, group_id_int) return HttpResponseRedirect(reverse('org_groups', args=[url_prefix])) except SearpcError, e: return render_error(request, _(e.msg))
def view_shared_file(request, token): """ Preview file via shared link. """ assert token is not None # Checked by URLconf try: fileshare = FileShare.objects.get(token=token) except FileShare.DoesNotExist: raise Http404 shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = fileshare.path.rstrip('/') # Normalize file path obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) # get file content ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype} fsize = get_file_size(obj_id) exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype) if exceeds_limit: err = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) # Increase file shared link view_cnt, this operation should be atomic fileshare.view_cnt = F('view_cnt') + 1 fileshare.save() # send statistic messages if ret_dict['filetype'] != 'Unknown': try: obj_size = seafserv_threaded_rpc.get_file_size(obj_id) send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, obj_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
def _decorated(request): error = False if not ENABLE_OAUTH: logger.error('OAuth not enabled.') error = True else: if not CLIENT_ID or not CLIENT_SECRET or not AUTHORIZATION_URL \ or not REDIRECT_URL or not TOKEN_URL or not USER_INFO_URL \ or not SCOPE or not PROVIDER_DOMAIN: logger.error('OAuth relevant settings invalid.') logger.error('CLIENT_ID: %s' % CLIENT_ID) logger.error('CLIENT_SECRET: %s' % CLIENT_SECRET) logger.error('AUTHORIZATION_URL: %s' % AUTHORIZATION_URL) logger.error('REDIRECT_URL: %s' % REDIRECT_URL) logger.error('TOKEN_URL: %s' % TOKEN_URL) logger.error('USER_INFO_URL: %s' % USER_INFO_URL) logger.error('SCOPE: %s' % SCOPE) logger.error('PROVIDER_DOMAIN: %s' % PROVIDER_DOMAIN) error = True if error: return render_error(request, _('Error, please contact administrator.')) return func(request)
def _decorated(request, *args, **kwargs): repo_id = kwargs.get("repo_id", None) if not repo_id: raise Exception, "Repo id is not found in url." repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username 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_passwd_set( repo_id, username ): return render_to_response( "decrypt_repo_form.html", {"repo": repo, "next": request.get_full_path(), "force_server_crypto": FORCE_SERVER_CRYPTO}, context_instance=RequestContext(request), ) if repo.enc_version == 2 and not server_crypto: return render_error(request, _(u"Files in this library can not be viewed online.")) return func(request, *args, **kwargs)
def repo_history(request, repo_id): """ List library modification histories. """ user_perm = check_folder_permission(request, repo_id, '/') if not user_perm: return render_permission_error(request, _(u'Unable to view library modification')) repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.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 password_set = False if repo.props.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)): try: ret = seafserv_rpc.is_passwd_set(repo_id, username) if ret == 1: password_set = True except SearpcError, e: return render_error(request, e.msg) if not password_set: return HttpResponseRedirect(reverse("view_common_lib_dir", args=[repo_id, '']))
def _decorated(request, *args, **kwargs): repo_id = kwargs.get('repo_id', None) if not repo_id: raise Exception, 'Repo id is not found in url.' repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username 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_passwd_set(repo_id, username): return render_to_response('decrypt_repo_form.html', { 'repo': repo, 'next': request.get_full_path(), }, context_instance=RequestContext(request)) if repo.enc_version == 2 and not server_crypto: return render_error(request, _(u'Files in this library can not be viewed online.')) return func(request, *args, **kwargs)
def org_group_remove(request, url_prefix, group_id): # Request header may missing HTTP_REFERER, we need to handle that case. next = request.META.get("HTTP_REFERER", None) if not next: next = seahub_settings.SITE_ROOT try: group_id_int = int(group_id) except ValueError: return HttpResponseRedirect(next) # Check whether is the org group. org_id = get_org_id_by_group(group_id_int) if request.user.org["org_id"] != org_id: return render_permission_error( request, _(u"This group doesn't belong to current organazation"), extra_ctx={"org": request.user.org, "base_template": "org_base.html"}, ) try: ccnet_threaded_rpc.remove_group(group_id_int, request.user.username) seafserv_threaded_rpc.remove_repo_group(group_id_int, None) ccnet_threaded_rpc.remove_org_group(org_id, group_id_int) except SearpcError, e: return render_error(request, e.msg, extra_ctx={"org": request.user.org, "base_template": "org_base.html"})
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_folder_permission(request, repo.id, '/') 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 personal_wiki(request, page_name="home"): username = request.user.username wiki_exists = True try: content, repo, dirent = get_personal_wiki_page(username, page_name) except WikiDoesNotExist: wiki_exists = False owned_repos = seafile_api.get_owned_repo_list(username) owned_repos = [r for r in owned_repos if not r.encrypted] return render_to_response( "wiki/personal_wiki.html", {"wiki_exists": wiki_exists, "owned_repos": owned_repos}, context_instance=RequestContext(request), ) except WikiPageMissing: repo = get_personal_wiki_repo(username) filename = clean_page_name(page_name) + ".md" if not seaserv.post_empty_file(repo.id, "/", filename, username): return render_error(request, _("Failed to create wiki page. Please retry later.")) return HttpResponseRedirect(reverse("personal_wiki", args=[page_name])) else: url_prefix = reverse("personal_wiki", args=[]) content = convert_wiki_link(content, url_prefix, repo.id, username) # fetch file latest contributor and last modified path = "/" + dirent.obj_name file_path_hash = hashlib.md5(urllib2.quote(path.encode("utf-8"))).hexdigest()[:12] contributors, last_modified, last_commit_id = FileContributors.objects.get_file_contributors( repo.id, path.encode("utf-8"), file_path_hash, dirent.obj_id ) latest_contributor = contributors[0] if contributors else None wiki_index_exists = True index_pagename = "index" index_content = None try: index_content, index_repo, index_dirent = get_personal_wiki_page(username, index_pagename) except (WikiDoesNotExist, WikiPageMissing) as e: wiki_index_exists = False else: index_content = convert_wiki_link(index_content, url_prefix, index_repo.id, username) return render_to_response( "wiki/personal_wiki.html", { "wiki_exists": wiki_exists, "content": content, "page": os.path.splitext(dirent.obj_name)[0], "last_modified": last_modified, "latest_contributor": latest_contributor, "path": path, "repo_id": repo.id, "search_repo_id": repo.id, "search_wiki": True, "wiki_index_exists": wiki_index_exists, "index_content": index_content, }, context_instance=RequestContext(request), )
def group_unshare_repo(request, repo_id, group_id, from_email): """ Unshare a repo in group. """ # Check whether group exists group = get_group(group_id) if not group: return render_error(request, _(u"Failed to unshare: the group doesn't exist.")) # Check whether user is group staff or the one share the repo if not check_group_staff(group_id, from_email) and \ seafserv_threaded_rpc.get_group_repo_owner(repo_id) != from_email: return render_permission_error(request, _(u"Operation failed: only administrators and the owner of the library can unshare it.")) if seafserv_threaded_rpc.group_unshare_repo(repo_id, group_id, from_email) != 0: return render_error(request, _(u"Failed to unshare: internal error."))
def personal_wiki(request, page_name="home"): username = request.user.username wiki_exists = True try: content, repo, dirent = get_personal_wiki_page(username, page_name) except WikiDoesNotExist: wiki_exists = False owned_repos = seafile_api.get_owned_repo_list(username) owned_repos = [r for r in owned_repos if not r.encrypted] return render_to_response("wiki/personal_wiki.html", { "wiki_exists": wiki_exists, "owned_repos": owned_repos, }, context_instance=RequestContext(request)) except WikiPageMissing: repo = get_personal_wiki_repo(username) filename = clean_page_name(page_name) + '.md' if not seaserv.post_empty_file(repo.id, "/", filename, username): return render_error(request, _("Failed to create wiki page. Please retry later.")) return HttpResponseRedirect(reverse('personal_wiki', args=[page_name])) else: url_prefix = reverse('personal_wiki', args=[]) content = convert_wiki_link(content, url_prefix, repo.id, username) # fetch file modified time and modifier path = '/' + dirent.obj_name try: dirent = seafile_api.get_dirent_by_path(repo.id, path) if dirent: latest_contributor, last_modified = dirent.modifier, dirent.mtime else: latest_contributor, last_modified = None, 0 except SearpcError as e: logger.error(e) latest_contributor, last_modified = None, 0 wiki_index_exists = True index_pagename = 'index' index_content = None try: index_content, index_repo, index_dirent = get_personal_wiki_page(username, index_pagename) except (WikiDoesNotExist, WikiPageMissing) as e: wiki_index_exists = False else: index_content = convert_wiki_link(index_content, url_prefix, index_repo.id, username) return render_to_response("wiki/personal_wiki.html", { "wiki_exists": wiki_exists, "content": content, "page": os.path.splitext(dirent.obj_name)[0], "last_modified": last_modified, "latest_contributor": latest_contributor or _("Unknown"), "path": path, "repo_id": repo.id, "search_repo_id": repo.id, "search_wiki": True, "wiki_index_exists": wiki_index_exists, "index_content": index_content, }, context_instance=RequestContext(request))
def view_file_via_shared_dir(request, token): assert token is not None # Checked by URLconf try: fileshare = FileShare.objects.get(token=token) except FileShare.DoesNotExist: raise Http404 shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = request.GET.get('p', '').rstrip('/') if not path: raise Http404 if not path.startswith(fileshare.path): # Can not view upper dir of shared dir raise Http404 zipped = gen_path_link(path, '') obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) # get file content ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype} fsize = get_file_size(obj_id) exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype) if exceeds_limit: err = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) # send statistic messages try: obj_size = seafserv_threaded_rpc.get_file_size(obj_id) send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, obj_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
def repo_download_dir(request, repo_id): repo = get_repo(repo_id) if not repo: return render_error(request, _(u'Library does not exist')) path = request.GET.get('p', '/') if path[-1] != '/': # Normalize dir path path += '/' if not seafile_api.get_dir_id_by_path(repo.id, path): return render_error(request, _('"%s" does not exist.') % path) if len(path) > 1: dirname = os.path.basename(path.rstrip('/')) # Here use `rstrip` to cut out last '/' in path else: dirname = repo.name allow_download = True if check_folder_permission(request, repo_id, '/') else False if allow_download: dir_id = seafile_api.get_dir_id_by_commit_and_path(repo.id, repo.head_cmmt_id, path) try: total_size = seafile_api.get_dir_size(repo.store_id, repo.version, dir_id) except Exception, e: logger.error(str(e)) return render_error(request, _(u'Internal Error')) if total_size > MAX_DOWNLOAD_DIR_SIZE: return render_error(request, _(u'Unable to download directory "%s": size is too large.') % dirname) is_windows = 0 if is_windows_operating_system(request): is_windows = 1 fake_obj_id = { 'obj_id': dir_id, 'dir_name': dirname, 'is_windows': is_windows } token = seafile_api.get_fileserver_access_token( repo_id, json.dumps(fake_obj_id), 'download-dir', request.user.username)
def group_wiki_page_edit(request, group, page_name="home"): repo = find_wiki_repo(request, group) if not repo: return render_error(request, _('Wiki is not found.')) filepath = "/" + page_name + ".md" url = "%srepo/%s/file/edit/?p=%s&from=wiki_page_edit&gid=%s" % \ (SITE_ROOT, repo.id, filepath, group.id) return HttpResponseRedirect(url)
def _download_dir_from_share_link(request, fileshare, repo, real_path): # check whether owner's traffic over the limit if user_traffic_over_limit(fileshare.username): return render_error( request, _(u'Unable to access file: share link traffic is used up.')) shared_by = fileshare.username if real_path == '/': dirname = repo.name else: dirname = os.path.basename(real_path.rstrip('/')) dir_id = seafile_api.get_dir_id_by_path(repo.id, real_path) if not dir_id: return render_error(request, _(u'Unable to download: folder not found.')) try: total_size = seaserv.seafserv_threaded_rpc.get_dir_size( repo.store_id, repo.version, dir_id) except Exception as e: logger.error(str(e)) return render_error(request, _(u'Internal Error')) if total_size > seaserv.MAX_DOWNLOAD_DIR_SIZE: return render_error( request, _(u'Unable to download directory "%s": size is too large.') % dirname) token = seafile_api.get_fileserver_access_token( repo.id, dir_id, 'download-dir', request.user.username) try: seaserv.send_message( 'seahub.stats', 'dir-download\t%s\t%s\t%s\t%s' % (repo.id, shared_by, dir_id, total_size)) except Exception as e: logger.error('Error when sending dir-download message: %s' % str(e)) return HttpResponseRedirect(gen_file_get_url(token, dirname))
def unsetinnerpub(request, repo_id): """Unshare repos in organization or in share admin page. Only system admin, organization admin or repo owner can perform this op. """ repo = get_repo(repo_id) perm = request.GET.get('permission', None) if perm is None: return render_error(request, _(u'Argument is not valid')) if not repo: messages.error(request, _('Failed to unshare the library, as it does not exist.')) return HttpResponseRedirect(reverse('share_admin')) # permission check username = request.user.username if is_org_context(request): org_id = request.user.org.org_id repo_owner = seafile_api.get_org_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False if not (request.user.org.is_staff or is_repo_owner): raise Http404 else: repo_owner = seafile_api.get_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False if not (request.user.is_staff or is_repo_owner): raise Http404 try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(org_id, repo.id) else: seaserv.unset_inner_pub_repo(repo.id) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' send_perm_audit_msg('delete-repo-perm', username, 'all', perm_repo_id, perm_path, perm) messages.success(request, _('Unshare "%s" successfully.') % repo.name) except SearpcError: messages.error(request, _('Failed to unshare "%s".') % repo.name) referer = request.META.get('HTTP_REFERER', None) next = settings.SITE_ROOT if referer is None else referer return HttpResponseRedirect(next)
def group_wiki_pages(request, group): """ List wiki pages in group. """ repo = find_wiki_repo(request, group) if not repo: return render_error(request, _('Wiki is not found.')) try: dir_id = seafserv_threaded_rpc.get_dir_id_by_path(repo.id, '/') except SearpcError, e: dir_id = None
def group_wiki_page_new(request, group, page_name="home"): if request.method == 'POST': form = MessageForm(request.POST) page_name = request.POST.get('page_name', '') if not page_name: return HttpResponseRedirect(request.META.get('HTTP_REFERER')) page_name = normalize_page_name(page_name) # normalize page name repo = find_wiki_repo(request, group) if not repo: return render_error(request, _('Wiki is not found.')) filename = page_name + ".md" filepath = "/" + page_name + ".md" if not post_empty_file(repo.id, "/", filename, request.user.username): return render_error(request, _('Failed to create wiki page. Please retry later.')) url = "%srepo/%s/file/edit/?p=%s&from=wiki_page_new&gid=%s" % \ (SITE_ROOT, repo.id, filepath, group.id) return HttpResponseRedirect(url)
def personal_wiki_page_edit(request, page_name="home"): try: repo = get_personal_wiki_repo(request.user.username) except WikiDoesNotExist: return render_error(request, _('Wiki is not found.')) filepath = "/" + page_name + ".md" url = "%s?p=%s&from=personal_wiki_page_edit" % ( reverse('file_edit', args=[repo.id]), urllib2.quote(filepath.encode('utf-8'))) return HttpResponseRedirect(url)
def view_shared_file(request, token): """ Preview file via shared link. """ assert token is not None # Checked by URLconf try: fileshare = FileShare.objects.get(token=token) except FileShare.DoesNotExist: raise Http404 if fileshare.use_passwd: valid_access = cache.get('SharedLink_' + request.user.username + token, False) if not valid_access: d = { 'token': token, 'view_name': 'view_shared_file', } if request.method == 'POST': post_values = request.POST.copy() post_values['enc_password'] = fileshare.password form = SharedLinkPasswordForm(post_values) d['form'] = form if form.is_valid(): # set cache for non-anonymous user if request.user.is_authenticated(): cache.set( 'SharedLink_' + request.user.username + token, True, settings.SHARE_ACCESS_PASSWD_TIMEOUT) else: return render_to_response( 'share_access_validation.html', d, context_instance=RequestContext(request)) else: return render_to_response( 'share_access_validation.html', d, context_instance=RequestContext(request)) shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = fileshare.path.rstrip('/') # Normalize file path obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) # get file content ret_dict = { 'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype } fsize = get_file_size(obj_id) exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype) if exceeds_limit: err = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == SPREADSHEET: handle_spreadsheet(inner_path, obj_id, fileext, ret_dict) elif filetype == OPENDOCUMENT: if fsize == 0: ret_dict['err'] = _(u'Invalid file format.') elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) # Increase file shared link view_cnt, this operation should be atomic fileshare.view_cnt = F('view_cnt') + 1 fileshare.save() # send statistic messages if ret_dict['filetype'] != 'Unknown': try: obj_size = seafserv_threaded_rpc.get_file_size(obj_id) send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, obj_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
def dingtalk_connect_callback(request): if not ENABLE_DINGTALK: return render_error(request, _('Error, please contact administrator.')) state = request.GET.get('state', '') if not state or state != request.session.get('dingtalk_connect_state', ''): logger.error('invalid state') return render_error(request, _('Error, please contact administrator.')) timestamp = str(int(time.time() * 1000)).encode('utf-8') appsecret = DINGTALK_QR_CONNECT_APP_SECRET.encode('utf-8') signature = base64.b64encode( hmac.new(appsecret, timestamp, digestmod=sha256).digest()) parameters = { 'accessKey': DINGTALK_QR_CONNECT_APP_ID, 'timestamp': timestamp, 'signature': signature, } code = request.GET.get('code') data = {"tmp_auth_code": code} full_user_info_url = DINGTALK_QR_CONNECT_USER_INFO_URL + '?' + urllib.parse.urlencode( parameters) user_info_resp = requests.post(full_user_info_url, data=json.dumps(data)) user_info = user_info_resp.json()['user_info'] # seahub authenticate user if 'unionid' not in user_info: logger.error('Required user info not found.') logger.error(user_info) return render_error(request, _('Error, please contact administrator.')) username = request.user.username dingtalk_union_id = user_info['unionid'] auth_user = SocialAuthUser.objects.get_by_provider_and_uid( 'dingtalk', dingtalk_union_id) if auth_user: logger.error('dingtalk account already exists %s' % dingtalk_union_id) return render_error(request, '出错了,此钉钉账号已被绑定') SocialAuthUser.objects.add(username, 'dingtalk', dingtalk_union_id) # update user's profile name = user_info['nick'] if 'nick' in user_info else '' if name: profile = Profile.objects.get_profile_by_user(username) if not profile: profile = Profile(user=username) profile.nickname = name.strip() profile.save() user_detail_info = dingtalk_get_detailed_user_info(user_info['unionid']) contact_email = user_detail_info.get('email', '') if contact_email: profile.contact_email = contact_email profile.save() response = HttpResponseRedirect( request.session['dingtalk_connect_redirect']) return response
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 dtable_asset_preview(request, workspace_id, dtable_id, path): # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: return render_error(request, 'Workspace does not exist.') repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, 'Library does not exist.') dtable = DTables.objects.get_dtable_by_uuid(dtable_id) if not dtable: return render_error(request, 'DTable does not exist.') asset_path = normalize_file_path(os.path.join('/asset', dtable_id, path)) asset_id = seafile_api.get_file_id_by_path(repo_id, asset_path) if not asset_id: return render_error(request, 'Asset file does not exist.') # permission check username = request.user.username if not check_dtable_permission(username, workspace, dtable): return render_permission_error(request, _('Permission denied.')) file_enc = request.GET.get('file_enc', 'auto') if file_enc not in FILE_ENCODING_LIST: file_enc = 'auto' token = seafile_api.get_fileserver_access_token(repo_id, asset_id, 'view', '', use_onetime=False) file_name = os.path.basename(normalize_file_path(path)) file_type, file_ext = get_file_type_and_ext(file_name) inner_path = gen_inner_file_get_url(token, file_name) error_msg, file_content, encoding = get_file_content( file_type, inner_path, file_enc) raw_path = gen_file_get_url(token, file_name) download_url = '%s/workspace/%s/asset/%s/%s?dl=1' % ( DTABLE_WEB_SERVICE_URL.strip('/'), workspace_id, dtable_id, path) return_dict = { 'repo': repo, 'filename': file_name, 'file_path': asset_path, 'file_type': file_type, 'file_ext': file_ext, 'raw_path': raw_path, 'download_url': download_url, 'file_content': file_content, 'err': 'File preview unsupported' if file_type == 'Unknown' else error_msg, } return render(request, 'dtable_asset_file_view_react.html', return_dict)
def dtable_form_edit(request, token): """ Permission: 1. owner 2. group member 3. shared user with `rw` permission """ # resource check form_obj = DTableForms.objects.get_form_by_token(token) if not form_obj: return render_error(request, 'Table\'s form does not exist.') workspace_id = form_obj.workspace_id workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: return render_error(request, 'Workspace does not exist.') dtable_uuid = form_obj.dtable_uuid dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid) if not dtable: return render_error(request, 'Table does not exist.') # permission check username = request.user.username permission = check_dtable_permission(username, workspace, dtable) if permission != PERMISSION_READ_WRITE: return render_permission_error(request, 'Permission denied.') if not check_user_workspace_quota(workspace): return render_error(request, 'Asset quota exceeded.') # generate json web token payload = { 'exp': int(time.time()) + 60 * 5, 'dtable_uuid': dtable_uuid, 'username': "******", 'permission': permission, } try: access_token = jwt.encode(payload, DTABLE_PRIVATE_KEY, algorithm='HS256') except Exception as e: logger.error(e) return render_error(request, _('Internal Server Error')) url = '%s/api/v1/dtables/%s/metadata/' % (DTABLE_SERVER_URL.strip('/'), dtable_uuid) req = requests.Request( url, headers={"Authorization": "Token %s" % access_token.decode()}) try: dtable_metadata = requests.urlopen(req).read().decode() except Exception as e: logger.error(e) return render_error(request, _('Internal Server Error')) share_type = form_obj.share_type shared_groups = list() if share_type == SHARED_GROUPS: group_ids = DTableFormShare.objects.list_by_form(form_obj) shared_groups = [{ 'id': group_id, 'name': group_id_to_name(group_id) } for group_id in group_ids] return_dict = { 'dtable_metadata': dtable_metadata, 'dtable_name': dtable.name, 'workspace_id': workspace_id, 'form_id': form_obj.form_id, 'form_config': form_obj.form_config, 'dtable_uuid': dtable.uuid.hex, 'dtable_web_service_url': DTABLE_WEB_SERVICE_URL, 'form_token': token, 'share_type': share_type, 'shared_groups': json.dumps(shared_groups), } return render(request, 'dtable_edit_form_view_react.html', return_dict)
def dtable_plugin_asset_view(request, workspace_id, name, plugin_id, path): """ Permission: 1. owner 2. group member 3. shared user """ try: plugin_record = DTablePlugins.objects.get(pk=plugin_id) except DTablePlugins.DoesNotExist: error_msg = 'Plugin %s not found.' % plugin_id return render_error(request, error_msg) workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return render_error(request, error_msg) if '@seafile_group' in workspace.owner: group_id = workspace.owner.split('@')[0] group = ccnet_api.get_group(int(group_id)) if not group: error_msg = 'Group %s not found.' % group_id return render_error(request, error_msg) table_name = name dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'DTable %s not found.' % table_name return render_error(request, error_msg) # permission check username = request.user.username permission = check_dtable_permission(username, workspace, dtable) if not permission: error_msg = 'Permission denied.' return render_error(request, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return render_error(request, error_msg) plugin_file_path = os.path.join('/asset', str(dtable.uuid), 'plugins', plugin_record.name) asset_path = os.path.join(plugin_file_path, path) plugin_file_dir_id = seafile_api.get_file_id_by_path(repo_id, asset_path) if not plugin_file_dir_id: return render_error(request, 'Asset file does not exist.') token = seafile_api.get_fileserver_access_token(workspace.repo_id, plugin_file_dir_id, 'view', '', use_onetime=False) url = gen_file_get_url(token, asset_path) import requests r = requests.get(url) response = HttpResponse(r.content) content_type = mimetypes.guess_type(path) if type: response['Content-Type'] = content_type[0] return response
def dtable_file_view(request, workspace_id, name): """ Permission: 1. owner 2. group member 3. shared user """ # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: return render_error(request, 'Workspace does not exist.') group_id = '' if '@seafile_group' in workspace.owner: group_id = workspace.owner.split('@')[0] group = seaserv.get_group(group_id) if not group: error_msg = 'Group %s not found.' % group_id return render_error(request, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, 'Library does not exist.') dtable = DTables.objects.get_dtable(workspace, name) if not dtable: return render_error(request, 'DTable does not exist.') # permission check username = request.user.username permission = check_dtable_permission(username, workspace, dtable) if not permission: return render_permission_error(request, _('Permission denied.')) is_admin = False if group_id: is_admin = is_group_admin_or_owner(group_id, username) else: # open your own dtable is_admin = username == workspace.owner seafile_url = '' repo_api_token = '' try: seafile_connector = SeafileConnectors.objects.get(dtable=dtable) seafile_url = seafile_connector.seafile_url repo_api_token = seafile_connector.repo_api_token except SeafileConnectors.DoesNotExist: pass return_dict = { 'version': SEATABLE_VERSION, 'dtable_baidu_map_key': DTABLE_BAIDU_MAP_KEY, 'dtable_google_map_key': DTABLE_GOOGLE_MAP_KEY, 'seatable_market_url': SEATABLE_MARKET_URL, 'filename': name, 'workspace_id': workspace_id, 'dtable_uuid': dtable.uuid.hex, 'permission': permission if check_user_workspace_quota(workspace) else 'r', 'media_url': MEDIA_URL, 'seafile_url': seafile_url, 'repo_api_token': repo_api_token, 'dtable_server': DTABLE_SERVER_URL, 'dtable_socket': DTABLE_SOCKET_URL, 'dtable_enable_geolocation_column': DTABLE_ENABLE_GEOLOCATION_COLUMN, 'is_admin': is_admin, 'asset_quota_exceeded': dtable.creator == request.user.username and not check_user_workspace_quota(workspace), } return render(request, 'dtable_file_view_react.html', return_dict)
def oauth_callback(request): """ Step 3: Retrieving an access token. The user has been redirected back from the provider to your registered callback URL. With this redirection comes an authorization code included in the redirect URL. We will use that to obtain an access token. """ session = OAuth2Session(client_id=CLIENT_ID, scope=SCOPE, state=request.session.get('oauth_state', None), redirect_uri=REDIRECT_URL) try: token = session.fetch_token( TOKEN_URL, client_secret=CLIENT_SECRET, authorization_response=request.get_full_path()) if 'user_id' in session._client.__dict__['token']: # used for sjtu.edu.cn # https://xjq12311.gitbooks.io/sjtu-engtc/content/ user_id = session._client.__dict__['token']['user_id'] user_info_resp = session.get(USER_INFO_URL + '?user_id=%s' % user_id) else: user_info_url = USER_INFO_URL if ACCESS_TOKEN_IN_URI: code = request.GET.get('code') user_info_url = USER_INFO_URL + '?access_token=%s&code=%s' % ( token['access_token'], code) user_info_resp = session.get(user_info_url) except Exception as e: logger.error(e) return render_error(request, _('Error, please contact administrator.')) def format_user_info(user_info_resp): logger.info('user info resp: %s' % user_info_resp.text) error = False user_info = {} user_info_json = user_info_resp.json() for item, attr in list(ATTRIBUTE_MAP.items()): required, user_attr = attr value = user_info_json.get(item, '') if value: # ccnet email if user_attr == 'email': user_info[user_attr] = value if is_valid_email(str(value)) else \ '%s@%s' % (str(value), PROVIDER_DOMAIN) else: user_info[user_attr] = value elif required: error = True return user_info, error user_info, error = format_user_info(user_info_resp) if error: logger.error('Required user info not found.') logger.error(user_info) return render_error(request, _('Error, please contact administrator.')) # seahub authenticate user email = user_info['email'] try: user = auth.authenticate(remote_user=email) except User.DoesNotExist: user = None if not user or not user.is_active: logger.error('User %s not found or inactive.' % email) # a page for authenticate user failed return render_error(request, _('User %s not found.') % email) # User is valid. Set request.user and persist user in the session # by logging the user in. request.user = user auth.login(request, user) # update user's profile name = user_info['name'] if 'name' in user_info else '' contact_email = user_info['contact_email'] if \ 'contact_email' in user_info else '' profile = Profile.objects.get_profile_by_user(email) if not profile: profile = Profile(user=email) if name: profile.nickname = name.strip() profile.save() if contact_email: profile.contact_email = contact_email.strip() profile.save() # generate auth token for Seafile client api_token = get_api_token(request) # redirect user to home page response = HttpResponseRedirect(request.session['oauth_redirect']) response.set_cookie('seahub_auth', email + '@' + api_token.key) return response
def file_revisions(request, repo_id): """List file revisions in file version history page. """ repo = get_repo(repo_id) if not repo: error_msg = _(u"Library does not exist") return render_error(request, error_msg) # perm check if not check_folder_permission(request, repo_id, '/'): error_msg = _(u"Permission denied.") return render_error(request, error_msg) path = request.GET.get('p', '/') if not path: return render_error(request) if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) filetype, file_ext = [x.lower() for x in get_file_type_and_ext(u_filename)] if filetype == 'text' or filetype == 'markdown': can_compare = True else: can_compare = False # Check whether user is repo owner if validate_owner(request, repo_id): is_owner = True else: is_owner = False zipped = gen_path_link(path, repo.name) can_revert_file = True username = request.user.username try: is_locked, locked_by_me = check_file_lock(repo_id, path, username) except Exception as e: logger.error(e) is_locked, locked_by_me = False, False repo_perm = seafile_api.check_permission_by_path(repo_id, path, username) if repo_perm != 'rw' or (is_locked and not locked_by_me): can_revert_file = False # for 'go back' referer = request.GET.get('referer', '') # Whether use new file revisions page which read file history from db. if request.GET.get('_new', None) is not None: if request.GET.get('_new') == '0': use_new_page = False else: use_new_page = True else: suffix_list = seafevents_api.get_file_history_suffix() if suffix_list and isinstance(suffix_list, list): suffix_list = [x.lower() for x in suffix_list] else: logger.error('Wrong type of suffix_list: %s' % repr(suffix_list)) suffix_list = [] use_new_page = True if file_ext in suffix_list else False if use_new_page: return render( request, 'file_revisions_new.html', { 'repo': repo, 'path': path, 'u_filename': u_filename, 'zipped': zipped, 'is_owner': is_owner, 'can_compare': can_compare, 'can_revert_file': can_revert_file, 'referer': referer, }) return render( request, 'file_revisions.html', { 'repo': repo, 'path': path, 'u_filename': u_filename, 'zipped': zipped, 'is_owner': is_owner, 'can_compare': can_compare, 'can_revert_file': can_revert_file, 'can_download_file': parse_repo_perm(repo_perm).can_download, 'referer': referer, })
if repo.props.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)): try: ret = seafserv_rpc.is_passwd_set(repo_id, username) if ret == 1: password_set = True except SearpcError, e: return render_error(request, e.msg) if not password_set: reverse_url = reverse('lib_view', args=[repo_id, repo.name, '']) return HttpResponseRedirect(reverse_url) commit_id = request.GET.get('commit_id', '') if not commit_id: return render_error(request, _(u'Please specify history ID')) try: seafserv_threaded_rpc.revert_on_server(repo_id, commit_id, request.user.username) messages.success(request, _('Successfully restored the library.')) except SearpcError, e: if e.msg == 'Bad arguments': return render_error(request, _(u'Invalid arguments.')) elif e.msg == 'No such repo': return render_error(request, _(u'Library does not exist')) elif e.msg == "Commit doesn't exist": return render_error(request, _(u'History you specified does not exist')) else: return render_error(request, _(u'Unknown error'))
def repo_download_dir(request, repo_id): repo = get_repo(repo_id) if not repo: return render_error(request, _('Library does not exist')) path = request.GET.get('p', '/') if path[-1] != '/': # Normalize dir path path += '/' if not seafile_api.get_dir_id_by_path(repo.id, path): return render_error(request, _('"%s" does not exist.') % path) if len(path) > 1: dirname = os.path.basename( path.rstrip('/')) # Here use `rstrip` to cut out last '/' in path else: dirname = repo.name allow_download = parse_repo_perm( check_folder_permission(request, repo_id, '/')).can_download if allow_download: dir_id = seafile_api.get_dir_id_by_commit_and_path( repo.id, repo.head_cmmt_id, path) try: total_size = seafile_api.get_dir_size(repo.store_id, repo.version, dir_id) except Exception as e: logger.error(str(e)) return render_error(request, _('Internal Server Error')) if total_size > MAX_DOWNLOAD_DIR_SIZE: return render_error( request, _('Unable to download directory "%s": size is too large.') % dirname) is_windows = 0 if is_windows_operating_system(request): is_windows = 1 fake_obj_id = { 'obj_id': dir_id, 'dir_name': dirname, 'is_windows': is_windows } token = seafile_api.get_fileserver_access_token( repo_id, json.dumps(fake_obj_id), 'download-dir', request.user.username) if not token: return render_error(request, _('Internal Server Error')) else: return render_error(request, _('Unable to download "%s"') % dirname) url = gen_file_get_url(token, dirname) from seahub.views.file import send_file_access_msg send_file_access_msg(request, repo, path, 'web') return redirect(url)
def repo_history(request, repo_id): """ List library modification histories. """ user_perm = check_folder_permission(request, repo_id, '/') if not user_perm: return render_permission_error( request, _('Unable to view library modification')) repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.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 password_set = False if repo.props.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)): try: ret = seafile_api.is_password_set(repo_id, username) if ret == 1: password_set = True except SearpcError as e: return render_error(request, e.msg) if not password_set: reverse_url = reverse('lib_view', args=[repo_id, repo.name, '']) return HttpResponseRedirect(reverse_url) try: current_page = int(request.GET.get('page', '1')) except ValueError: current_page = 1 per_page = 100 commits_all = get_commits(repo_id, per_page * (current_page - 1), per_page + 1) commits = commits_all[:per_page] for c in commits: c.show = False if new_merge_with_no_conflict(c) else True show_label = False if ENABLE_REPO_SNAPSHOT_LABEL: show_label = True snapshot_labels = RevisionTags.objects.filter(repo_id=repo_id) for c in commits: if c.show: c.labels = [] for label in snapshot_labels: if label.revision_id == c.id: c.labels.append(label.tag.name) if len(commits_all) == per_page + 1: page_next = True else: page_next = False # for 'go back' referer = request.GET.get('referer', '') #template = 'repo_history.html' template = 'repo_history_react.html' return render( request, template, { "repo": repo, "commits": commits, 'current_page': current_page, 'prev_page': current_page - 1, 'next_page': current_page + 1, 'page_next': page_next, 'user_perm': user_perm, 'show_label': show_label, 'referer': referer, })
def react_fake_view(request, **kwargs): username = request.user.username if resolve(request.path).url_name == 'lib_view': repo_id = kwargs.get('repo_id', '') path = kwargs.get('path', '') if repo_id and path and \ not check_folder_permission(request, repo_id, path): converted_repo_path = seafile_api.convert_repo_path( repo_id, path, username) if not converted_repo_path: error_msg = 'Permission denied.' return render_error(request, error_msg) repo_path_dict = json.loads(converted_repo_path) converted_repo_id = repo_path_dict['repo_id'] converted_repo = seafile_api.get_repo(converted_repo_id) if not converted_repo: error_msg = 'Library %s not found.' % converted_repo_id return render_error(request, error_msg) converted_path = repo_path_dict['path'] if not seafile_api.get_dirent_by_path(converted_repo_id, converted_path): error_msg = 'Dirent %s not found.' % converted_path return render_error(request, error_msg) if not check_folder_permission(request, converted_repo_id, converted_path): error_msg = 'Permission denied.' return render_error(request, error_msg) next_url = reverse('lib_view', args=[ converted_repo_id, converted_repo.repo_name, converted_path.strip('/') ]) return HttpResponseRedirect(next_url) guide_enabled = UserOptions.objects.is_user_guide_enabled(username) if guide_enabled: create_default_library(request) try: expire_days = seafile_api.get_server_config_int( 'library_trash', 'expire_days') except Exception as e: logger.error(e) expire_days = -1 folder_perm_enabled = True if is_pro_version( ) and ENABLE_FOLDER_PERM else False try: max_upload_file_size = seafile_api.get_server_config_int( 'fileserver', 'max_upload_size') except Exception as e: logger.error(e) max_upload_file_size = -1 return render( request, "react_app.html", { "onlyoffice_desktop_editors_portal_login": ONLYOFFICE_DESKTOP_EDITORS_PORTAL_LOGIN, "guide_enabled": guide_enabled, 'trash_repos_expire_days': expire_days if expire_days > 0 else 30, 'dtable_web_server': DTABLE_WEB_SERVER, 'max_upload_file_size': max_upload_file_size, 'seafile_collab_server': SEAFILE_COLLAB_SERVER, 'storages': get_library_storages(request), 'library_templates': list(LIBRARY_TEMPLATES.keys()), 'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL, 'resumable_upload_file_block_size': settings.RESUMABLE_UPLOAD_FILE_BLOCK_SIZE, 'max_number_of_files_for_fileupload': settings.MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD, 'share_link_expire_days_default': SHARE_LINK_EXPIRE_DAYS_DEFAULT, 'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN, 'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX, 'upload_link_expire_days_default': UPLOAD_LINK_EXPIRE_DAYS_DEFAULT, 'upload_link_expire_days_min': UPLOAD_LINK_EXPIRE_DAYS_MIN, 'upload_link_expire_days_max': UPLOAD_LINK_EXPIRE_DAYS_MAX, 'enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY, 'enable_repo_history_setting': config.ENABLE_REPO_HISTORY_SETTING, 'enable_reset_encrypted_repo_password': ENABLE_RESET_ENCRYPTED_REPO_PASSWORD, 'enableFileComment': settings.ENABLE_FILE_COMMENT, 'is_email_configured': IS_EMAIL_CONFIGURED, 'can_add_public_repo': request.user.permissions.can_add_public_repo(), 'folder_perm_enabled': folder_perm_enabled, 'file_audit_enabled': FILE_AUDIT_ENABLED, 'custom_nav_items': json.dumps(CUSTOM_NAV_ITEMS), 'enable_show_contact_email_when_search_user': settings.ENABLE_SHOW_CONTACT_EMAIL_WHEN_SEARCH_USER, 'additional_share_dialog_note': ADDITIONAL_SHARE_DIALOG_NOTE, 'additional_app_bottom_links': ADDITIONAL_APP_BOTTOM_LINKS, 'additional_about_dialog_links': ADDITIONAL_ABOUT_DIALOG_LINKS, 'enable_ocm': ENABLE_OCM, 'ocm_remote_servers': OCM_REMOTE_SERVERS, 'enable_share_to_department': settings.ENABLE_SHARE_TO_DEPARTMENT, })
def file_revisions(request, repo_id): """List file revisions in file version history page. """ repo = get_repo(repo_id) if not repo: error_msg = _(u"Library does not exist") return render_error(request, error_msg) # perm check if not check_folder_permission(request, repo_id, '/'): error_msg = _(u"Permission denied.") return render_error(request, error_msg) path = request.GET.get('p', '/') if not path: return render_error(request) if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) filetype = get_file_type_and_ext(u_filename)[0].lower() if filetype == 'text' or filetype == 'markdown': can_compare = True else: can_compare = False # Check whether user is repo owner if validate_owner(request, repo_id): is_owner = True else: is_owner = False zipped = gen_path_link(path, repo.name) can_revert_file = True username = request.user.username try: is_locked, locked_by_me = check_file_lock(repo_id, path, username) except Exception as e: logger.error(e) is_locked, locked_by_me = False, False if seafile_api.check_permission_by_path(repo_id, path, username) != 'rw' or \ (is_locked and not locked_by_me): can_revert_file = False # for 'go back' referer = request.GET.get('referer', '') return render(request, 'file_revisions.html', { 'repo': repo, 'path': path, 'u_filename': u_filename, 'zipped': zipped, 'is_owner': is_owner, 'can_compare': can_compare, 'can_revert_file': can_revert_file, 'referer': referer, })
def view_shared_upload_link(request, uploadlink): token = uploadlink.token password_check_passed, err_msg = check_share_link_common( request, uploadlink, is_upload_link=True) if not password_check_passed: d = { 'token': token, 'view_name': 'view_shared_upload_link', 'err_msg': err_msg } return render(request, 'share_access_validation.html', d) username = uploadlink.username repo_id = uploadlink.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = uploadlink.path if path == '/': # use repo name as dir name if share whole library dir_name = repo.name else: dir_name = os.path.basename(path[:-1]) repo = get_repo(repo_id) if not repo: raise Http404 if repo.encrypted or \ seafile_api.check_permission_by_path(repo_id, '/', username) != 'rw': return render_error(request, _(u'Permission denied')) uploadlink.view_cnt = F('view_cnt') + 1 uploadlink.save() no_quota = True if seaserv.check_quota(repo_id) < 0 else False return render( request, 'view_shared_upload_link.html', { 'repo': repo, 'path': path, 'username': username, 'dir_name': dir_name, 'max_upload_file_size': seaserv.MAX_UPLOAD_FILE_SIZE, 'no_quota': no_quota, 'uploadlink': uploadlink, 'enable_upload_folder': ENABLE_UPLOAD_FOLDER, 'enable_resumable_fileupload': ENABLE_RESUMABLE_FILEUPLOAD, 'max_number_of_files_for_fileupload': MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD, })
def repo_remove_share(request): """ If repo is shared from one person to another person, only these two person can remove share. If repo is shared from one person to a group, then only the one share the repo and group staff can remove share. """ repo_id = request.GET.get('repo_id', '') group_id = request.GET.get('gid', '') from_email = request.GET.get('from', '') perm = request.GET.get('permission', None) if not is_valid_username(from_email) or perm is None: return render_error(request, _(u'Argument is not valid')) username = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, _(u'Library does not exist')) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' # if request params don't have 'gid', then remove repos that share to # to other person; else, remove repos that share to groups if not group_id: to_email = request.GET.get('to', '') if not is_valid_username(to_email): return render_error(request, _(u'Argument is not valid')) if username != from_email and username != to_email: return render_permission_error(request, _(u'Failed to remove share')) if is_org_context(request): org_id = request.user.org.org_id org_remove_share(org_id, repo_id, from_email, to_email) else: seaserv.remove_share(repo_id, from_email, to_email) send_perm_audit_msg('delete-repo-perm', from_email, to_email, \ perm_repo_id, perm_path, perm) else: try: group_id = int(group_id) except: return render_error(request, _(u'group id is not valid')) group = seaserv.get_group(group_id) if not group: return render_error( request, _(u"Failed to unshare: the group doesn't exist.")) if not seaserv.check_group_staff(group_id, username) \ and username != from_email: return render_permission_error(request, _(u'Failed to remove share')) if is_org_group(group_id): org_id = get_org_id_by_group(group_id) del_org_group_repo(repo_id, org_id, group_id) else: seafile_api.unset_group_repo(repo_id, group_id, from_email) send_perm_audit_msg('delete-repo-perm', from_email, group_id, \ perm_repo_id, perm_path, perm) messages.success(request, _('Successfully removed share')) next = request.META.get('HTTP_REFERER', SITE_ROOT) return HttpResponseRedirect(next)
def dtable_external_download_link_view(request, token): dtable_external_link = DTableExternalLinks.objects.filter( token=token).first() if not dtable_external_link: raise Http404 # resource check workspace_id = dtable_external_link.dtable.workspace.id workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: raise Http404 name = dtable_external_link.dtable.name dtable = DTables.objects.get_dtable(workspace, name) if not dtable: return render_error(request, _('DTable does not exist')) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return render_error(request, error_msg) # get dtable_file_dir_id and asset_dir_id dtable_file_dir_id = seafile_api.get_file_id_by_path( repo_id, '/' + name + '.dtable/') if not dtable_file_dir_id: error_msg = 'DTable %s not found.' % name return render_error(request, error_msg) params = {} params['username'] = '******' params['table_name'] = name params['repo_id'] = repo_id params['dtable_uuid'] = str(dtable.uuid) try: task_id = add_dtable_io_task(type='export', params=params) except Exception as e: return render_error(request, 'Server is busy. Please try again later.') finished = False while not finished: resp = query_dtable_io_status(task_id) finished = json.loads(resp.content)['is_finished'] time.sleep(1) tmp_zip_path = os.path.join('/tmp/dtable-io', str(dtable.uuid), 'zip_file') + '.zip' if not os.path.exists(tmp_zip_path): return render_error(request, _('Internal Server Error')) with open(tmp_zip_path, 'rb') as f: zip_stream = f.read() os.remove(tmp_zip_path) response = HttpResponse(zip_stream, content_type="application/x-zip-compressed") response[ 'Content-Disposition'] = 'attachment;filename*=UTF-8\'\'' + urlquote( dtable.dtable_name) + '.dtable' return response
def share_permission_admin(request): """Change repo share permission in ShareAdmin. """ share_type = request.GET.get('share_type', '') content_type = 'application/json; charset=utf-8' form = RepoShareForm(request.POST) form.is_valid() email_or_group = form.cleaned_data['email_or_group'] repo_id = form.cleaned_data['repo_id'] permission = form.cleaned_data['permission'] from_email = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, _(u'Library does not exist')) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' if share_type == 'personal': if not is_valid_username(email_or_group): return HttpResponse(json.dumps({'success': False}), status=400, content_type=content_type) try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_set_share_permission( org_id, repo_id, from_email, email_or_group, permission) else: seafile_api.set_share_permission(repo_id, from_email, email_or_group, permission) send_perm_audit_msg('modify-repo-perm', from_email, \ email_or_group, perm_repo_id, perm_path, permission) except SearpcError: return HttpResponse(json.dumps({'success': False}), status=500, content_type=content_type) return HttpResponse(json.dumps({'success': True}), content_type=content_type) elif share_type == 'group': try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.set_org_group_repo_permission( org_id, int(email_or_group), repo_id, permission) else: group_id = int(email_or_group) seafile_api.set_group_repo_permission(group_id, repo_id, permission) send_perm_audit_msg('modify-repo-perm', from_email, \ group_id, perm_repo_id, perm_path, permission) except SearpcError: return HttpResponse(json.dumps({'success': False}), status=500, content_type=content_type) return HttpResponse(json.dumps({'success': True}), content_type=content_type) elif share_type == 'public': try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.set_org_inner_pub_repo( org_id, repo_id, permission) else: seafile_api.add_inner_pub_repo(repo_id, permission) send_perm_audit_msg('modify-repo-perm', from_email, 'all', \ perm_repo_id, perm_path, permission) except SearpcError: return HttpResponse(json.dumps({'success': False}), status=500, content_type=content_type) return HttpResponse(json.dumps({'success': True}), content_type=content_type) else: return HttpResponse(json.dumps({'success': False}), status=400, content_type=content_type)
def dtable_row_share_link_view(request, token): # resource check dtable_row_share = DTableRowShares.objects.get_dtable_row_share_by_token( token) if not dtable_row_share: return render_error(request, 'DTable row share link does not exist.') workspace_id = dtable_row_share.workspace_id workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: return render_error(request, 'Workspace does not exist.') repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, 'Library does not exist.') dtable_uuid = dtable_row_share.dtable_uuid dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid) if not dtable: return render_error(request, 'DTable %s does not exist' % dtable_uuid) # generate json web token username = request.user.username payload = { 'exp': int(time.time()) + 86400 * 3, 'dtable_uuid': dtable.uuid.hex, 'username': username, 'permission': PERMISSION_READ, } try: access_token = jwt.encode(payload, DTABLE_PRIVATE_KEY, algorithm='HS256') except Exception as e: logger.error(e) return render_error(request, _('Internal Server Error')) url_for_row = '%s/api/v1/dtables/%s/tables/%s/rows/%s/' % \ (DTABLE_SERVER_URL.strip('/'), dtable_uuid, dtable_row_share.table_id, dtable_row_share.row_id) req_for_row = requests.Request( url_for_row, headers={"Authorization": "Token %s" % access_token.decode()}) url_for_columns = '%s/api/v1/dtables/%s/tables/%s/columns/' % \ (DTABLE_SERVER_URL.strip('/'), dtable_uuid, dtable_row_share.table_id) req_for_columns = requests.Request( url_for_columns, headers={"Authorization": "Token %s" % access_token.decode()}) try: row_content = requests.urlopen(req_for_row).read().decode() columns = requests.urlopen(req_for_columns).read().decode() except Exception as e: logger.error(e) return render_error(request, _('Internal Server Error')) return_dict = { 'row_content': row_content, 'columns': columns, 'workspace_id': workspace_id, 'dtable_name': dtable.name } return render(request, 'dtable_shared_row_view_react.html', return_dict)
def group_wiki(request, group, page_name="home"): username = request.user.username # get available modules(wiki, etc) mods_available = get_available_mods_by_group(group.id) mods_enabled = get_enabled_mods_by_group(group.id) wiki_exists = True try: content, repo, dirent = get_group_wiki_page(username, group, page_name) except WikiDoesNotExist: wiki_exists = False group_repos = get_group_repos(group.id, username) group_repos = [r for r in group_repos if not r.encrypted] return render_to_response("group/group_wiki.html", { "group": group, "is_staff": group.is_staff, "wiki_exists": wiki_exists, "mods_enabled": mods_enabled, "mods_available": mods_available, "group_repos": group_repos, }, context_instance=RequestContext(request)) except WikiPageMissing: '''create that page for user if he/she is a group member''' if not is_group_user(group.id, username): raise Http404 repo = get_group_wiki_repo(group, username) # No need to check whether repo is none, since repo is already created filename = page_name_to_file_name(clean_page_name(page_name)) if not post_empty_file(repo.id, "/", filename, username): return render_error( request, _("Failed to create wiki page. Please retry later.")) return HttpResponseRedirect( reverse('group_wiki', args=[group.id, page_name])) else: # fetch file modified time and modifier path = '/' + dirent.obj_name try: dirent = seafile_api.get_dirent_by_path(repo.id, path) if dirent: latest_contributor, last_modified = dirent.modifier, dirent.mtime else: latest_contributor, last_modified = None, 0 except SearpcError as e: logger.error(e) latest_contributor, last_modified = None, 0 if is_registered_user(username): repo_perm = seafile_api.check_permission_by_path( repo.id, '/', username) else: # when anonymous user visit public group wiki, set permission as 'r' repo_perm = 'r' wiki_index_exists = True index_pagename = 'index' index_content = None try: index_content, index_repo, index_dirent = get_group_wiki_page( username, group, index_pagename) except (WikiDoesNotExist, WikiPageMissing) as e: wiki_index_exists = False return render_to_response( "group/group_wiki.html", { "group": group, "is_staff": group.is_staff, "wiki_exists": wiki_exists, "content": content, "page": os.path.splitext(dirent.obj_name)[0], "last_modified": last_modified, "latest_contributor": latest_contributor or _("Unknown"), "path": path, "repo_id": repo.id, "search_repo_id": repo.id, "search_wiki": True, "mods_enabled": mods_enabled, "mods_available": mods_available, "repo_perm": repo_perm, "wiki_index_exists": wiki_index_exists, "index_content": index_content, }, context_instance=RequestContext(request))
def dtable_form_view(request, token): # resource check form_obj = DTableForms.objects.get_form_by_token(token) if not form_obj: return render_error(request, 'Table\'s form does not exist.') workspace_id = form_obj.workspace_id workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: return render_error(request, 'Workspace does not exist.') dtable_uuid = form_obj.dtable_uuid dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid) if not dtable: return render_error(request, 'Table does not exist.') # permission check if not check_form_submit_permission(request, form_obj): return render_permission_error(request, _('Permission denied.')) # asset quota check if not check_user_workspace_quota(workspace): return render_error(request, _('Asset quota exceeded.')) # generate json web token payload = { 'exp': int(time.time()) + 60 * 5, 'dtable_uuid': dtable_uuid, 'username': "******", 'permission': PERMISSION_READ, } try: access_token = jwt.encode(payload, DTABLE_PRIVATE_KEY, algorithm='HS256') except Exception as e: logger.error(e) return render_error(request, _('Internal Server Error')) url = '%s/api/v1/dtables/%s/metadata/' % (DTABLE_SERVER_URL.strip('/'), dtable_uuid) req = requests.Request( url, headers={"Authorization": "Token %s" % access_token.decode()}) try: dtable_metadata = requests.urlopen(req).read().decode() except Exception as e: logger.error(e) return render_error(request, _('Internal Server Error')) return_dict = { 'version': SEATABLE_VERSION, 'dtable_metadata': dtable_metadata, 'workspace_id': workspace_id, 'form_id': form_obj.form_id, 'form_config': form_obj.form_config, 'dtable_name': dtable.name, 'dtable_web_service_url': DTABLE_WEB_SERVICE_URL, 'form_token': token, } return render(request, 'dtable_share_form_view_react.html', return_dict)
def work_weixin_oauth_connect_callback(request): if not work_weixin_oauth_check(): return render_error(request, _('Feature is not enabled.')) code = request.GET.get('code', None) state = request.GET.get('state', None) if state != request.session.get('work_weixin_oauth_connect_state', None) or not code: logger.error( 'can not get right code or state from work weixin request') return render_error(request, _('Error, please contact administrator.')) access_token = get_work_weixin_access_token() if not access_token: logger.error('can not get work weixin access_token') return render_error(request, _('Error, please contact administrator.')) data = { 'access_token': access_token, 'code': code, } api_response = requests.get(WORK_WEIXIN_GET_USER_INFO_URL, params=data) api_response_dic = handler_work_weixin_api_response(api_response) if not api_response_dic: logger.error('can not get work weixin user info') return render_error(request, _('Error, please contact administrator.')) if not api_response_dic.get('UserId', None): logger.error('can not get UserId in work weixin user info response') return render_error(request, _('Error, please contact administrator.')) user_id = api_response_dic.get('UserId') uid = WORK_WEIXIN_UID_PREFIX + user_id email = request.user.username work_weixin_user = SocialAuthUser.objects.get_by_provider_and_uid( WORK_WEIXIN_PROVIDER, uid) if work_weixin_user: logger.error('work weixin account already exists %s' % user_id) return render_error(request, '出错了,此企业微信账号已被绑定') SocialAuthUser.objects.add(email, WORK_WEIXIN_PROVIDER, uid) # update user info if WORK_WEIXIN_USER_INFO_AUTO_UPDATE: user_info_data = { 'access_token': access_token, 'userid': user_id, } user_info_api_response = requests.get(WORK_WEIXIN_GET_USER_PROFILE_URL, params=user_info_data) user_info_api_response_dic = handler_work_weixin_api_response( user_info_api_response) if user_info_api_response_dic: api_user = user_info_api_response_dic api_user['username'] = email api_user['contact_email'] = api_user['email'] update_work_weixin_user_info(api_user) # redirect user to page response = HttpResponseRedirect( request.session.get('work_weixin_oauth_connect_redirect', '/')) return response
def work_weixin_oauth_callback(request): if not work_weixin_oauth_check(): return render_error(request, _('Feature is not enabled.')) code = request.GET.get('code', None) state = request.GET.get('state', None) if state != request.session.get('work_weixin_oauth_state', None) or not code: logger.error( 'can not get right code or state from work weixin request') return render_error(request, _('Error, please contact administrator.')) access_token = get_work_weixin_access_token() if not access_token: logger.error('can not get work weixin access_token') return render_error(request, _('Error, please contact administrator.')) data = { 'access_token': access_token, 'code': code, } api_response = requests.get(WORK_WEIXIN_GET_USER_INFO_URL, params=data) api_response_dic = handler_work_weixin_api_response(api_response) if not api_response_dic: logger.error('can not get work weixin user info') return render_error(request, _('Error, please contact administrator.')) if not api_response_dic.get('UserId', None): logger.error('can not get UserId in work weixin user info response') return render_error(request, _('Error, please contact administrator.')) user_id = api_response_dic.get('UserId') uid = WORK_WEIXIN_UID_PREFIX + user_id work_weixin_user = SocialAuthUser.objects.get_by_provider_and_uid( WORK_WEIXIN_PROVIDER, uid) if work_weixin_user: email = work_weixin_user.username is_new_user = False else: email = gen_user_virtual_id() is_new_user = True try: user = auth.authenticate(remote_user=email) except User.DoesNotExist: user = None if not user: return render_error( request, _('Error, new user registration is not allowed, please contact administrator.' )) if is_new_user: SocialAuthUser.objects.add(email, WORK_WEIXIN_PROVIDER, uid) # update user info if is_new_user or WORK_WEIXIN_USER_INFO_AUTO_UPDATE: user_info_data = { 'access_token': access_token, 'userid': user_id, } user_info_api_response = requests.get(WORK_WEIXIN_GET_USER_PROFILE_URL, params=user_info_data) user_info_api_response_dic = handler_work_weixin_api_response( user_info_api_response) if user_info_api_response_dic: api_user = user_info_api_response_dic api_user['username'] = email api_user['contact_email'] = api_user['email'] update_work_weixin_user_info(api_user) if not user.is_active: return render_error( request, _('Your account is created successfully, please wait for administrator to activate your account.' )) # User is valid. Set request.user and persist user in the session # by logging the user in. request.user = user request.session['remember_me'] = REMEMBER_ME auth.login(request, user) # generate auth token for Seafile client api_token = get_api_token(request) # redirect user to page response = HttpResponseRedirect( request.session.get('work_weixin_oauth_redirect', '/')) response.set_cookie('seahub_auth', user.username + '@' + api_token.key) return response
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 get_user_permission(request, repo_id) != '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 = seafserv_rpc.is_passwd_set(repo_id, request.user.username) if not repo.password_set: op = 'decrypt' if not op: raw_path = gen_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(raw_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]) search_repo_id = None if not repo.encrypted: search_repo_id = repo.id 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, 'search_repo_id': search_repo_id, }, context_instance=RequestContext(request))
def dingtalk_callback(request): if not ENABLE_DINGTALK: return render_error(request, _('Error, please contact administrator.')) state = request.GET.get('state', '') if not state or state != request.session.get('dingtalk_login_state', ''): logger.error('invalid state') return render_error(request, _('Error, please contact administrator.')) timestamp = str(int(time.time() * 1000)).encode('utf-8') appsecret = DINGTALK_QR_CONNECT_APP_SECRET.encode('utf-8') signature = base64.b64encode( hmac.new(appsecret, timestamp, digestmod=sha256).digest()) parameters = { 'accessKey': DINGTALK_QR_CONNECT_APP_ID, 'timestamp': timestamp, 'signature': signature, } code = request.GET.get('code') data = {"tmp_auth_code": code} full_user_info_url = DINGTALK_QR_CONNECT_USER_INFO_URL + '?' + urllib.parse.urlencode( parameters) user_info_resp = requests.post(full_user_info_url, data=json.dumps(data)) user_info = user_info_resp.json()['user_info'] # seahub authenticate user if 'unionid' not in user_info: logger.error('Required user info not found.') logger.error(user_info) return render_error(request, _('Error, please contact administrator.')) auth_user = SocialAuthUser.objects.get_by_provider_and_uid( 'dingtalk', user_info['unionid']) if auth_user: email = auth_user.username else: email = gen_user_virtual_id() SocialAuthUser.objects.add(email, 'dingtalk', user_info['unionid']) try: user = auth.authenticate(remote_user=email) except User.DoesNotExist: user = None except Exception as e: logger.error(e) return render_error(request, _('Error, please contact administrator.')) if not user or not user.is_active: return render_error(request, _('User %s not found or inactive.') % email) # User is valid. Set request.user and persist user in the session # by logging the user in. request.user = user request.session['remember_me'] = DINGTALK_QR_CONNECT_LOGIN_REMEMBER_ME auth.login(request, user) # update user's profile name = user_info['nick'] if 'nick' in user_info else '' if name: profile = Profile.objects.get_profile_by_user(email) if not profile: profile = Profile(user=email) profile.nickname = name.strip() profile.save() user_detail_info = dingtalk_get_detailed_user_info(user_info['unionid']) contact_email = user_detail_info.get('email', '') if contact_email: profile.contact_email = contact_email profile.save() # generate auth token for Seafile client api_token = get_api_token(request) # redirect user to home page response = HttpResponseRedirect( request.session.get('dingtalk_login_redirect', '/')) response.set_cookie('seahub_auth', email + '@' + api_token.key) return response
def view_file(request, repo_id): """ Steps to view file: 1. Get repo id and file path. 2. Check user's permission. 3. Check whether this file can be viewed online. 4.1 Get file content if file is text file. 4.2 Prepare flash if file is document. 4.3 Prepare or use pdfjs if file is pdf. 4.4 Other file return it's raw path. """ username = request.user.username # check arguments repo = get_repo(repo_id) if not repo: raise Http404 path = request.GET.get('p', '/') obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) # construct some varibles u_filename = os.path.basename(path) filename_utf8 = urllib2.quote(u_filename.encode('utf-8')) current_commit = get_commits(repo_id, 0, 1)[0] # Check whether user has permission to view file and get file raw path, # render error page if permission is deny. raw_path, user_perm = get_file_view_path_and_perm(request, repo_id, obj_id, u_filename) if not user_perm: return render_permission_error(request, _(u'Unable to view file')) # get file type and extension filetype, fileext = get_file_type_and_ext(u_filename) img_prev = None img_next = None ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype} # Check file size fsize = get_file_size(obj_id) if fsize > FILE_PREVIEW_MAX_SIZE: err = _(u'File size surpasses %s, can not be opened online.') % \ filesizeformat(FILE_PREVIEW_MAX_SIZE) ret_dict['err'] = err elif filetype in (DOCUMENT, PDF) and fsize > OFFICE_PREVIEW_MAX_SIZE: err = _(u'File size surpasses %s, can not be opened online.') % \ filesizeformat(OFFICE_PREVIEW_MAX_SIZE) ret_dict['err'] = err else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, raw_path, ret_dict) if filetype == MARKDOWN: c = ret_dict['file_content'] ret_dict['file_content'] = convert_md_link(c, repo_id, username) elif filetype == DOCUMENT: handle_document(raw_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(raw_path, obj_id, fileext, ret_dict) elif filetype == IMAGE: parent_dir = os.path.dirname(path) dirs = list_dir_by_path(current_commit.id, parent_dir) if not dirs: raise Http404 img_list = [] for dirent in dirs: if not stat.S_ISDIR(dirent.props.mode): fltype, flext = get_file_type_and_ext(dirent.obj_name) if fltype == 'Image': img_list.append(dirent.obj_name) if len(img_list) > 1: img_list.sort(lambda x, y : cmp(x.lower(), y.lower())) cur_img_index = img_list.index(u_filename) if cur_img_index != 0: img_prev = os.path.join(parent_dir, img_list[cur_img_index - 1]) if cur_img_index != len(img_list) - 1: img_next = os.path.join(parent_dir, img_list[cur_img_index + 1]) else: pass # generate file path navigator zipped = gen_path_link(path, repo.name) # file shared link l = FileShare.objects.filter(repo_id=repo_id).filter( username=username).filter(path=path) fileshare = l[0] if len(l) > 0 else None http_or_https = request.is_secure() and 'https' or 'http' domain = RequestSite(request).domain if fileshare: file_shared_link = gen_shared_link(request, fileshare.token, 'f') else: file_shared_link = '' # my contacts used in shared link autocomplete contacts = Contact.objects.filter(user_email=username) """List repo groups""" # Get groups this repo is shared. if request.user.org: org_id = request.user.org['org_id'] repo_shared_groups = get_org_groups_by_repo(org_id, repo_id) else: repo_shared_groups = get_shared_groups_by_repo(repo_id) # Filter out groups that user in joined. groups = [ x for x in repo_shared_groups if is_group_user(x.id, username)] if len(groups) > 1: ctx = {} ctx['groups'] = groups repogrp_str = render_to_string("snippets/repo_group_list.html", ctx) else: repogrp_str = '' file_path_hash = md5_constructor(urllib2.quote(path.encode('utf-8'))).hexdigest()[:12] # fetch file contributors and latest contributor contributors, last_modified, last_commit_id = get_file_contributors(repo_id, path.encode('utf-8'), file_path_hash, obj_id) latest_contributor = contributors[0] if contributors else None # check whether file is starred is_starred = False org_id = -1 if request.user.org: org_id = request.user.org['org_id'] is_starred = is_file_starred(username, repo.id, path.encode('utf-8'), org_id) template = 'view_file_%s.html' % ret_dict['filetype'].lower() search_repo_id = None if not repo.encrypted: search_repo_id = repo.id return render_to_response(template, { 'repo': repo, 'obj_id': obj_id, 'filename': u_filename, 'path': path, 'zipped': zipped, 'current_commit': current_commit, 'fileext': fileext, 'raw_path': raw_path, 'fileshare': fileshare, 'protocol': http_or_https, 'domain': domain, 'file_shared_link': file_shared_link, 'contacts': contacts, 'err': ret_dict['err'], 'file_content': ret_dict['file_content'], 'file_enc': ret_dict['file_enc'], 'encoding': ret_dict['encoding'], 'file_encoding_list':ret_dict['file_encoding_list'], 'html_exists': ret_dict['html_exists'], 'html_detail': ret_dict.get('html_detail', {}), 'filetype': ret_dict['filetype'], "applet_root": get_ccnetapplet_root(), 'groups': groups, 'use_pdfjs':USE_PDFJS, 'contributors': contributors, 'latest_contributor': latest_contributor, 'last_modified': last_modified, 'last_commit_id': last_commit_id, 'repo_group_str': repogrp_str, 'is_starred': is_starred, 'user_perm': user_perm, 'img_prev': img_prev, 'img_next': img_next, 'search_repo_id': search_repo_id, }, context_instance=RequestContext(request))
def view_file_via_shared_dir(request, token): assert token is not None # Checked by URLconf try: fileshare = FileShare.objects.get(token=token) except FileShare.DoesNotExist: raise Http404 shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = request.GET.get('p', '').rstrip('/') if not path: raise Http404 if not path.startswith( fileshare.path): # Can not view upper dir of shared dir raise Http404 zipped = gen_path_link(path, '') obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) img_prev = None img_next = None # get file content ret_dict = { 'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype } fsize = get_file_size(obj_id) exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype) if exceeds_limit: err = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == SPREADSHEET: handle_spreadsheet(inner_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) elif filetype == IMAGE: current_commit = get_commits(repo_id, 0, 1)[0] parent_dir = os.path.dirname(path) dirs = seafile_api.list_dir_by_commit_and_path( current_commit.id, parent_dir) if not dirs: raise Http404 img_list = [] for dirent in dirs: if not stat.S_ISDIR(dirent.props.mode): fltype, flext = get_file_type_and_ext(dirent.obj_name) if fltype == 'Image': img_list.append(dirent.obj_name) if len(img_list) > 1: img_list.sort(lambda x, y: cmp(x.lower(), y.lower())) cur_img_index = img_list.index(filename) if cur_img_index != 0: img_prev = posixpath.join(parent_dir, img_list[cur_img_index - 1]) if cur_img_index != len(img_list) - 1: img_next = posixpath.join(parent_dir, img_list[cur_img_index + 1]) # send statistic messages if ret_dict['filetype'] != 'Unknown': try: obj_size = seafserv_threaded_rpc.get_file_size(obj_id) send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, obj_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
def view_shared_dir(request, fileshare): token = fileshare.token password_check_passed, err_msg = check_share_link_common(request, fileshare) if not password_check_passed: d = {'token': token, 'view_name': 'view_shared_dir', 'err_msg': err_msg} return render(request, 'share_access_validation.html', d) username = fileshare.username repo_id = fileshare.repo_id # Get path from frontend, use '/' if missing, and construct request path # with fileshare.path to real path, used to fetch dirents by RPC. req_path = request.GET.get('p', '/') req_path = normalize_dir_path(req_path) if req_path == '/': real_path = fileshare.path else: real_path = posixpath.join(fileshare.path, req_path.lstrip('/')) real_path = normalize_dir_path(real_path) repo = get_repo(repo_id) if not repo: raise Http404 if repo.encrypted or not \ seafile_api.check_permission_by_path(repo_id, '/', username): return render_error(request, _('Permission denied')) # Check path still exist, otherwise show error if not seafile_api.get_dir_id_by_path(repo.id, fileshare.path): return render_error(request, _('"%s" does not exist.') % fileshare.path) if fileshare.path == '/': # use repo name as dir name if share whole library dir_name = repo.name else: dir_name = os.path.basename(real_path[:-1]) current_commit = seaserv.get_commits(repo_id, 0, 1)[0] file_list, dir_list, dirent_more = get_repo_dirents(request, repo, current_commit, real_path) # generate dir navigator if fileshare.path == '/': zipped = gen_path_link(req_path, repo.name) else: zipped = gen_path_link(req_path, os.path.basename(fileshare.path[:-1])) if req_path == '/': # When user view the root of shared dir.. # increase shared link view_cnt, fileshare = FileShare.objects.get(token=token) fileshare.view_cnt = F('view_cnt') + 1 fileshare.save() traffic_over_limit = user_traffic_over_limit(fileshare.username) permissions = fileshare.get_permissions() # mode to view dir/file items mode = request.GET.get('mode', 'list') if mode != 'list': mode = 'grid' thumbnail_size = THUMBNAIL_DEFAULT_SIZE if mode == 'list' else THUMBNAIL_SIZE_FOR_GRID for f in file_list: file_type, file_ext = get_file_type_and_ext(f.obj_name) if file_type == IMAGE: f.is_img = True if file_type == VIDEO: f.is_video = True if file_type in (IMAGE, XMIND) or \ (file_type == VIDEO and ENABLE_VIDEO_THUMBNAIL): if os.path.exists(os.path.join(THUMBNAIL_ROOT, str(thumbnail_size), f.obj_id)): req_image_path = posixpath.join(req_path, f.obj_name) src = get_share_link_thumbnail_src(token, thumbnail_size, req_image_path) f.encoded_thumbnail_src = urlquote(src) # for 'upload file' no_quota = True if seaserv.check_quota(repo_id) < 0 else False template = 'view_shared_dir_react.html' dir_share_link = request.path desc_for_ogp = _('Share link for %s.') % dir_name return render(request, template, { 'repo': repo, 'token': token, 'path': req_path, 'username': username, 'dir_name': dir_name, 'dir_path': real_path, 'file_list': file_list, 'dir_list': dir_list, 'zipped': zipped, 'traffic_over_limit': traffic_over_limit, 'no_quota': no_quota, 'permissions': permissions, 'mode': mode, 'thumbnail_size': thumbnail_size, 'dir_share_link': dir_share_link, 'desc_for_ogp': desc_for_ogp, 'enable_share_link_report_abuse': ENABLE_SHARE_LINK_REPORT_ABUSE, 'enable_video_thumbnail': ENABLE_VIDEO_THUMBNAIL, })
def view_shared_dir(request, fileshare): token = fileshare.token password_check_passed, err_msg = check_share_link_common( request, fileshare) if not password_check_passed: d = { 'token': token, 'view_name': 'view_shared_dir', 'err_msg': err_msg } return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) username = fileshare.username repo_id = fileshare.repo_id # Get path from frontend, use '/' if missing, and construct request path # with fileshare.path to real path, used to fetch dirents by RPC. req_path = request.GET.get('p', '/') if req_path[-1] != '/': req_path += '/' if req_path == '/': real_path = fileshare.path else: real_path = posixpath.join(fileshare.path, req_path.lstrip('/')) if real_path[-1] != '/': # Normalize dir path real_path += '/' repo = get_repo(repo_id) if not repo: raise Http404 # Check path still exist, otherwise show error if not seafile_api.get_dir_id_by_path(repo.id, fileshare.path): return render_error(request, _('"%s" does not exist.') % fileshare.path) if fileshare.path == '/': # use repo name as dir name if share whole library dir_name = repo.name else: dir_name = os.path.basename(real_path[:-1]) current_commit = seaserv.get_commits(repo_id, 0, 1)[0] file_list, dir_list, dirent_more = get_repo_dirents( request, repo, current_commit, real_path) # generate dir navigator if fileshare.path == '/': zipped = gen_path_link(req_path, repo.name) else: zipped = gen_path_link(req_path, os.path.basename(fileshare.path[:-1])) if req_path == '/': # When user view the root of shared dir.. # increase shared link view_cnt, fileshare = FileShare.objects.get(token=token) fileshare.view_cnt = F('view_cnt') + 1 fileshare.save() traffic_over_limit = user_traffic_over_limit(fileshare.username) # mode to view dir/file items mode = request.GET.get('mode', 'list') if mode != 'list': mode = 'grid' thumbnail_size = THUMBNAIL_DEFAULT_SIZE if mode == 'list' else THUMBNAIL_SIZE_FOR_GRID for f in file_list: file_type, file_ext = get_file_type_and_ext(f.obj_name) if file_type == IMAGE: f.is_img = True if file_type == VIDEO: f.is_video = True if (file_type == IMAGE or file_type == VIDEO) and ENABLE_THUMBNAIL: if os.path.exists( os.path.join(THUMBNAIL_ROOT, str(thumbnail_size), f.obj_id)): req_image_path = posixpath.join(req_path, f.obj_name) src = get_share_link_thumbnail_src(token, thumbnail_size, req_image_path) f.encoded_thumbnail_src = urlquote(src) return render_to_response('view_shared_dir.html', { 'repo': repo, 'token': token, 'path': req_path, 'username': username, 'dir_name': dir_name, 'file_list': file_list, 'dir_list': dir_list, 'zipped': zipped, 'traffic_over_limit': traffic_over_limit, 'ENABLE_THUMBNAIL': ENABLE_THUMBNAIL, 'mode': mode, 'thumbnail_size': thumbnail_size, }, context_instance=RequestContext(request))
def view_shared_dir(request, token): assert token is not None # Checked by URLconf fileshare = FileShare.objects.get_valid_dir_link_by_token(token) if fileshare is None: raise Http404 if fileshare.is_encrypted(): if not check_share_link_access(request, token): d = { 'token': token, 'view_name': 'view_shared_dir', } if request.method == 'POST': post_values = request.POST.copy() post_values['enc_password'] = fileshare.password form = SharedLinkPasswordForm(post_values) d['form'] = form if form.is_valid(): set_share_link_access(request, token) else: return render_to_response( 'share_access_validation.html', d, context_instance=RequestContext(request)) else: return render_to_response( 'share_access_validation.html', d, context_instance=RequestContext(request)) username = fileshare.username repo_id = fileshare.repo_id # Get path from frontend, use '/' if missing, and construct request path # with fileshare.path to real path, used to fetch dirents by RPC. req_path = request.GET.get('p', '/') if req_path[-1] != '/': req_path += '/' if req_path == '/': real_path = fileshare.path else: real_path = posixpath.join(fileshare.path, req_path.lstrip('/')) if real_path[-1] != '/': # Normalize dir path real_path += '/' repo = get_repo(repo_id) if not repo: raise Http404 # Check path still exist, otherwise show error if not seafile_api.get_dir_id_by_path(repo.id, fileshare.path): return render_error(request, _('"%s" does not exist.') % fileshare.path) # download shared dir if request.GET.get('dl', '') == '1': return _download_dir_from_share_link(request, fileshare, repo, real_path) if fileshare.path == '/': # use repo name as dir name if share whole library dir_name = repo.name else: dir_name = os.path.basename(real_path[:-1]) current_commit = seaserv.get_commits(repo_id, 0, 1)[0] file_list, dir_list, dirent_more = get_repo_dirents( request, repo, current_commit, real_path) # generate dir navigator if fileshare.path == '/': zipped = gen_path_link(req_path, repo.name) else: zipped = gen_path_link(req_path, os.path.basename(fileshare.path[:-1])) if req_path == '/': # When user view the root of shared dir.. # increase shared link view_cnt, fileshare = FileShare.objects.get(token=token) fileshare.view_cnt = F('view_cnt') + 1 fileshare.save() traffic_over_limit = user_traffic_over_limit(fileshare.username) for f in file_list: file_type, file_ext = get_file_type_and_ext(f.obj_name) if file_type == IMAGE: f.is_img = True if allow_generate_thumbnail(username, repo, f): f.allow_generate_thumbnail = True if os.path.exists( os.path.join(THUMBNAIL_ROOT, THUMBNAIL_DEFAULT_SIZE, f.obj_id)): f.thumbnail_src = get_thumbnail_src(repo.id, f.obj_id, THUMBNAIL_DEFAULT_SIZE) return render_to_response('view_shared_dir.html', { 'repo': repo, 'token': token, 'path': req_path, 'username': username, 'dir_name': dir_name, 'file_list': file_list, 'dir_list': dir_list, 'zipped': zipped, 'traffic_over_limit': traffic_over_limit, 'ENABLE_THUMBNAIL': ENABLE_THUMBNAIL, 'PREVIEW_DEFAULT_SIZE': PREVIEW_DEFAULT_SIZE, }, context_instance=RequestContext(request))