def download_file(request, repo_id, obj_id): """Download file. Arguments: - `request`: - `repo_id`: - `obj_id`: """ username = request.user.username repo = get_repo(repo_id) if not repo: raise Http404 if repo.encrypted and not seafile_api.is_password_set(repo_id, username): return HttpResponseRedirect(reverse('repo', args=[repo_id])) # If vistor's file shared token in url params matches the token in db, # then we know the vistor is from file shared link. share_token = request.GET.get('t', '') fileshare = FileShare.objects.get( token=share_token) if share_token else None shared_by = None if fileshare: from_shared_link = True shared_by = fileshare.username else: from_shared_link = False if from_shared_link: # check whether owner's traffic over the limit if user_traffic_over_limit(fileshare.username): messages.error( request, _(u'Unable to access file: share link traffic is used up.')) next = request.META.get('HTTP_REFERER', settings.SITE_ROOT) return HttpResponseRedirect(next) # Permission check and generate download link path = request.GET.get('p', '') if check_repo_access_permission(repo_id, request.user) or \ get_file_access_permission(repo_id, path, username) or from_shared_link: # Get a token to access file token = seafserv_rpc.web_get_access_token(repo_id, obj_id, 'download', username) else: messages.error(request, _(u'Unable to download file')) next = request.META.get('HTTP_REFERER', settings.SITE_ROOT) return HttpResponseRedirect(next) # send stats message if from_shared_link: try: file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) send_message( 'seahub.stats', 'file-download\t%s\t%s\t%s\t%s' % (repo.id, shared_by, obj_id, file_size)) except Exception, e: logger.error('Error when sending file-download message: %s' % str(e))
def repo_revert_history(request, repo_id): next_page = request.META.get('HTTP_REFERER', None) if not next_page: next_page = settings.SITE_ROOT repo = get_repo(repo_id) if not repo: messages.error(request, _("Library does not exist")) return HttpResponseRedirect(next_page) # perm check perm = check_folder_permission(request, repo_id, '/') username = request.user.username repo_owner = seafile_api.get_repo_owner(repo.id) if perm is None or repo_owner != username: messages.error(request, _("Permission denied")) return HttpResponseRedirect(next_page) 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) commit_id = request.GET.get('commit_id', '') if not commit_id: return render_error(request, _('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 as e: if e.msg == 'Bad arguments': return render_error(request, _('Invalid arguments.')) elif e.msg == 'No such repo': return render_error(request, _('Library does not exist')) elif e.msg == "Commit doesn't exist": return render_error(request, _('History you specified does not exist')) else: return render_error(request, _('Unknown error')) return HttpResponseRedirect(next_page)
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(request, 'options/set_user_options.html', {}) if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not seafile_api.is_password_set(repo_id, username): return render(request, 'decrypt_repo_form.html', { 'repo': repo, 'next': request.get_full_path(), }) if repo.enc_version == 2 and not server_crypto: return render_error( request, _('Files in this library can not be viewed online.')) return func(request, *args, **kwargs)
def repo_history_changes(request, repo_id): changes = {} content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _('Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) # perm check if check_folder_permission(request, repo_id, '/') is None: if request.user.is_staff is True: pass # Allow system staff to check repo changes else: err_msg = _("Permission denied") return HttpResponse(json.dumps({"error": err_msg}), status=403, content_type=content_type) 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 if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not seafile_api.is_password_set(repo_id, username): err_msg = _('Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) commit_id = request.GET.get('commit_id', '') if not commit_id: err_msg = _('Argument missing') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) changes = get_diff(repo_id, '', commit_id) c = get_commit(repo.id, repo.version, commit_id) if c.parent_id is None: # A commit is a first commit only if it's parent id is None. changes['cmt_desc'] = repo.desc elif c.second_parent_id is None: # Normal commit only has one parent. if c.desc.startswith('Changed library'): changes['cmt_desc'] = _('Changed library name or description') else: # A commit is a merge only if it has two parents. changes['cmt_desc'] = _('No conflict in the merge.') changes['date_time'] = tsstr_sec(c.ctime) return HttpResponse(json.dumps(changes), content_type=content_type)
def list_dir_more(request, repo_id): """ List 'more' entries in a directory with AJAX. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, username) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) if repo.encrypted and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) path = request.GET.get('p', '/') if path[-1] != '/': path = path + '/' offset = int(request.GET.get('start')) if not offset: err_msg = _(u'Argument missing') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) more_start = None file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset, limit=100) if dirent_more: more_start = offset + 100 ctx = { 'repo': repo, 'user_perm': user_perm, 'path': path, 'dir_list': dir_list, 'file_list': file_list, 'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY, } html = render_to_string('snippets/repo_dirents.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({'html': html, 'dirent_more': dirent_more, 'more_start': more_start}), content_type=content_type)
def test_password(encrypted_repo): old_passwd = '123' new_passwd = '456' assert api.set_passwd(encrypted_repo.id, encrypted_repo.name, old_passwd) == 0 assert api.get_decrypt_key(encrypted_repo.id, encrypted_repo.name) api.change_repo_passwd(encrypted_repo.repo_id, old_passwd, new_passwd, encrypted_repo.name) == 0 assert api.set_passwd(encrypted_repo.id, encrypted_repo.name, new_passwd) == 0 assert api.is_password_set(encrypted_repo.id, encrypted_repo.name) assert api.unset_passwd(encrypted_repo.id, encrypted_repo.name, new_passwd) == 0 assert api.is_password_set(encrypted_repo.id, encrypted_repo.name) == 0
def test_encrypted_repo(rpc, enc_version): test_repo_name = 'test_enc_repo' test_repo_desc = 'test_enc_repo' test_repo_passwd = 'test_enc_repo' if rpc == 'create_repo': repo_id = api.create_repo(test_repo_name, test_repo_desc, USER, test_repo_passwd, enc_version) assert repo_id else: if enc_version == 2: repo_id = 'd17bf8ca-3019-40ee-8fdb-0258c89fb762' elif enc_version == 3: repo_id = 'd17bf8ca-3019-40ee-8fdb-0258c89fb763' else: repo_id = 'd17bf8ca-3019-40ee-8fdb-0258c89fb764' enc_info = api.generate_magic_and_random_key(enc_version, repo_id, test_repo_passwd) assert enc_info ret_repo_id = api.create_enc_repo(repo_id, test_repo_name, test_repo_desc, USER, enc_info.magic, enc_info.random_key, enc_info.salt, enc_version) assert ret_repo_id == repo_id repo = api.get_repo(repo_id) assert repo assert repo.enc_version == enc_version assert len(repo.magic) == 64 assert len(repo.random_key) == 96 if enc_version == 3 or enc_version == 4: assert len(repo.salt) == 64 new_passwd = 'new password' assert api.set_passwd(repo.id, USER, test_repo_passwd) == 0 assert api.get_decrypt_key(repo.id, USER) api.change_repo_passwd(repo.repo_id, test_repo_passwd, new_passwd, USER) == 0 assert api.set_passwd(repo.id, USER, new_passwd) == 0 assert api.is_password_set(repo.id, USER) assert api.unset_passwd(repo.id, USER) == 0 assert api.is_password_set(repo.id, USER) == 0 api.remove_repo(repo_id)
def get(self, request, repo_id): """ Return repo info Permission checking: 1. all authenticated user can perform this action. """ # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check permission = check_folder_permission(request, repo_id, '/') if permission is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) username = request.user.username lib_need_decrypt = False if repo.encrypted \ and not seafile_api.is_password_set(repo.id, username): lib_need_decrypt = True repo_owner = get_repo_owner(request, repo_id) try: has_been_shared_out = repo_has_been_shared_out(request, repo_id) except Exception as e: has_been_shared_out = False logger.error(e) result = { "repo_id": repo.id, "repo_name": repo.name, "owner_email": repo_owner, "owner_name": email2nickname(repo_owner), "owner_contact_email": email2contact_email(repo_owner), "size": repo.size, "encrypted": repo.encrypted, "file_count": repo.file_count, "permission": permission, "no_quota": True if seafile_api.check_quota(repo_id) < 0 else False, "is_admin": is_repo_admin(username, repo_id), "is_virtual": repo.is_virtual, "has_been_shared_out": has_been_shared_out, "lib_need_decrypt": lib_need_decrypt, "last_modified": timestamp_to_isoformat_timestr(repo.last_modify), "status": normalize_repo_status_code(repo.status), } return Response(result)
def get(self, request, repo_id): """ Return repo info Permission checking: 1. all authenticated user can perform this action. """ # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check permission = check_folder_permission(request, repo_id, '/') if permission is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) username = request.user.username lib_need_decrypt = False if repo.encrypted \ and not seafile_api.is_password_set(repo.id, username): lib_need_decrypt = True repo_owner = get_repo_owner(request, repo_id) try: has_been_shared_out = repo_has_been_shared_out(request, repo_id) except Exception as e: has_been_shared_out = False logger.error(e) result = { "repo_id": repo.id, "repo_name": repo.name, "owner_email": repo_owner, "owner_name": email2nickname(repo_owner), "owner_contact_email": email2contact_email(repo_owner), "size": repo.size, "encrypted": repo.encrypted, "file_count": repo.file_count, "permission": permission, "no_quota": True if seafile_api.check_quota(repo_id) < 0 else False, "is_admin": is_repo_admin(username, repo_id), "is_virtual": repo.is_virtual, "has_been_shared_out": has_been_shared_out, "lib_need_decrypt": lib_need_decrypt, "last_modified": timestamp_to_isoformat_timestr(repo.last_modify), } return Response(result)
def download_file(request, repo_id, obj_id): """Download file. Arguments: - `request`: - `repo_id`: - `obj_id`: """ username = request.user.username repo = get_repo(repo_id) if not repo: raise Http404 if repo.encrypted and not seafile_api.is_password_set(repo_id, username): return HttpResponseRedirect(reverse("repo", args=[repo_id])) # If vistor's file shared token in url params matches the token in db, # then we know the vistor is from file shared link. share_token = request.GET.get("t", "") fileshare = FileShare.objects.get(token=share_token) if share_token else None shared_by = None if fileshare: from_shared_link = True shared_by = fileshare.username else: from_shared_link = False if from_shared_link: # check whether owner's traffic over the limit if user_traffic_over_limit(fileshare.username): messages.error(request, _(u"Unable to access file: share link traffic is used up.")) next = request.META.get("HTTP_REFERER", settings.SITE_ROOT) return HttpResponseRedirect(next) # Permission check and generate download link path = request.GET.get("p", "") if ( check_repo_access_permission(repo_id, request.user) or get_file_access_permission(repo_id, path, username) or from_shared_link ): # Get a token to access file token = seafserv_rpc.web_get_access_token(repo_id, obj_id, "download", username) else: messages.error(request, _(u"Unable to download file")) next = request.META.get("HTTP_REFERER", settings.SITE_ROOT) return HttpResponseRedirect(next) # send stats message if from_shared_link: try: file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) send_message("seahub.stats", "file-download\t%s\t%s\t%s\t%s" % (repo.id, shared_by, obj_id, file_size)) except Exception, e: logger.error("Error when sending file-download message: %s" % str(e))
def get_current_commit(request, repo_id): if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) if new_merge_with_no_conflict(head_commit): head_commit = get_commit_before_new_merge(head_commit) ctx = {'repo': repo, 'current_commit': head_commit} html = render_to_string('snippets/current_commit.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({'html': html}), content_type=content_type)
def post(self, request, repo_id, commit_id, format=None): """ revert commit in repo history Permission checking: 1. only repo owner can perform this action. """ username = request.user.username # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) commit = seafile_api.get_commit(repo.id, repo.version, commit_id) if not commit: error_msg = 'Commit %s not found.' % commit_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check has_perm = is_repo_owner(request, repo.id, username) if not has_perm: repo_owner = get_repo_owner(request, repo_id) # department admin if '@seafile_group' in repo_owner: group_id = get_group_id_by_repo_owner(repo_owner) has_perm = is_group_admin(group_id, username) if not has_perm: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # main if repo.encrypted: ret = seafile_api.is_password_set(repo_id, username) is_decrypted = False if ret == 0 else True if not is_decrypted: error_msg = _('This library has not been decrypted.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: seafile_api.revert_repo(repo_id, commit_id, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True})
def get_current_commit(request, repo_id): if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, request.user) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) if new_merge_with_no_conflict(head_commit): head_commit = get_commit_before_new_merge(head_commit) ctx = { 'repo': repo, 'current_commit': head_commit } html = render_to_string('snippets/current_commit.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({'html': html}), content_type=content_type)
def get_current_commit(request, repo_id): if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, username) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) ctx = {'repo': repo, 'current_commit': head_commit} html = render_to_string('snippets/current_commit.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({'html': html}), content_type=content_type)
def _get_events_inner(ev_session, username, start, limit, org_id=None): '''Read events from seafevents database, and remove events that are no longer valid Return 'limit' events or less than 'limit' events if no more events remain ''' valid_events = [] next_start = start while True: if org_id > 0: events = seafevents.get_org_user_events( ev_session, org_id, username, next_start, limit) else: events = seafevents.get_user_events(ev_session, username, next_start, limit) if not events: break for ev in events: if ev.etype == 'repo-update': repo = seafile_api.get_repo(ev.repo_id) if not repo: # delete the update event for repo which has been deleted seafevents.delete_event(ev_session, ev.uuid) continue if repo.encrypted: repo.password_set = seafile_api.is_password_set( repo.id, username) ev.repo = repo ev.commit = seaserv.get_commit(repo.id, repo.version, ev.commit_id) valid_events.append(ev) if len(valid_events) == limit: break if len(valid_events) == limit: break next_start = next_start + len(valid_events) return valid_events
def _get_events_inner(ev_session, username, start, limit, org_id=None): '''Read events from seafevents database, and remove events that are no longer valid Return 'limit' events or less than 'limit' events if no more events remain ''' valid_events = [] next_start = start while True: if org_id > 0: events = seafevents.get_org_user_events(ev_session, org_id, username, next_start, limit) else: events = seafevents.get_user_events(ev_session, username, next_start, limit) if not events: break for ev in events: if ev.etype == 'repo-update': repo = seafile_api.get_repo(ev.repo_id) if not repo: # delete the update event for repo which has been deleted seafevents.delete_event(ev_session, ev.uuid) continue if repo.encrypted: repo.password_set = seafile_api.is_password_set( repo.id, username) ev.repo = repo ev.commit = seaserv.get_commit(repo.id, repo.version, ev.commit_id) valid_events.append(ev) if len(valid_events) == limit: break if len(valid_events) == limit: break next_start = next_start + len(valid_events) return valid_events
def remove_org_repo_passwds(self, org_id): """ Remove all org repo decryption passwords stored on server. """ from seahub.utils import get_user_repos owned_repos, shared_repos, groups_repos, public_repos = get_user_repos(self.email, org_id=org_id) def has_repo(repos, repo): for r in repos: if repo.id == r.id: return True return False passwd_setted_repos = [] for r in owned_repos + shared_repos + groups_repos + public_repos: if not has_repo(passwd_setted_repos, r) and r.encrypted and \ seafile_api.is_password_set(r.id, self.email): passwd_setted_repos.append(r) for r in passwd_setted_repos: unset_repo_passwd(r.id, self.email)
def get_current_commit(request, repo_id): if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, username) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) ctx = { 'repo': repo, 'current_commit': head_commit } html = render_to_string('snippets/current_commit.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({'html': html}), content_type=content_type)
def file_edit(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 if request.method == 'POST': return file_edit_submit(request, repo_id) if check_repo_access_permission(repo_id, request.user) != 'rw': return render_permission_error(request, _(u'Unable to edit file')) path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) filename = urllib2.quote(u_filename.encode('utf-8')) head_id = repo.head_cmmt_id obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'The file does not exist.')) token = web_get_access_token(repo_id, obj_id, 'view', request.user.username) # generate path and link zipped = gen_path_link(path, repo.name) filetype, fileext = get_file_type_and_ext(filename) op = None err = '' file_content = None encoding = None file_encoding_list = FILE_ENCODING_LIST if filetype == TEXT or filetype == MARKDOWN or filetype == SF: if repo.encrypted: repo.password_set = seafile_api.is_password_set( repo_id, request.user.username) if not repo.password_set: op = 'decrypt' if not op: inner_path = gen_inner_file_get_url(token, filename) file_enc = request.GET.get('file_enc', 'auto') if not file_enc in FILE_ENCODING_LIST: file_enc = 'auto' err, file_content, encoding = repo_file_get(inner_path, file_enc) if encoding and encoding not in FILE_ENCODING_LIST: file_encoding_list.append(encoding) else: err = _(u'Edit online is not offered for this type of file.') # Redirect to different place according to from page when user click # cancel button on file edit page. cancel_url = reverse('repo_view_file', args=[repo.id ]) + '?p=' + urlquote(path) page_from = request.GET.get('from', '') gid = request.GET.get('gid', '') wiki_name = os.path.splitext(u_filename)[0] if page_from == 'wiki_page_edit' or page_from == 'wiki_page_new': cancel_url = reverse('group_wiki', args=[gid, wiki_name]) elif page_from == 'personal_wiki_page_edit' or page_from == 'personal_wiki_page_new': cancel_url = reverse('personal_wiki', args=[wiki_name]) return render_to_response('file_edit.html', { 'repo': repo, 'u_filename': u_filename, 'wiki_name': wiki_name, 'path': path, 'zipped': zipped, 'filetype': filetype, 'fileext': fileext, 'op': op, 'err': err, 'file_content': file_content, 'encoding': encoding, 'file_encoding_list': file_encoding_list, 'head_id': head_id, 'from': page_from, 'gid': gid, 'cancel_url': cancel_url, }, context_instance=RequestContext(request))
def file_edit_submit(request, repo_id): content_type = 'application/json; charset=utf-8' def error_json(error_msg=_(u'Internal Error'), op=None): return HttpResponse(json.dumps({ 'error': error_msg, 'op': op }), status=400, content_type=content_type) username = request.user.username if check_repo_access_permission(repo_id, request.user) != 'rw': return error_json(_(u'Permission denied')) repo = get_repo(repo_id) if not repo: return error_json(_(u'The library does not exist.')) if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, username) if not repo.password_set: return error_json(_(u'The library is encrypted.'), 'decrypt') content = request.POST.get('content') encoding = request.POST.get('encoding') path = request.GET.get('p') if content is None or not path or encoding not in ["gbk", "utf-8"]: return error_json(_(u'Invalid arguments')) head_id = request.GET.get('head', None) content = content.encode(encoding) # first dump the file content to a tmp file, then update the file fd, tmpfile = mkstemp() def remove_tmp_file(): try: os.remove(tmpfile) except: pass try: bytesWritten = os.write(fd, content) except: bytesWritten = -1 finally: os.close(fd) if bytesWritten != len(content): remove_tmp_file() return error_json() req_from = request.GET.get('from', '') if req_from == 'wiki_page_edit' or req_from == 'wiki_page_new': try: gid = int(request.GET.get('gid', 0)) except ValueError: gid = 0 wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse('group_wiki', args=[gid, wiki_name]) elif req_from == 'personal_wiki_page_edit' or req_from == 'personal_wiki_page_new': wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse('personal_wiki', args=[wiki_name]) else: next = reverse('repo_view_file', args=[repo_id ]) + '?p=' + urlquote(path) parent_dir = os.path.dirname(path).encode('utf-8') filename = os.path.basename(path).encode('utf-8') try: seafserv_threaded_rpc.put_file(repo_id, tmpfile, parent_dir, filename, username, head_id) remove_tmp_file() return HttpResponse(json.dumps({'href': next}), content_type=content_type) except SearpcError, e: remove_tmp_file() return error_json(str(e))
def list_lib_dir(request, repo_id): ''' New ajax API for list library directory ''' content_type = 'application/json; charset=utf-8' result = {} repo = get_repo(repo_id) if not repo: err_msg = _('Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username path = request.GET.get('p', '/') path = normalize_dir_path(path) dir_id = seafile_api.get_dir_id_by_path(repo.id, path) if not dir_id: err_msg = 'Folder not found.' return HttpResponse(json.dumps({'error': err_msg}), status=404, content_type=content_type) # perm for current dir user_perm = check_folder_permission(request, repo_id, path) if not user_perm: return convert_repo_path_when_can_not_view_folder( request, repo_id, path) if repo.encrypted \ and not seafile_api.is_password_set(repo.id, username): err_msg = _('Library is encrypted.') return HttpResponse(json.dumps({ 'error': err_msg, 'lib_need_decrypt': True }), status=403, content_type=content_type) head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id) if not head_commit: err_msg = _('Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) dir_list = [] file_list = [] dirs = seafserv_threaded_rpc.list_dir_with_perm(repo_id, path, dir_id, username, -1, -1) starred_files = get_dir_starred_files(username, repo_id, path) for dirent in dirs: dirent.last_modified = dirent.mtime if stat.S_ISDIR(dirent.mode): dpath = posixpath.join(path, dirent.obj_name) if dpath[-1] != '/': dpath += '/' dir_list.append(dirent) else: if repo.version == 0: file_size = seafile_api.get_file_size(repo.store_id, repo.version, dirent.obj_id) else: file_size = dirent.size dirent.file_size = file_size if file_size else 0 dirent.starred = False fpath = posixpath.join(path, dirent.obj_name) if fpath in starred_files: dirent.starred = True file_list.append(dirent) 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) result["repo_owner"] = repo_owner result["is_repo_owner"] = False result["has_been_shared_out"] = False result["is_admin"] = is_repo_admin(username, repo_id) if repo_owner == username: result["is_repo_owner"] = True try: result["has_been_shared_out"] = repo_has_been_shared_out( request, repo_id) except Exception as e: logger.error(e) if result["is_admin"]: result["has_been_shared_out"] = True result["is_virtual"] = repo.is_virtual result["repo_name"] = repo.name result["user_perm"] = user_perm # check quota for fileupload result["no_quota"] = True if seaserv.check_quota(repo.id) < 0 else False result["encrypted"] = repo.encrypted dirent_list = [] for d in dir_list: d_ = {} d_['is_dir'] = True d_['obj_name'] = d.obj_name d_['last_modified'] = d.last_modified d_['last_update'] = translate_seahub_time(d.last_modified) d_['p_dpath'] = posixpath.join(path, d.obj_name) d_['perm'] = d.permission # perm for sub dir in current dir dirent_list.append(d_) size = int(request.GET.get('thumbnail_size', THUMBNAIL_DEFAULT_SIZE)) for f in file_list: f_ = {} f_['is_file'] = True f_['obj_name'] = f.obj_name f_['last_modified'] = f.last_modified f_['last_update'] = translate_seahub_time(f.last_modified) f_['starred'] = f.starred f_['file_size'] = filesizeformat(f.file_size) f_['obj_id'] = f.obj_id f_['perm'] = f.permission # perm for file in current dir if not repo.encrypted and ENABLE_THUMBNAIL: # used for providing a way to determine # if send a request to create thumbnail. fileExt = os.path.splitext(f.obj_name)[1][1:].lower() file_type = FILEEXT_TYPE_MAP.get(fileExt) if file_type == IMAGE: f_['is_img'] = True if file_type == VIDEO and ENABLE_VIDEO_THUMBNAIL: f_['is_video'] = True if file_type == XMIND: f_['is_xmind'] = True if file_type in (IMAGE, XMIND) or \ file_type == VIDEO and ENABLE_VIDEO_THUMBNAIL: # if thumbnail has already been created, return its src. # Then web browser will use this src to get thumbnail instead of # recreating it. thumbnail_file_path = os.path.join(THUMBNAIL_ROOT, str(size), f.obj_id) thumbnail_exist = os.path.exists(thumbnail_file_path) if thumbnail_exist: file_path = posixpath.join(path, f.obj_name) src = get_thumbnail_src(repo_id, size, file_path) f_['encoded_thumbnail_src'] = urlquote(src) if is_pro_version(): f_['is_locked'] = True if f.is_locked else False f_['lock_owner'] = f.lock_owner f_['lock_owner_name'] = email2nickname(f.lock_owner) f_['locked_by_me'] = False if f.lock_owner == username: f_['locked_by_me'] = True if f.lock_owner == ONLINE_OFFICE_LOCK_OWNER and \ user_perm == PERMISSION_READ_WRITE: f_['locked_by_me'] = True dirent_list.append(f_) result["dirent_list"] = dirent_list return HttpResponse(json.dumps(result), content_type=content_type)
def file_edit(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 if request.method == "POST": return file_edit_submit(request, repo_id) if check_repo_access_permission(repo_id, request.user) != "rw": return render_permission_error(request, _(u"Unable to edit file")) path = request.GET.get("p", "/") if path[-1] == "/": path = path[:-1] u_filename = os.path.basename(path) filename = urllib2.quote(u_filename.encode("utf-8")) head_id = repo.head_cmmt_id obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u"The file does not exist.")) token = web_get_access_token(repo_id, obj_id, "view", request.user.username) # generate path and link zipped = gen_path_link(path, repo.name) filetype, fileext = get_file_type_and_ext(filename) op = None err = "" file_content = None encoding = None file_encoding_list = FILE_ENCODING_LIST if filetype == TEXT or filetype == MARKDOWN or filetype == SF: if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, request.user.username) if not repo.password_set: op = "decrypt" if not op: inner_path = gen_inner_file_get_url(token, filename) file_enc = request.GET.get("file_enc", "auto") if not file_enc in FILE_ENCODING_LIST: file_enc = "auto" err, file_content, encoding = repo_file_get(inner_path, file_enc) if encoding and encoding not in FILE_ENCODING_LIST: file_encoding_list.append(encoding) else: err = _(u"Edit online is not offered for this type of file.") # Redirect to different place according to from page when user click # cancel button on file edit page. cancel_url = reverse("repo_view_file", args=[repo.id]) + "?p=" + urlquote(path) page_from = request.GET.get("from", "") gid = request.GET.get("gid", "") wiki_name = os.path.splitext(u_filename)[0] if page_from == "wiki_page_edit" or page_from == "wiki_page_new": cancel_url = reverse("group_wiki", args=[gid, wiki_name]) elif page_from == "personal_wiki_page_edit" or page_from == "personal_wiki_page_new": cancel_url = reverse("personal_wiki", args=[wiki_name]) return render_to_response( "file_edit.html", { "repo": repo, "u_filename": u_filename, "wiki_name": wiki_name, "path": path, "zipped": zipped, "filetype": filetype, "fileext": fileext, "op": op, "err": err, "file_content": file_content, "encoding": encoding, "file_encoding_list": file_encoding_list, "head_id": head_id, "from": page_from, "gid": gid, "cancel_url": cancel_url, }, context_instance=RequestContext(request), )
def list_dir_more(request, repo_id): """ List 'more' entries in a directory with AJAX. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, username) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) path = request.GET.get('p', '/') if path[-1] != '/': path = path + '/' offset = int(request.GET.get('start')) if not offset: err_msg = _(u'Argument missing') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) more_start = None file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset, limit=100) if dirent_more: more_start = offset + 100 ctx = { 'repo': repo, 'user_perm': user_perm, 'path': path, 'dir_list': dir_list, 'file_list': file_list, 'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY, } html = render_to_string('snippets/repo_dirents.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({ 'html': html, 'dirent_more': dirent_more, 'more_start': more_start }), content_type=content_type)
def list_dir(request, repo_id): """ List directory entries in AJAX. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, username) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) path = request.GET.get('p', '/') if path[-1] != '/': path = path + '/' more_start = None file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset=0, limit=100) if dirent_more: more_start = 100 zipped = get_nav_path(path, repo.name) 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) ctx = { 'repo': repo, 'zipped': zipped, 'user_perm': user_perm, 'path': path, 'server_crypto': server_crypto, 'fileshare': fileshare, 'dir_shared_link': dir_shared_link, 'uploadlink': uploadlink, 'dir_shared_upload_link': dir_shared_upload_link, 'dir_list': dir_list, 'file_list': file_list, 'dirent_more': dirent_more, 'more_start': more_start, 'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY, "sub_lib_enabled": sub_lib_enabled, } html = render_to_string('snippets/repo_dir_data.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({'html': html, 'path': path}), content_type=content_type)
def list_lib_dir(request, repo_id): ''' New ajax API for list library directory ''' content_type = 'application/json; charset=utf-8' result = {} repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username path = request.GET.get('p', '/') if path[-1] != '/': path = path + '/' # perm for current dir user_perm = check_folder_permission(request, repo.id, path) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) if repo.encrypted \ and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg, 'lib_need_decrypt': True}), status=403, content_type=content_type) head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) dir_list = [] file_list = [] try: dir_id = seafile_api.get_dir_id_by_path(repo.id, path) except SearpcError as e: logger.error(e) err_msg = 'Internal Server Error' return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) if not dir_id: err_msg = 'Folder not found.' return HttpResponse(json.dumps({'error': err_msg}), status=404, content_type=content_type) dirs = seafserv_threaded_rpc.list_dir_with_perm(repo_id, path, dir_id, username, -1, -1) starred_files = get_dir_starred_files(username, repo_id, path) for dirent in dirs: dirent.last_modified = dirent.mtime if stat.S_ISDIR(dirent.mode): dpath = posixpath.join(path, dirent.obj_name) if dpath[-1] != '/': dpath += '/' dir_list.append(dirent) else: if repo.version == 0: file_size = seafile_api.get_file_size(repo.store_id, repo.version, dirent.obj_id) else: file_size = dirent.size dirent.file_size = file_size if file_size else 0 dirent.starred = False fpath = posixpath.join(path, dirent.obj_name) if fpath in starred_files: dirent.starred = True file_list.append(dirent) 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) result["is_repo_owner"] = False result["has_been_shared_out"] = False if repo_owner == username: result["is_repo_owner"] = True try: if is_org_context(request): org_id = request.user.org.org_id is_inner_org_pub_repo = False # check if current repo is pub-repo org_pub_repos = seafile_api.list_org_inner_pub_repos_by_owner( org_id, username) for org_pub_repo in org_pub_repos: if repo_id == org_pub_repo.id: is_inner_org_pub_repo = True break if seafile_api.list_org_repo_shared_group(org_id, username, repo_id) or \ seafile_api.list_org_repo_shared_to(org_id, username, repo_id) or \ is_inner_org_pub_repo: result["has_been_shared_out"] = True else: if seafile_api.list_repo_shared_to(username, repo_id) or \ seafile_api.list_repo_shared_group_by_user(username, repo_id) or \ (not request.cloud_mode and seafile_api.is_inner_pub_repo(repo_id)): result["has_been_shared_out"] = True except Exception as e: logger.error(e) result["is_virtual"] = repo.is_virtual result["repo_name"] = repo.name result["user_perm"] = user_perm # check quota for fileupload result["no_quota"] = True if seaserv.check_quota(repo.id) < 0 else False result["encrypted"] = repo.encrypted dirent_list = [] for d in dir_list: d_ = {} d_['is_dir'] = True d_['obj_name'] = d.obj_name d_['last_modified'] = d.last_modified d_['last_update'] = translate_seahub_time(d.last_modified) d_['p_dpath'] = posixpath.join(path, d.obj_name) d_['perm'] = d.permission # perm for sub dir in current dir dirent_list.append(d_) size = int(request.GET.get('thumbnail_size', THUMBNAIL_DEFAULT_SIZE)) for f in file_list: f_ = {} f_['is_file'] = True f_['file_icon'] = file_icon_filter(f.obj_name) f_['obj_name'] = f.obj_name f_['last_modified'] = f.last_modified f_['last_update'] = translate_seahub_time(f.last_modified) f_['starred'] = f.starred f_['file_size'] = filesizeformat(f.file_size) f_['obj_id'] = f.obj_id f_['perm'] = f.permission # perm for file in current dir file_type, file_ext = get_file_type_and_ext(f.obj_name) if file_type == IMAGE: f_['is_img'] = True if not repo.encrypted and ENABLE_THUMBNAIL and \ os.path.exists(os.path.join(THUMBNAIL_ROOT, str(size), f.obj_id)): file_path = posixpath.join(path, f.obj_name) src = get_thumbnail_src(repo_id, size, file_path) f_['encoded_thumbnail_src'] = urlquote(src) if is_pro_version(): f_['is_locked'] = True if f.is_locked else False f_['lock_owner'] = f.lock_owner f_['lock_owner_name'] = email2nickname(f.lock_owner) if username == f.lock_owner: f_['locked_by_me'] = True else: f_['locked_by_me'] = False dirent_list.append(f_) result["dirent_list"] = dirent_list return HttpResponse(json.dumps(result), content_type=content_type)
def get(self, request, repo_id, format=None): """ Return history of library Permission checking: 1. all authenticated user can perform this action. """ # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, '/') is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) 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.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 Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not password_set: error_msg = 'Library is encrypted, but password is not set in server.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '100')) except ValueError: page = 1 per_page = 100 if page <= 0: error_msg = 'page invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if per_page <= 0: error_msg = 'per_page invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) start = (page - 1) * per_page limit = per_page + 1 try: all_commits = seafile_api.get_commit_list(repo_id, start, limit) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) items = [] commits = all_commits[:per_page] for commit in commits: if new_merge_with_no_conflict(commit): continue item_info = self.get_item_info(commit) items.append(item_info) commit_tag_dict = {} if ENABLE_REPO_SNAPSHOT_LABEL: try: revision_tags = RevisionTags.objects.filter(repo_id=repo_id) except Exception as e: logger.error(e) revision_tags = [] for tag in revision_tags: if commit_tag_dict.has_key(tag.revision_id): commit_tag_dict[tag.revision_id].append(tag.tag.name) else: commit_tag_dict[tag.revision_id] = [tag.tag.name] for item in items: item['tags'] = [] for commit_id, tags in commit_tag_dict.items(): if commit_id == item['commit_id']: item['tags'] = tags result = { 'data': items, 'more': True if len(all_commits) == per_page + 1 else False } return Response(result)
def is_password_set(repo_id, username): return seafile_api.is_password_set(repo_id, username)
def file_edit(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 if request.method == 'POST': return file_edit_submit(request, repo_id) if check_repo_access_permission(repo_id, request.user) != 'rw': return render_permission_error(request, _(u'Unable to edit file')) path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) filename = urllib2.quote(u_filename.encode('utf-8')) head_id = repo.head_cmmt_id obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'The file does not exist.')) token = web_get_access_token(repo_id, obj_id, 'view', request.user.username) # generate path and link zipped = gen_path_link(path, repo.name) filetype, fileext = get_file_type_and_ext(filename) op = None err = '' file_content = None encoding = None file_encoding_list = FILE_ENCODING_LIST if filetype == TEXT or filetype == MARKDOWN or filetype == SF: if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, request.user.username) if not repo.password_set: op = 'decrypt' if not op: inner_path = gen_inner_file_get_url(token, filename) file_enc = request.GET.get('file_enc', 'auto') if not file_enc in FILE_ENCODING_LIST: file_enc = 'auto' err, file_content, encoding = repo_file_get(inner_path, file_enc) if encoding and encoding not in FILE_ENCODING_LIST: file_encoding_list.append(encoding) else: err = _(u'Edit online is not offered for this type of file.') # Redirect to different place according to from page when user click # cancel button on file edit page. cancel_url = reverse('repo_view_file', args=[repo.id]) + '?p=' + urlquote(path) page_from = request.GET.get('from', '') gid = request.GET.get('gid', '') wiki_name = os.path.splitext(u_filename)[0] if page_from == 'wiki_page_edit' or page_from == 'wiki_page_new': cancel_url = reverse('group_wiki', args=[gid, wiki_name]) elif page_from == 'personal_wiki_page_edit' or page_from == 'personal_wiki_page_new': cancel_url = reverse('personal_wiki', args=[wiki_name]) return render_to_response('file_edit.html', { 'repo':repo, 'u_filename':u_filename, 'wiki_name': wiki_name, 'path':path, 'zipped':zipped, 'filetype':filetype, 'fileext':fileext, 'op':op, 'err':err, 'file_content':file_content, 'encoding': encoding, 'file_encoding_list':file_encoding_list, 'head_id': head_id, 'from': page_from, 'gid': gid, 'cancel_url': cancel_url, }, context_instance=RequestContext(request))
def file_edit_submit(request, repo_id): content_type = 'application/json; charset=utf-8' def error_json(error_msg=_(u'Internal Error'), op=None): return HttpResponse(json.dumps({'error': error_msg, 'op': op}), status=400, content_type=content_type) username = request.user.username if check_repo_access_permission(repo_id, request.user) != 'rw': return error_json(_(u'Permission denied')) repo = get_repo(repo_id) if not repo: return error_json(_(u'The library does not exist.')) if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, username) if not repo.password_set: return error_json(_(u'The library is encrypted.'), 'decrypt') content = request.POST.get('content') encoding = request.POST.get('encoding') path = request.GET.get('p') if content is None or not path or encoding not in ["gbk", "utf-8"]: return error_json(_(u'Invalid arguments')) head_id = request.GET.get('head', None) content = content.encode(encoding) # first dump the file content to a tmp file, then update the file fd, tmpfile = mkstemp() def remove_tmp_file(): try: os.remove(tmpfile) except: pass try: bytesWritten = os.write(fd, content) except: bytesWritten = -1 finally: os.close(fd) if bytesWritten != len(content): remove_tmp_file() return error_json() req_from = request.GET.get('from', '') if req_from == 'wiki_page_edit' or req_from == 'wiki_page_new': try: gid = int(request.GET.get('gid', 0)) except ValueError: gid = 0 wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse('group_wiki', args=[gid, wiki_name]) elif req_from == 'personal_wiki_page_edit' or req_from == 'personal_wiki_page_new': wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse('personal_wiki', args=[wiki_name]) else: next = reverse('repo_view_file', args=[repo_id]) + '?p=' + urlquote(path) parent_dir = os.path.dirname(path).encode('utf-8') filename = os.path.basename(path).encode('utf-8') try: seafserv_threaded_rpc.put_file(repo_id, tmpfile, parent_dir, filename, username, head_id) remove_tmp_file() return HttpResponse(json.dumps({'href': next}), content_type=content_type) except SearpcError, e: remove_tmp_file() return error_json(str(e))
def list_dir(request, repo_id): """ List directory entries in AJAX. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: err_msg = _(u'Library does not exist.') return HttpResponse(json.dumps({'error': err_msg}), status=400, content_type=content_type) username = request.user.username user_perm = check_repo_access_permission(repo.id, username) if user_perm is None: err_msg = _(u'Permission denied.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) if repo.encrypted and not seafile_api.is_password_set(repo.id, username): err_msg = _(u'Library is encrypted.') return HttpResponse(json.dumps({'error': err_msg}), status=403, content_type=content_type) head_commit = get_commit(repo.head_cmmt_id) if not head_commit: err_msg = _(u'Error: no head commit id') return HttpResponse(json.dumps({'error': err_msg}), status=500, content_type=content_type) path = request.GET.get('p', '/') if path[-1] != '/': path = path + '/' more_start = None file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset=0, limit=100) if dirent_more: more_start = 100 zipped = get_nav_path(path, repo.name) fileshare = get_fileshare(repo.id, username, path) dir_shared_link = get_dir_share_link(fileshare) ctx = { 'repo': repo, 'zipped': zipped, 'user_perm': user_perm, 'path': path, 'fileshare': fileshare, 'dir_shared_link': dir_shared_link, 'dir_list': dir_list, 'file_list': file_list, 'dirent_more': dirent_more, 'more_start': more_start, 'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY, } html = render_to_string('snippets/repo_dir_data.html', ctx, context_instance=RequestContext(request)) return HttpResponse(json.dumps({ 'html': html, 'path': path }), content_type=content_type)
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 file_edit_submit(request, repo_id): content_type = "application/json; charset=utf-8" def error_json(error_msg=_(u"Internal Error"), op=None): return HttpResponse(json.dumps({"error": error_msg, "op": op}), status=400, content_type=content_type) username = request.user.username if check_repo_access_permission(repo_id, request.user) != "rw": return error_json(_(u"Permission denied")) repo = get_repo(repo_id) if not repo: return error_json(_(u"The library does not exist.")) if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, username) if not repo.password_set: return error_json(_(u"The library is encrypted."), "decrypt") content = request.POST.get("content") encoding = request.POST.get("encoding") path = request.GET.get("p") if content is None or not path or encoding not in ["gbk", "utf-8"]: return error_json(_(u"Invalid arguments")) head_id = request.GET.get("head", None) content = content.encode(encoding) # first dump the file content to a tmp file, then update the file fd, tmpfile = mkstemp() def remove_tmp_file(): try: os.remove(tmpfile) except: pass try: bytesWritten = os.write(fd, content) except: bytesWritten = -1 finally: os.close(fd) if bytesWritten != len(content): remove_tmp_file() return error_json() req_from = request.GET.get("from", "") if req_from == "wiki_page_edit" or req_from == "wiki_page_new": try: gid = int(request.GET.get("gid", 0)) except ValueError: gid = 0 wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse("group_wiki", args=[gid, wiki_name]) elif req_from == "personal_wiki_page_edit" or req_from == "personal_wiki_page_new": wiki_name = os.path.splitext(os.path.basename(path))[0] next = reverse("personal_wiki", args=[wiki_name]) else: next = reverse("repo_view_file", args=[repo_id]) + "?p=" + urlquote(path) parent_dir = os.path.dirname(path).encode("utf-8") filename = os.path.basename(path).encode("utf-8") try: seafserv_threaded_rpc.put_file(repo_id, tmpfile, parent_dir, filename, username, head_id) remove_tmp_file() return HttpResponse(json.dumps({"href": next}), content_type=content_type) except SearpcError, e: remove_tmp_file() return error_json(str(e))
def get(self, request, repo_id, format=None): """ Return history of library Permission checking: 1. all authenticated user can perform this action. """ # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, '/') is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) 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.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 Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not password_set: error_msg = 'Library is encrypted, but password is not set in server.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '100')) except ValueError: page = 1 per_page = 100 if page <= 0: error_msg = 'page invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if per_page <= 0: error_msg = 'per_page invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) start = (page - 1) * per_page limit = per_page + 1 try: all_commits = seafile_api.get_commit_list(repo_id, start, limit) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) items = [] commits = all_commits[:per_page] for commit in commits: if new_merge_with_no_conflict(commit): continue item_info = self.get_item_info(commit) items.append(item_info) result = { 'data': items, 'more': True if len(all_commits) == per_page + 1 else False } return Response(result)