1
0
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:
xiez
2016-03-07 13:31:57 +08:00
5 changed files with 315 additions and 0 deletions

View 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)

View 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)

View File

@@ -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()),

View 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)

View 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)