mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-25 06:33:48 +00:00
Merge pull request #1047 from haiwen/email
[api2] add send share/upload link api
This commit is contained in:
113
seahub/api2/endpoints/send_share_link_email.py
Normal file
113
seahub/api2/endpoints/send_share_link_email.py
Normal file
@@ -0,0 +1,113 @@
|
||||
import os
|
||||
import logging
|
||||
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.throttling import UserRateThrottle
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.utils import api_error
|
||||
|
||||
from seahub.utils import IS_EMAIL_CONFIGURED, is_valid_username, \
|
||||
string2list, gen_shared_link, send_html_email
|
||||
from seahub.share.models import FileShare
|
||||
|
||||
from seahub.settings import REPLACE_FROM_EMAIL, ADD_REPLY_TO_HEADER, SITE_NAME
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class SendShareLinkView(APIView):
|
||||
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication )
|
||||
permission_classes = (IsAuthenticated,)
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
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)
|
||||
for to_email in to_email_list:
|
||||
|
||||
failed_info = {}
|
||||
|
||||
if not is_valid_username(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 = username
|
||||
else:
|
||||
from_email = None # use default from email
|
||||
|
||||
if ADD_REPLY_TO_HEADER:
|
||||
reply_to = username
|
||||
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)
|
105
seahub/api2/endpoints/send_upload_link_email.py
Normal file
105
seahub/api2/endpoints/send_upload_link_email.py
Normal file
@@ -0,0 +1,105 @@
|
||||
import logging
|
||||
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.throttling import UserRateThrottle
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.utils import api_error
|
||||
|
||||
from seahub.utils import IS_EMAIL_CONFIGURED, is_valid_username, \
|
||||
string2list, gen_shared_upload_link, send_html_email
|
||||
from seahub.share.models import UploadLinkShare
|
||||
|
||||
from seahub.settings import REPLACE_FROM_EMAIL, ADD_REPLY_TO_HEADER, SITE_NAME
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class SendUploadLinkView(APIView):
|
||||
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication )
|
||||
permission_classes = (IsAuthenticated,)
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
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 = UploadLinkShare.objects.get(token=token)
|
||||
except UploadLinkShare.DoesNotExist:
|
||||
error_msg = 'token %s not found.' % token
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# check if is upload 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)
|
||||
for to_email in to_email_list:
|
||||
|
||||
failed_info = {}
|
||||
if not is_valid_username(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 = username
|
||||
else:
|
||||
from_email = None # use default from email
|
||||
|
||||
if ADD_REPLY_TO_HEADER:
|
||||
reply_to = username
|
||||
else:
|
||||
reply_to = None
|
||||
|
||||
c['shared_upload_link'] = gen_shared_upload_link(token)
|
||||
title = _(u'An upload link is shared to you on %s') % SITE_NAME
|
||||
template = 'shared_upload_link_email.html'
|
||||
|
||||
# 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)
|
||||
|
@@ -7,6 +7,8 @@ from .endpoints.dir_shared_items import DirSharedItemsEndpoint
|
||||
from .endpoints.account import Account
|
||||
from .endpoints.shared_upload_links import SharedUploadLinksView
|
||||
from .endpoints.be_shared_repo import BeSharedReposView
|
||||
from .endpoints.send_share_link_email import SendShareLinkView
|
||||
from .endpoints.send_upload_link_email import SendUploadLinkView
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^ping/$', Ping.as_view()),
|
||||
@@ -53,6 +55,8 @@ urlpatterns = patterns('',
|
||||
url(r'^beshared-repos/$', BeShared.as_view(), name='beshared'),
|
||||
url(r'^beshared-repos/(?P<repo_id>[-0-9-a-f]{36})/$', BeSharedReposView.as_view(), name='beshared-repos'),
|
||||
url(r'^default-repo/$', DefaultRepoView.as_view(), name='api2-defaultrepo'),
|
||||
url(r'^send-share-link/$', SendShareLinkView.as_view(), name='api2-send-share-link'),
|
||||
url(r'^send-upload-link/$', SendUploadLinkView.as_view(), name='api2-send-upload-link'),
|
||||
url(r'^shared-links/$', SharedLinksView.as_view()),
|
||||
url(r'^shared-upload-links/$', SharedUploadLinksView.as_view()),
|
||||
url(r'^shared-files/$', SharedFilesView.as_view()),
|
||||
|
47
tests/api/endpoints/test_send_share_link.py
Normal file
47
tests/api/endpoints/test_send_share_link.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#coding: UTF-8
|
||||
import json
|
||||
from django.core.urlresolvers import reverse
|
||||
from seahub.utils import IS_EMAIL_CONFIGURED
|
||||
from seahub.share.models import FileShare
|
||||
from seahub.test_utils import BaseTestCase
|
||||
|
||||
|
||||
class SendShareLinkApiTest(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
fs = FileShare.objects.create_file_link(self.user.username,
|
||||
self.repo.id, self.file, None)
|
||||
|
||||
self.token = fs.token
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo()
|
||||
|
||||
def test_can_send_email(self):
|
||||
self.login_as(self.user)
|
||||
invalid_email = 'invalid'
|
||||
url = reverse("api2-send-share-link")
|
||||
data = {
|
||||
"token": self.token,
|
||||
"email": self.admin.email + ',' + invalid_email,
|
||||
}
|
||||
|
||||
resp = self.client.post(url, data)
|
||||
if not IS_EMAIL_CONFIGURED:
|
||||
self.assertEqual(403, resp.status_code)
|
||||
else:
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['success'][0] == self.admin.email
|
||||
assert json_resp['failed'][0]['email'] == invalid_email
|
||||
|
||||
def test_can_not_send_email_if_not_link_owner(self):
|
||||
self.login_as(self.admin)
|
||||
url = reverse("api2-send-share-link")
|
||||
data = {
|
||||
"token": self.token,
|
||||
"email": self.admin.email,
|
||||
}
|
||||
|
||||
resp = self.client.post(url, data)
|
||||
self.assertEqual(403, resp.status_code)
|
46
tests/api/endpoints/test_send_upload_link.py
Normal file
46
tests/api/endpoints/test_send_upload_link.py
Normal file
@@ -0,0 +1,46 @@
|
||||
#coding: UTF-8
|
||||
import json
|
||||
from django.core.urlresolvers import reverse
|
||||
from seahub.utils import IS_EMAIL_CONFIGURED
|
||||
from seahub.test_utils import BaseTestCase
|
||||
from seahub.share.models import UploadLinkShare
|
||||
|
||||
|
||||
class SendUploadLinkApiTest(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
uls = UploadLinkShare.objects.create_upload_link_share(self.user.username,
|
||||
self.repo.id, '/')
|
||||
self.token = uls.token
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo()
|
||||
|
||||
def test_can_send_email(self):
|
||||
self.login_as(self.user)
|
||||
invalid_email = 'invalid'
|
||||
url = reverse("api2-send-upload-link")
|
||||
data = {
|
||||
"token": self.token,
|
||||
"email": self.admin.email + ',' + invalid_email,
|
||||
}
|
||||
|
||||
resp = self.client.post(url, data)
|
||||
if not IS_EMAIL_CONFIGURED:
|
||||
self.assertEqual(403, resp.status_code)
|
||||
else:
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['success'][0] == self.admin.email
|
||||
assert json_resp['failed'][0]['email'] == invalid_email
|
||||
|
||||
def test_can_not_send_email_if_not_link_owner(self):
|
||||
self.login_as(self.admin)
|
||||
url = reverse("api2-send-upload-link")
|
||||
data = {
|
||||
"token": self.token,
|
||||
"email": self.admin.email,
|
||||
}
|
||||
|
||||
resp = self.client.post(url, data)
|
||||
self.assertEqual(403, resp.status_code)
|
Reference in New Issue
Block a user