def put(self, request, repo_id, format=None): # generate file shared link path = unquote(request.DATA.get('p', '').encode('utf-8')) if not path: return api_error(status.HTTP_400_BAD_REQUEST, 'Path is missing.') if path[-1] == '/': path = path[:-1] l = FileShare.objects.filter(repo_id=repo_id).filter( username=request.user.username).filter(path=path) if len(l) > 0: fileshare = l[0] token = fileshare.token else: token = gen_token(max_length=10) fs = FileShare() fs.username = request.user.username fs.repo_id = repo_id fs.path = path fs.token = token try: fs.save() except IntegrityError, e: return api_err(status.HTTP_500_INTERNAL_SERVER_ERROR, e.msg)
def _add_file_share(self, username, repo_id, path, s_type): token = gen_token(max_length=10) fs = super(FileShareManager, self).create( username=username, repo_id=repo_id, path=path, token=token, s_type=s_type) fs.save() return fs
def get_or_create_invitation_link(org_id): """Invitation link for an org. Users will be redirected to WeChat QR page. Mainly used in docs.seafile.com. """ org_id = int(org_id) expires = 3 * 24 * 60 * 60 def get_token_by_org_id(org_id): return cache.get('org_associate_%d' % org_id, None) def set_token_by_org_id(org_id, token): cache.set('org_associate_%d' % org_id, token, expires) def get_org_id_by_token(token): return cache.get('org_associate_%s' % token, -1) def set_org_id_by_token(token, org_id): cache.set('org_associate_%s' % token, org_id, expires) token = get_token_by_org_id(org_id) cached_org_id = get_org_id_by_token(token) if token and org_id == cached_org_id: return '%s/weixin/oauth-login/?next=%s' % (get_service_url().rstrip( '/'), reverse('org_associate', args=[token])) token = gen_token(32) set_token_by_org_id(org_id, token) set_org_id_by_token(token, org_id) link = '%s/weixin/oauth-login/?next=%s' % ( get_service_url().rstrip('/'), reverse('org_associate', args=[token])) return link
def test_get_file_share_link_with_invalid_token(self): self.login_as(self.user) invalid_token = gen_token(max_length=20) url = reverse('api-v2.1-share-link', args=[invalid_token]) resp = self.client.get(url) self.assertEqual(404, resp.status_code)
def get_shared_link(request): """ Handle ajax request to generate file shared link. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo_id = request.GET.get('repo_id') obj_id = request.GET.get('obj_id') path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] l = FileShare.objects.filter(repo_id=repo_id).filter( username=request.user.username).filter(path=path) if len(l) > 0: fileshare = l[0] token = fileshare.token else: token = gen_token(max_length=10) fs = FileShare() fs.username = request.user.username fs.repo_id = repo_id fs.path = path fs.token = token try: fs.save() except IntegrityError, e: err = _('Failed to get shared link, please retry.') data = json.dumps([{'error': err}]) return HttpResponse(data, status=500, content_type=content_type)
def get_or_create_invitation_link(org_id): """Invitation link for an org. Users will be redirected to WeChat QR page. """ if not weixin_check(): return None org_id = int(org_id) expires = 3 * 24 * 60 * 60 def get_token_by_org_id(org_id): return cache.get('org_associate_%d' % org_id, None) def set_token_by_org_id(org_id, token): cache.set('org_associate_%d' % org_id, token, expires) def get_org_id_by_token(token): return cache.get('org_associate_%s' % token, -1) def set_org_id_by_token(token, org_id): cache.set('org_associate_%s' % token, org_id, expires) token = get_token_by_org_id(org_id) cached_org_id = get_org_id_by_token(token) if not token or org_id != cached_org_id: token = gen_token(32) set_token_by_org_id(org_id, token) set_org_id_by_token(token, org_id) link = get_site_scheme_and_netloc() + reverse('weixin_oauth_login') \ + '?org_token=' + token return link
def test_is_file_share_link(self): fs = FileShare.objects.create(username=self.user.username, repo_id=self.repo.id, path=self.file, token=gen_token(10)) assert fs.is_file_share_link() is True
def post(self, request, format=None): if has_two_factor_auth() and two_factor_auth_enabled(request.user): return {} randstr = gen_token(max_length=32) token = ClientLoginToken(randstr, request.user.username) token.save() return {'token': randstr}
def _add_file_share(self, username, repo_id, path, s_type, password=None, expire_date=None, permission='view_download', org_id=None): if password is not None: password_enc = make_password(password) else: password_enc = None token = gen_token(max_length=config.SHARE_LINK_TOKEN_LENGTH) fs = super(FileShareManager, self).create(username=username, repo_id=repo_id, path=path, token=token, s_type=s_type, password=password_enc, expire_date=expire_date, permission=permission) fs.save() if is_valid_org_id(org_id): OrgFileShare.objects.set_org_file_share(org_id, fs) return fs
def post(self, request, format=None): if has_two_factor_auth() and two_factor_auth_enabled(request.user.username): return {} randstr = gen_token(max_length=32) token = ClientLoginToken(randstr, request.user.username) token.save() return {"token": randstr}
def add(self, inviter, accepter, invite_type=GUEST): token = gen_token(max_length=32) expire_at = timezone.now() + timedelta(hours=int(INVITATIONS_TOKEN_AGE)) i = self.model(token=token, inviter=inviter, accepter=accepter, invite_type=invite_type, expire_time=expire_at) i.save(using=self._db) return i
def add(self, inviter, accepter, invite_type=GUEST): token = gen_token(max_length=32) expire_at = timezone.now() + timedelta(hours=INVITATIONS_TOKEN_AGE) i = self.model(token=token, inviter=inviter, accepter=accepter, invite_type=invite_type, expire_time=expire_at) i.save(using=self._db) return i
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', '') use_passwd = request.POST.get('use_passwd', '0') if int(use_passwd) == 1: passwd = request.POST.get('passwd') 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': if path[-1] == '/': # cut out last '/' at end of path path = path[:-1] else: if path == '/': # can not share root dir err = _('You cannot share the library in this way.') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) else: if path[-1] != '/': # append '/' at end of path path += '/' l = FileShare.objects.filter(repo_id=repo_id).filter( username=request.user.username).filter(path=path) if len(l) > 0: fs = l[0] token = fs.token else: token = gen_token(max_length=10) 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' fs.use_passwd = (int(use_passwd) == 1) if fs.use_passwd: fs.password = make_password(passwd) 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)
def ajax_get_link_audit_code(request): """ Generate a token, and record that token with email in cache, expires in one hour, send token to that email address. User provide token and email at share link page, if the token and email are valid, record that email in session. """ content_type = 'application/json; charset=utf-8' token = request.POST.get('token') email = request.POST.get('email') if not is_valid_email(email): return HttpResponse(json.dumps( {'error': _('Email address is not valid')}), status=400, content_type=content_type) dfs = FileShare.objects.get_valid_file_link_by_token(token) ufs = UploadLinkShare.objects.get_valid_upload_link_by_token(token) fs = dfs if dfs else ufs if fs is None: return HttpResponse(json.dumps({'error': _('Share link is not found')}), status=400, content_type=content_type) cache_key = normalize_cache_key(email, 'share_link_audit_') timeout = 60 * 60 # one hour code = gen_token(max_length=6) cache.set(cache_key, code, timeout) # send code to user via email subject = _("Verification code for visiting share links") c = { 'code': code, } try: send_html_email_with_dj_template( email, dj_template='share/audit_code_email.html', context=c, subject=subject, priority=MAIL_PRIORITY.now) return HttpResponse(json.dumps({'success': True}), status=200, content_type=content_type) except Exception as e: logger.error('Failed to send audit code via email to %s') logger.error(e) return HttpResponse(json.dumps({ "error": _("Failed to send a verification code, please try again later.") }), status=500, content_type=content_type)
def _add_file_share(self, username, repo_id, path, s_type): token = gen_token(max_length=10) fs = super(FileShareManager, self).create(username=username, repo_id=repo_id, path=path, token=token, s_type=s_type) fs.save() return fs
def add_private_dir_share(self, from_user, to_user, repo_id, path, perm): """ """ path = normalize_dir_path(path) token = gen_token(max_length=10) pfs = self.model(from_user=from_user, to_user=to_user, repo_id=repo_id, path=path, s_type='d', token=token, permission=perm) pfs.save(using=self._db) return pfs
def create_dtable_external_link(self, dtable, username, permission=PERMISSION_READ): token = gen_token(max_length=config.SHARE_LINK_TOKEN_LENGTH) return super(DTableExternalLinksManager, self).create(dtable=dtable, token=token, creator=username, create_at=datetime.datetime.utcnow(), permission=permission)
def create_upload_link_share(self, username, repo_id, path, password=None, expire_date=None): path = normalize_dir_path(path) token = gen_token(max_length=10) if password is not None: password_enc = make_password(password) else: password_enc = None uls = super(UploadLinkShareManager, self).create( username=username, repo_id=repo_id, path=path, token=token, password=password_enc, expire_date=expire_date) uls.save() return uls
def _add_file_share(self, username, repo_id, path, s_type, password=None, expire_date=None): if password is not None: password_enc = make_password(password) else: password_enc = None token = gen_token(max_length=10) fs = super(FileShareManager, self).create( username=username, repo_id=repo_id, path=path, token=token, s_type=s_type, password=password_enc, expire_date=expire_date) fs.save() return fs
def get_shared_upload_link(request): """ Handle ajax request to generate dir upload link. """ if not request.is_ajax(): raise Http404 content_type = 'application/json; charset=utf-8' repo_id = request.GET.get('repo_id', '') path = request.GET.get('p', '') use_passwd = request.POST.get('use_passwd', '0') if int(use_passwd) == 1: passwd = request.POST.get('passwd') if not (repo_id and path): err = _('Invalid arguments') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) if path == '/': # can not share root dir err = _('You cannot share the library in this way.') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) else: if path[-1] != '/': # append '/' at end of path path += '/' l = UploadLinkShare.objects.filter(repo_id=repo_id).filter( username=request.user.username).filter(path=path) if len(l) > 0: upload_link = l[0] token = upload_link.token else: token = gen_token(max_length=10) upload_link = UploadLinkShare() upload_link.username = request.user.username upload_link.repo_id = repo_id upload_link.path = path upload_link.token = token upload_link.use_passwd = (int(use_passwd) == 1) if upload_link.use_passwd: upload_link.password = make_password(passwd) try: upload_link.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)
def ajax_get_link_audit_code(request): """ Generate a token, and record that token with email in cache, expires in one hour, send token to that email address. User provide token and email at share link page, if the token and email are valid, record that email in session. """ content_type = 'application/json; charset=utf-8' token = request.POST.get('token') email = request.POST.get('email') if not is_valid_email(email): return HttpResponse(json.dumps({ 'error': _('Email address is not valid') }), status=400, content_type=content_type) dfs = FileShare.objects.get_valid_file_link_by_token(token) ufs = UploadLinkShare.objects.get_valid_upload_link_by_token(token) fs = dfs if dfs else ufs if fs is None: return HttpResponse(json.dumps({ 'error': _('Share link is not found') }), status=400, content_type=content_type) cache_key = normalize_cache_key(email, 'share_link_audit_') timeout = 60 * 60 # one hour code = gen_token(max_length=6) cache.set(cache_key, code, timeout) # send code to user via email subject = _("Verification code for visiting share links") c = { 'code': code, } try: send_html_email_with_dj_template( email, dj_template='share/audit_code_email.html', context=c, subject=subject, priority=MAIL_PRIORITY.now ) return HttpResponse(json.dumps({'success': True}), status=200, content_type=content_type) except Exception as e: logger.error('Failed to send audit code via email to %s') logger.error(e) return HttpResponse(json.dumps({ "error": _("Failed to send a verification code, please try again later.") }), status=500, content_type=content_type)
def create_link(self, dtable_id, username, password=None, expire_date=None, permission='r'): if password: password = make_password(password) token = gen_token(max_length=config.SHARE_LINK_TOKEN_LENGTH) sdl = super(DTableShareLinksManager, self).create(dtable_id=dtable_id, username=username, token=token, permission=permission, expire_date=expire_date, password=password) return sdl
def _add_file_share(self, username, repo_id, path, s_type, password=None, expire_date=None, permission='view_download', org_id=None): if password is not None: password_enc = make_password(password) else: password_enc = None token = gen_token(max_length=config.SHARE_LINK_TOKEN_LENGTH) fs = super(FileShareManager, self).create( username=username, repo_id=repo_id, path=path, token=token, s_type=s_type, password=password_enc, expire_date=expire_date, permission=permission) fs.save() if is_valid_org_id(org_id): OrgFileShare.objects.set_org_file_share(org_id, fs) return fs
def test_anonymous_user_post_correct_token(self, mock_is_pro_version): """ Check that anonnymous user input email and correct verification code. """ mock_is_pro_version.return_value = True code = gen_token(max_length=6) email = '*****@*****.**' cache_key = normalize_cache_key(email, 'share_link_audit_') cache.set(cache_key, code, timeout=60) assert cache.get(cache_key) == code anon_req = self._anon_post_request(data={'code': code, 'email': email}) self.assertEqual(anon_req.session.get('anonymous_email'), None) resp = self._fake_view_shared_file(anon_req, self.fs.token) self.assertEqual(resp.status_code, 200) self.assertEqual(anon_req.session.get('anonymous_email'), email) # email is set in session assert cache.get(cache_key) is None # token is delete after used
def send_share_link(request, repo_id, path, emails): l = FileShare.objects.filter(repo_id=repo_id).filter(\ username=request.user.username).filter(path=path) if len(l) > 0: fileshare = l[0] token = fileshare.token else: token = gen_token(max_length=10) fs = FileShare() fs.username = request.user.username fs.repo_id = repo_id fs.path = path fs.token = token try: fs.save() except IntegrityError, e: return api_err(request, '501')
def get_shared_link(request, repo_id, path): l = FileShare.objects.filter(repo_id=repo_id).filter(\ username=request.user.username).filter(path=path) token = None if len(l) > 0: fileshare = l[0] token = fileshare.token else: token = gen_token(max_length=10) fs = FileShare() fs.username = request.user.username fs.repo_id = repo_id fs.path = path fs.token = token try: fs.save() except IntegrityError, e: return api_err(status.HTTP_500_INTERNAL_SERVER_ERROR, e.msg)
def org_admin(request, url_prefix): """ List and add org users. """ if request.method == "POST": emails = request.POST.get("added-member-name") email_list = string2list(emails) for email in email_list: if not email or email.find("@") <= 0: continue org_id = request.user.org["org_id"] try: User.objects.get(email=email) email = email.strip(" ") org_id = request.user.org["org_id"] add_org_user(org_id, email, 0) # send signal org_user_added.send(sender=None, org_id=org_id, from_email=request.user.username, to_email=email) except User.DoesNotExist: # User is not registered, just create account and # add that account to org password = gen_token(max_length=6) if Site._meta.installed: site = Site.objects.get_current() else: site = RequestSite(request) RegistrationProfile.objects.create_active_user(email, email, password, site, send_email=False) add_org_user(org_id, email, 0) if hasattr(seahub_settings, "EMAIL_HOST"): org_name = request.user.org["org_name"] send_org_user_add_mail(request, email, password, org_name) # Make sure page request is an int. If not, deliver first page. try: current_page = int(request.GET.get("page", "1")) per_page = int(request.GET.get("per_page", "25")) except ValueError: current_page = 1 per_page = 25 users_plus_one = get_org_users_by_url_prefix(url_prefix, per_page * (current_page - 1), per_page + 1) if len(users_plus_one) == per_page + 1: page_next = True else: page_next = False org = get_user_current_org(request.user.username, url_prefix) if not org: return HttpResponseRedirect(reverse(myhome)) users = users_plus_one[:per_page] for user in users: if user.props.id == request.user.id: user.is_self = True try: user.quota_usage = seafserv_threaded_rpc.get_org_user_quota_usage(org.org_id, user.email) except: user.quota_usage = -1 # My contacts contacts = Contact.objects.filter(user_email=request.user.username) org_quota_usage = seafserv_threaded_rpc.get_org_quota_usage(org.org_id) org_quota = seafserv_threaded_rpc.get_org_quota(org.org_id) return render_to_response( "organizations/org_admin.html", { "users": users, "contacts": contacts, "current_page": current_page, "prev_page": current_page - 1, "next_page": current_page + 1, "per_page": per_page, "page_next": page_next, "org_quota_usage": org_quota_usage, "org_quota": org_quota, }, context_instance=RequestContext(request), )
def gen_user_virtual_id(): return gen_token(max_length=32) + '@auth.local'
def gen_user_virtual_id(): return gen_token(max_length=32) + VIRTUAL_ID_EMAIL_DOMAIN
def post(self, request, format=None): randstr = gen_token(max_length=32) token = ClientLoginToken(randstr, request.user.username) token.save() return {'token': randstr}