def get_user_share_link_info(fileshare): data = {} repo_id = fileshare.repo_id try: repo = seafile_api.get_repo(repo_id) except Exception as e: logger.error(e) repo = None path = fileshare.path if path: obj_name = '/' if path == '/' else os.path.basename(path.rstrip('/')) else: obj_name = '' data['repo_name'] = repo.repo_name if repo else '' data['token'] = fileshare.token data['link'] = gen_shared_link(fileshare.token, fileshare.s_type) data['path'] = path data['obj_name'] = obj_name data['is_dir'] = True if fileshare.s_type == 'd' else False data['view_cnt'] = fileshare.view_cnt if fileshare.s_type == 'f': obj_id = seafile_api.get_file_id_by_path(repo_id, path) data['size'] = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) else: data['size'] = '' return data
def get_shared_link(request, fileshare): # dir shared link if fileshare: dir_shared_link = gen_shared_link(request, fileshare.token, 'd') else: dir_shared_link = '' return dir_shared_link
def get_share_link_info(fileshare): data = {} token = fileshare.token repo_id = fileshare.repo_id try: repo = seafile_api.get_repo(repo_id) except Exception as e: logger.error(e) repo = None path = fileshare.path if path: obj_name = '/' if path == '/' else os.path.basename(path.rstrip('/')) else: obj_name = '' if fileshare.expire_date: expire_date = datetime_to_isoformat_timestr(fileshare.expire_date) else: expire_date = '' if fileshare.ctime: ctime = datetime_to_isoformat_timestr(fileshare.ctime) else: ctime = '' data['username'] = fileshare.username data['repo_id'] = repo_id data['repo_name'] = repo.repo_name if repo else '' data['path'] = path data['obj_name'] = obj_name data['is_dir'] = True if fileshare.s_type == 'd' else False data['token'] = token data['link'] = gen_shared_link(token, fileshare.s_type) data['view_cnt'] = fileshare.view_cnt data['ctime'] = ctime data['expire_date'] = expire_date data['is_expired'] = fileshare.is_expired() data['permissions'] = fileshare.get_permissions() data['can_edit'] = False if repo and path != '/' and not data['is_dir']: dirent = seafile_api.get_dirent_by_path(repo_id, path) if dirent: try: can_edit, error_msg = can_edit_file(obj_name, dirent.size, repo) data['can_edit'] = can_edit except Exception as e: logger.error(e) else: data['can_edit'] = False return data
def get_shared_link(request): """ Handle ajax request to generate file or dir shared link. """ content_type = 'application/json; charset=utf-8' repo_id = request.GET.get('repo_id', '') share_type = request.GET.get('type', 'f') # `f` or `d` path = request.GET.get('p', '') use_passwd = True if int(request.POST.get('use_passwd', '0')) == 1 else False passwd = request.POST.get('passwd') if use_passwd else None try: expire_days = int(request.POST.get('expire_days', 0)) except ValueError: expire_days = 0 if expire_days <= 0: expire_date = None else: expire_date = timezone.now() + relativedelta(days=expire_days) if not (repo_id and path): err = _('Invalid arguments') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) if share_type != 'f' and path == '/': err = _('You cannot share the library in this way.') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) username = request.user.username if share_type == 'f': fs = FileShare.objects.get_file_link_by_path(username, repo_id, path) if fs is None: fs = FileShare.objects.create_file_link(username, repo_id, path, passwd, expire_date) if is_org_context(request): org_id = request.user.org.org_id OrgFileShare.objects.set_org_file_share(org_id, fs) else: fs = FileShare.objects.get_dir_link_by_path(username, repo_id, path) if fs is None: fs = FileShare.objects.create_dir_link(username, repo_id, path, passwd, expire_date) if is_org_context(request): org_id = request.user.org.org_id OrgFileShare.objects.set_org_file_share(org_id, fs) token = fs.token shared_link = gen_shared_link(token, fs.s_type) data = json.dumps({'token': token, 'shared_link': shared_link}) return HttpResponse(data, status=200, content_type=content_type)
def get_share_link_info(fileshare): data = {} token = fileshare.token repo_id = fileshare.repo_id try: repo = seafile_api.get_repo(repo_id) except Exception as e: logger.error(e) repo = None path = fileshare.path if path: obj_name = '/' if path == '/' else os.path.basename(path.rstrip('/')) else: obj_name = '' if fileshare.expire_date: expire_date = datetime_to_isoformat_timestr(fileshare.expire_date) else: expire_date = '' if fileshare.ctime: ctime = datetime_to_isoformat_timestr(fileshare.ctime) else: ctime = '' ccnet_email = fileshare.username data['creator_email'] = ccnet_email data['creator_name'] = email2nickname(ccnet_email) data['creator_contact_email'] = email2contact_email(ccnet_email) data['repo_id'] = repo_id data['repo_name'] = repo.repo_name if repo else '' data['path'] = path data['obj_name'] = obj_name data['is_dir'] = True if fileshare.s_type == 'd' else False data['token'] = token data['link'] = gen_shared_link(token, fileshare.s_type) data['view_cnt'] = fileshare.view_cnt data['ctime'] = ctime data['expire_date'] = expire_date data['is_expired'] = fileshare.is_expired() data['permissions'] = fileshare.get_permissions() if fileshare.s_type == 'f': obj_id = seafile_api.get_file_id_by_path(repo_id, path) data['size'] = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) return data
def get_share_link_info(fileshare): data = {} token = fileshare.token data['repo_id'] = fileshare.repo_id data['path'] = fileshare.path data['ctime'] = fileshare.ctime data['view_cnt'] = fileshare.view_cnt data['link'] = gen_shared_link(token, fileshare.s_type) data['token'] = token data['expire_date'] = fileshare.expire_date data['is_expired'] = fileshare.is_expired() data['username'] = fileshare.username return data
def get_share_link_info(fileshare): data = {} token = fileshare.token repo_id = fileshare.repo_id try: repo = seafile_api.get_repo(repo_id) except Exception as e: logger.error(e) repo = None path = fileshare.path if path: obj_name = '/' if path == '/' else os.path.basename(path.rstrip('/')) else: obj_name = '' if fileshare.expire_date: expire_date = datetime_to_isoformat_timestr(fileshare.expire_date) else: expire_date = '' if fileshare.ctime: ctime = datetime_to_isoformat_timestr(fileshare.ctime) else: ctime = '' data['username'] = fileshare.username data['repo_id'] = repo_id data['repo_name'] = repo.repo_name if repo else '' data['path'] = path data['obj_name'] = obj_name data['is_dir'] = True if fileshare.s_type == 'd' else False data['token'] = token data['link'] = gen_shared_link(token, fileshare.s_type) data['view_cnt'] = fileshare.view_cnt data['ctime'] = ctime data['expire_date'] = expire_date data['is_expired'] = fileshare.is_expired() return data
def get_shared_link(request): """ Handle ajax request to generate file or dir shared link. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo_id = request.GET.get('repo_id', '') share_type = request.GET.get('type', 'f') # `f` or `d` path = request.GET.get('p', '') if not (repo_id and path): err = _('Invalid arguments') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) if share_type != 'f' and path == '/': err = _('You cannot share the library in this way.') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) username = request.user.username if share_type == 'f': fs = FileShare.objects.get_file_link_by_path(username, repo_id, path) if fs is None: fs = FileShare.objects.create_file_link(username, repo_id, path) if is_org_context(request): org_id = request.user.org.org_id OrgFileShare.objects.set_org_file_share(org_id, fs) else: fs = FileShare.objects.get_dir_link_by_path(username, repo_id, path) if fs is None: fs = FileShare.objects.create_dir_link(username, repo_id, path) if is_org_context(request): org_id = request.user.org.org_id OrgFileShare.objects.set_org_file_share(org_id, fs) token = fs.token shared_link = gen_shared_link(token, fs.s_type) data = json.dumps({'token': token, 'shared_link': shared_link}) return HttpResponse(data, status=200, content_type=content_type)
def get_shared_link(request): """ Handle ajax request to generate file or dir shared link. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo_id = request.GET.get('repo_id', '') share_type = request.GET.get('type', 'f') # `f` or `d` path = request.GET.get('p', '') if not (repo_id and path): err = _('Invalid arguments') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) if share_type != 'f' and path == '/': err = _('You cannot share the library in this way.') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) username = request.user.username if share_type == 'f': fs = FileShare.objects.get_file_link_by_path(username, repo_id, path) if fs is None: fs = FileShare.objects.create_file_link(username, repo_id, path) else: fs = FileShare.objects.get_dir_link_by_path(username, repo_id, path) if fs is None: fs = FileShare.objects.create_dir_link(username, repo_id, path) if is_org_context(request): org_id = request.user.org.org_id OrgFileShare.objects.set_org_file_share(org_id, fs) token = fs.token shared_link = gen_shared_link(token, fs.s_type) data = json.dumps({'token': token, 'shared_link': shared_link}) return HttpResponse(data, status=200, content_type=content_type)
def get_share_link_info(fileshare): data = {} token = fileshare.token path = fileshare.path if path: obj_name = '/' if path == '/' else os.path.basename(path.rstrip('/')) else: obj_name = '' if fileshare.expire_date: expire_date = datetime_to_isoformat_timestr(fileshare.expire_date) else: expire_date = '' if fileshare.ctime: ctime = datetime_to_isoformat_timestr(fileshare.ctime) else: ctime = '' creator_email = fileshare.username data['creator_email'] = creator_email data['creator_name'] = email2nickname(creator_email) data['creator_contact_email'] = email2contact_email(creator_email) data['path'] = path data['obj_name'] = obj_name data['is_dir'] = True if fileshare.s_type == 'd' else False data['token'] = token data['link'] = gen_shared_link(token, fileshare.s_type) data['ctime'] = ctime data['expire_date'] = expire_date return data
fs = FileShare() fs.username = request.user.username fs.repo_id = repo_id fs.path = path fs.token = token fs.s_type = 'f' if share_type == 'f' else 'd' try: fs.save() except IntegrityError, e: err = _('Failed to get the link, please retry later.') data = json.dumps({'error': err}) return HttpResponse(data, status=500, content_type=content_type) shared_link = gen_shared_link(request, token, fs.s_type) data = json.dumps({'token': token, 'shared_link': shared_link}) return HttpResponse(data, status=200, content_type=content_type) @login_required def remove_shared_link(request): """ Handle request to remove file shared link. """ token = request.GET.get('t', '') if not request.is_ajax(): FileShare.objects.filter(token=token).delete() next = request.META.get('HTTP_REFERER', None)
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": [], "swf_exists": False, "filetype": filetype, } # Check file size fsize = get_file_size(obj_id) if fsize > FILE_PREVIEW_MAX_SIZE: from django.template.defaultfilters import filesizeformat err = _(u"File size surpasses %s, can not be opened online.") % filesizeformat(FILE_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() 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"], "swf_exists": ret_dict["swf_exists"], "filetype": ret_dict["filetype"], "applet_root": get_ccnetapplet_root(), "groups": groups, "DOCUMENT_CONVERTOR_ROOT": DOCUMENT_CONVERTOR_ROOT, "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, }, context_instance=RequestContext(request), )
def post(self, request): if not IS_EMAIL_CONFIGURED: error_msg = _('Sending shared link failed. Email service is not properly configured, please contact administrator.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check args email = request.POST.get('email', None) if not email: error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) token = request.POST.get('token', None) if not token: error_msg = 'token invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) extra_msg = request.POST.get('extra_msg', '') # check if token exists try: link = FileShare.objects.get(token=token) except FileShare.DoesNotExist: error_msg = 'token %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check if is share link owner username = request.user.username if not link.is_owner(username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) result = {} result['failed'] = [] result['success'] = [] to_email_list = string2list(email) # use contact_email, if present useremail = Profile.objects.get_contact_email_by_user(request.user.username) for to_email in to_email_list: failed_info = {} if not is_valid_email(to_email): failed_info['email'] = to_email failed_info['error_msg'] = 'email invalid.' result['failed'].append(failed_info) continue # prepare basic info c = { 'email': username, 'to_email': to_email, 'extra_msg': extra_msg, } if REPLACE_FROM_EMAIL: from_email = useremail else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = useremail else: reply_to = None c['file_shared_link'] = gen_shared_link(token, link.s_type) c['file_shared_name'] = os.path.basename(link.path.rstrip('/')) template = 'shared_link_email.html' if link.s_type == 'f': c['file_shared_type'] = _("file") title = _('A file is shared to you on %s') % get_site_name() else: c['file_shared_type'] = _("directory") title = _('A directory is shared to you on %s') % get_site_name() # send email try: send_html_email(title, template, c, from_email, [to_email], reply_to=reply_to) result['success'].append(to_email) except Exception as e: logger.error(e) failed_info['email'] = to_email failed_info['error_msg'] = 'Internal Server Error' result['failed'].append(failed_info) return Response(result)
def ajax_get_download_link(request): """ Handle ajax request to generate file or dir shared link. """ content_type = 'application/json; charset=utf-8' if request.method == 'GET': repo_id = request.GET.get('repo_id', '') share_type = request.GET.get('type', 'f') # `f` or `d` path = request.GET.get('p', '') username = request.user.username if share_type == 'd' and not path.endswith('/'): path = path + '/' l = FileShare.objects.filter(repo_id=repo_id).filter( username=username).filter(path=path) if len(l) > 0: token = l[0].token data = { 'download_link': gen_shared_link(token, l[0].s_type), 'token': token, 'is_expired': l[0].is_expired(), } else: data = {} return HttpResponse(json.dumps(data), content_type=content_type) elif request.method == 'POST': if not request.user.permissions.can_generate_shared_link(): err = _('You do not have permission to generate shared link') data = json.dumps({'error': err}) return HttpResponse(data, status=403, content_type=content_type) repo_id = request.POST.get('repo_id', '') share_type = request.POST.get('type', 'f') # `f` or `d` path = request.POST.get('p', '') use_passwd = True if int(request.POST.get('use_passwd', '0')) == 1 else False passwd = request.POST.get('passwd') if use_passwd else None if not (repo_id and path): err = _('Invalid arguments') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) if passwd and len(passwd) < config.SHARE_LINK_PASSWORD_MIN_LENGTH: err = _('Password is too short') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) try: expire_days = int(request.POST.get('expire_days', 0)) except ValueError: expire_days = 0 if expire_days <= 0: expire_date = None else: expire_date = timezone.now() + relativedelta(days=expire_days) username = request.user.username if share_type == 'f': fs = FileShare.objects.get_file_link_by_path( username, repo_id, path) if fs is None: fs = FileShare.objects.create_file_link( username, repo_id, path, passwd, expire_date) if is_org_context(request): org_id = request.user.org.org_id OrgFileShare.objects.set_org_file_share(org_id, fs) else: fs = FileShare.objects.get_dir_link_by_path( username, repo_id, path) if fs is None: fs = FileShare.objects.create_dir_link(username, repo_id, path, passwd, expire_date) if is_org_context(request): org_id = request.user.org.org_id OrgFileShare.objects.set_org_file_share(org_id, fs) token = fs.token shared_link = gen_shared_link(token, fs.s_type) data = json.dumps({'token': token, 'download_link': shared_link}) return HttpResponse(data, content_type=content_type)
def share_admin(request): """ List personal shared repos and shared links. """ username = request.user.username shared_repos = [] # personal repos shared by this user shared_repos += list_share_repos(username, 'from_email', -1, -1) # repos shared to groups group_repos = get_group_repos_by_owner(username) for repo in group_repos: group = ccnet_threaded_rpc.get_group(int(repo.group_id)) if not group: repo.props.user = '' continue repo.props.user = group.props.group_name repo.props.user_info = repo.group_id shared_repos += group_repos if not CLOUD_MODE: # public repos shared by this user pub_repos = list_inner_pub_repos_by_owner(username) for repo in pub_repos: repo.props.user = _(u'all members') repo.props.user_info = 'all' shared_repos += pub_repos for repo in shared_repos: if repo.props.permission == 'rw': repo.share_permission = _(u'Read-Write') elif repo.props.permission == 'r': repo.share_permission = _(u'Read-Only') else: repo.share_permission = '' if repo.props.share_type == 'personal': repo.props.user_info = repo.props.user shared_repos.sort(lambda x, y: cmp(x.repo_id, y.repo_id)) # Repo anonymous share links # out_links = AnonymousShare.objects.filter(repo_owner=request.user.username) # for link in out_links: # repo = get_repo(link.repo_id) # link.repo_name = repo.name # link.remain_time = anon_share_token_generator.get_remain_time(link.token) # Shared links fileshares = FileShare.objects.filter(username=username) p_fileshares = [] # personal file share for fs in fileshares: if is_personal_repo(fs.repo_id): # only list files in personal repos if fs.s_type == 'f': fs.filename = os.path.basename(fs.path) fs.shared_link = gen_shared_link(request, fs.token, 'f') else: fs.filename = os.path.basename(fs.path[:-1]) fs.shared_link = gen_shared_link(request, fs.token, 'd') r = get_repo(fs.repo_id) if not r: # get_repo may returns None continue fs.repo = r p_fileshares.append(fs) return render_to_response( 'repo/share_admin.html', { "org": None, "shared_repos": shared_repos, # "out_links": out_links, "fileshares": p_fileshares, }, context_instance=RequestContext(request))
fs = FileShare() fs.username = request.user.username fs.repo_id = repo_id fs.path = path fs.token = token fs.s_type = 'f' if share_type == 'f' else 'd' try: fs.save() except IntegrityError, e: err = _('Failed to get the link, please retry later.') data = json.dumps({'error': err}) return HttpResponse(data, status=500, content_type=content_type) shared_link = gen_shared_link(token, fs.s_type) data = json.dumps({'token': token, 'shared_link': shared_link}) return HttpResponse(data, status=200, content_type=content_type) @login_required def remove_shared_link(request): """ Handle request to remove file shared link. """ token = request.GET.get('t') if not request.is_ajax(): FileShare.objects.filter(token=token).delete() next = request.META.get('HTTP_REFERER', None)
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) 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} fsize = get_file_size(obj_id) exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype) if exceeds_limit: ret_dict['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, 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))
fs = FileShare() fs.username = request.user.username fs.repo_id = repo_id fs.path = path fs.token = token fs.s_type = 'f' if share_type == 'f' else 'd' try: fs.save() except IntegrityError, e: err = _('Failed to get the link, please retry later.') data = json.dumps({'error': err}) return HttpResponse(data, status=500, content_type=content_type) shared_link = gen_shared_link(token, fs.s_type) data = json.dumps({'token': token, 'shared_link': shared_link}) return HttpResponse(data, status=200, content_type=content_type) @login_required def remove_shared_link(request): """ Handle request to remove file shared link. """ token = request.GET.get('t') if not request.is_ajax(): FileShare.objects.filter(token=token).delete() next = request.META.get('HTTP_REFERER', None) if not next:
def post(self, request): if not IS_EMAIL_CONFIGURED: error_msg = _(u'Sending shared link failed. Email service is not properly configured, please contact administrator.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check args email = request.POST.get('email', None) if not email: error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) token = request.POST.get('token', None) if not token: error_msg = 'token invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) extra_msg = request.POST.get('extra_msg', '') # check if token exists try: link = FileShare.objects.get(token=token) except FileShare.DoesNotExist: error_msg = 'token %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check if is share link owner username = request.user.username if not link.is_owner(username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) result = {} result['failed'] = [] result['success'] = [] to_email_list = string2list(email) # use contact_email, if present useremail = Profile.objects.get_contact_email_by_user(request.user.username) for to_email in to_email_list: failed_info = {} if not is_valid_email(to_email): failed_info['email'] = to_email failed_info['error_msg'] = 'email invalid.' result['failed'].append(failed_info) continue # prepare basic info c = { 'email': username, 'to_email': to_email, 'extra_msg': extra_msg, } if REPLACE_FROM_EMAIL: from_email = useremail else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = useremail else: reply_to = None c['file_shared_link'] = gen_shared_link(token, link.s_type) c['file_shared_name'] = os.path.basename(link.path.rstrip('/')) template = 'shared_link_email.html' if link.s_type == 'f': c['file_shared_type'] = _(u"file") title = _(u'A file is shared to you on %s') % SITE_NAME else: c['file_shared_type'] = _(u"directory") title = _(u'A directory is shared to you on %s') % SITE_NAME # send email try: send_html_email(title, template, c, from_email, [to_email], reply_to=reply_to) result['success'].append(to_email) except Exception as e: logger.error(e) failed_info['email'] = to_email failed_info['error_msg'] = 'Internal Server Error' result['failed'].append(failed_info) return Response(result)
def ajax_get_download_link(request): """ Handle ajax request to generate file or dir shared link. """ content_type = 'application/json; charset=utf-8' if request.method == 'GET': repo_id = request.GET.get('repo_id', '') share_type = request.GET.get('type', 'f') # `f` or `d` path = request.GET.get('p', '') username = request.user.username if share_type == 'd' and not path.endswith('/'): path = path + '/' l = FileShare.objects.filter(repo_id=repo_id).filter( username=username).filter(path=path) if len(l) > 0: token = l[0].token data = { 'download_link': gen_shared_link(token, l[0].s_type), 'token': token, 'is_expired': l[0].is_expired(), } else: data = {} return HttpResponse(json.dumps(data), content_type=content_type) elif request.method == 'POST': if not request.user.permissions.can_generate_shared_link(): err = _('You do not have permission to generate shared link') data = json.dumps({'error': err}) return HttpResponse(data, status=403, content_type=content_type) repo_id = request.POST.get('repo_id', '') share_type = request.POST.get('type', 'f') # `f` or `d` path = request.POST.get('p', '') use_passwd = True if int(request.POST.get('use_passwd', '0')) == 1 else False passwd = request.POST.get('passwd') if use_passwd else None if not (repo_id and path): err = _('Invalid arguments') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) if passwd and len(passwd) < config.SHARE_LINK_PASSWORD_MIN_LENGTH: err = _('Password is too short') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) try: expire_days = int(request.POST.get('expire_days', 0)) except ValueError: expire_days = 0 if expire_days <= 0: expire_date = None else: expire_date = timezone.now() + relativedelta(days=expire_days) username = request.user.username if share_type == 'f': fs = FileShare.objects.get_file_link_by_path(username, repo_id, path) if fs is None: fs = FileShare.objects.create_file_link(username, repo_id, path, passwd, expire_date) if is_org_context(request): org_id = request.user.org.org_id OrgFileShare.objects.set_org_file_share(org_id, fs) else: fs = FileShare.objects.get_dir_link_by_path(username, repo_id, path) if fs is None: fs = FileShare.objects.create_dir_link(username, repo_id, path, passwd, expire_date) if is_org_context(request): org_id = request.user.org.org_id OrgFileShare.objects.set_org_file_share(org_id, fs) token = fs.token shared_link = gen_shared_link(token, fs.s_type) data = json.dumps({'token': token, 'download_link': shared_link}) return HttpResponse(data, content_type=content_type)
def org_shareadmin(request, url_prefix): """ List org shared repos and org shared links. """ username = request.user.username org = get_user_current_org(request.user.username, url_prefix) if not org: return HttpResponseRedirect(reverse(myhome)) shared_repos = [] # org repos shared by this user shared_repos += seafserv_threaded_rpc.list_org_share_repos(org.org_id, username, "from_email", -1, -1) # repos shared to groups group_repos = seafserv_threaded_rpc.get_org_group_repos_by_owner(org.org_id, username) for repo in group_repos: group = ccnet_threaded_rpc.get_group(int(repo.group_id)) if not group: repo.props.user = "" continue repo.props.user = group.props.group_name repo.props.user_info = repo.group_id shared_repos += group_repos # public repos shared by this user pub_repos = seafserv_threaded_rpc.list_org_inner_pub_repos_by_owner(org.org_id, username) for repo in pub_repos: repo.props.user = _(u"all members") repo.props.user_info = "all" shared_repos += pub_repos for repo in shared_repos: if repo.props.permission == "rw": repo.share_permission = _(u"Read-Write") elif repo.props.permission == "r": repo.share_permission = _(u"Read-Only") else: repo.share_permission = "" if repo.props.share_type == "personal": repo.props.user_info = repo.props.user shared_repos.sort(lambda x, y: cmp(x.repo_id, y.repo_id)) # shared links fileshares = FileShare.objects.filter(username=request.user.username) o_fileshares = [] # shared links in org repos for fs in fileshares: if not is_personal_repo(fs.repo_id): # only list links in org repos if fs.s_type == "f": fs.filename = os.path.basename(fs.path) fs.shared_link = gen_shared_link(request, fs.token, "f") else: fs.filename = os.path.basename(fs.path[:-1]) fs.shared_link = gen_shared_link(request, fs.token, "d") r = get_repo(fs.repo_id) # get_repo may returns None if not r: continue fs.repo = r o_fileshares.append(fs) # use org base template request.base_template = "org_base.html" return render_to_response( "repo/share_admin.html", { "org": org, "shared_repos": shared_repos, "fileshares": o_fileshares, "protocol": request.is_secure() and "https" or "http", "domain": RequestSite(request).domain, }, context_instance=RequestContext(request), )
def share_admin(request): """ List personal shared repos and shared links. """ username = request.user.username shared_repos = [] # personal repos shared by this user shared_repos += seafserv_threaded_rpc.list_share_repos(username, 'from_email', -1, -1) # repos shared to groups group_repos = seafserv_threaded_rpc.get_group_repos_by_owner(username) for repo in group_repos: group = ccnet_threaded_rpc.get_group(int(repo.group_id)) if not group: repo.props.user = '' continue repo.props.user = group.props.group_name repo.props.user_info = repo.group_id shared_repos += group_repos if not CLOUD_MODE: # public repos shared by this user pub_repos = seafserv_threaded_rpc.list_inner_pub_repos_by_owner(username) for repo in pub_repos: repo.props.user = _(u'all members') repo.props.user_info = 'all' shared_repos += pub_repos for repo in shared_repos: if repo.props.permission == 'rw': repo.share_permission = _(u'Read-Write') elif repo.props.permission == 'r': repo.share_permission = _(u'Read-Only') else: repo.share_permission = '' if repo.props.share_type == 'personal': repo.props.user_info = repo.props.user shared_repos.sort(lambda x, y: cmp(x.repo_id, y.repo_id)) # Repo anonymous share links # out_links = AnonymousShare.objects.filter(repo_owner=request.user.username) # for link in out_links: # repo = get_repo(link.repo_id) # link.repo_name = repo.name # link.remain_time = anon_share_token_generator.get_remain_time(link.token) # Shared links fileshares = FileShare.objects.filter(username=username) p_fileshares = [] # personal file share for fs in fileshares: if is_personal_repo(fs.repo_id): # only list files in personal repos if fs.s_type == 'f': fs.filename = os.path.basename(fs.path) fs.shared_link = gen_shared_link(request, fs.token, 'f') else: fs.filename = os.path.basename(fs.path[:-1]) fs.shared_link = gen_shared_link(request, fs.token, 'd') r = get_repo(fs.repo_id) if not r: # get_repo may returns None continue fs.repo = r p_fileshares.append(fs) return render_to_response('repo/share_admin.html', { "org": None, "shared_repos": shared_repos, # "out_links": out_links, "fileshares": p_fileshares, }, context_instance=RequestContext(request))
fs = FileShare() fs.username = request.user.username fs.repo_id = repo_id fs.path = path fs.token = token fs.s_type = 'f' if share_type == 'f' else 'd' try: fs.save() except IntegrityError, e: err = _('Failed to get the link, please retry later.') data = json.dumps({'error': err}) return HttpResponse(data, status=500, content_type=content_type) shared_link = gen_shared_link(request, token, fs.s_type) data = json.dumps({'token': token, 'shared_link': shared_link}) return HttpResponse(data, status=200, content_type=content_type) @login_required def remove_shared_link(request): """ Handle request to remove file shared link. """ token = request.GET.get('t', '') if not request.is_ajax(): FileShare.objects.filter(token=token).delete() next = request.META.get('HTTP_REFERER', None) if not next: