[email] Only one email bot per hood - reducing API

This commit is contained in:
maike 2020-07-13 03:21:11 +02:00 committed by dl6tom
parent 4bee982005
commit b9dafa9fc8
4 changed files with 17 additions and 27 deletions

View file

@ -10,7 +10,7 @@ from kibicara.config import config
from kibicara.email import send_email from kibicara.email import send_email
from kibicara.webapi.hoods import get_hood, get_hood_unauthorized from kibicara.webapi.hoods import get_hood, get_hood_unauthorized
from pydantic import BaseModel from pydantic import BaseModel
from ormantic.exceptions import NoMatch, MultipleMatches from ormantic.exceptions import NoMatch
from sqlite3 import IntegrityError from sqlite3 import IntegrityError
from kibicara.webapi.admin import from_token, to_token from kibicara.webapi.admin import from_token, to_token
from os import urandom from os import urandom
@ -35,23 +35,17 @@ class Subscriber(BaseModel):
email: str email: str
async def get_email(hood, email_id=None): async def get_email(hood):
""" Get Email row by hood. """ Get Email row by hood.
You can specify an email_id to nail it down, but it works without as well. You can specify an email_id to nail it down, but it works without as well.
:param hood: Hood the Email bot belongs to. :param hood: Hood the Email bot belongs to.
:param email_id: id of the email row you are looking for.
:return: Email row of the found email bot. :return: Email row of the found email bot.
""" """
try: try:
return await Email.objects.get(hood=hood) return await Email.objects.get(hood=hood)
except NoMatch: except NoMatch:
return HTTPException(status_code=status.HTTP_404_NOT_FOUND) return HTTPException(status_code=status.HTTP_404_NOT_FOUND)
except MultipleMatches:
# Email rows *should* be unique - the unique constraint doesn't work yet though.
if email_id is None:
email_id = hood.id
return await Email.objects.get(hood=hood, id=email_id)
# registers the routes, gets imported in /kibicara/webapi/__init__.py # registers the routes, gets imported in /kibicara/webapi/__init__.py
@ -73,14 +67,14 @@ async def email_create(hood=Depends(get_hood)):
raise HTTPException(status_code=status.HTTP_409_CONFLICT) raise HTTPException(status_code=status.HTTP_409_CONFLICT)
@router.delete('/{email_id}', status_code=status.HTTP_204_NO_CONTENT) @router.delete('/', status_code=status.HTTP_204_NO_CONTENT)
async def email_delete(email_id, hood=Depends(get_hood)): async def email_delete(hood=Depends(get_hood)):
""" Delete an Email bot. Call this when deleting a hood. """ Delete an Email bot. Call this when deleting a hood.
Stops and deletes the Email bot as well as all subscribers. Stops and deletes the Email bot as well as all subscribers.
:param hood: Hood the Email bot belongs to. :param hood: Hood the Email bot belongs to.
""" """
email_row = await get_email(hood, email_id=email_id) email_row = await get_email(hood)
spawner.stop(email_row) spawner.stop(email_row)
await EmailSubscribers.objects.delete_many(hood=hood.id) await EmailSubscribers.objects.delete_many(hood=hood.id)
await email_row.delete() await email_row.delete()
@ -147,9 +141,9 @@ async def email_unsubscribe(token, hood=Depends(get_hood_unauthorized)):
) )
@router.post('/messages/{email_id}', status_code=status.HTTP_201_CREATED) @router.post('/messages/', status_code=status.HTTP_201_CREATED)
async def email_message_create( async def email_message_create(
email_id, message: BodyMessage, hood=Depends(get_hood_unauthorized) message: BodyMessage, hood=Depends(get_hood_unauthorized)
): ):
""" Receive a message from the MDA and pass it to the censor. """ Receive a message from the MDA and pass it to the censor.
@ -159,7 +153,7 @@ async def email_message_create(
""" """
# get bot via "To:" header # get bot via "To:" header
try: try:
email_row = await get_email(hood, email_id=email_id) email_row = await get_email(hood)
except HTTPException as exc: except HTTPException as exc:
raise exc raise exc
# check API secret # check API secret
@ -172,6 +166,7 @@ async def email_message_create(
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED) raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
# pass message.text to bot.py # pass message.text to bot.py
if await spawner.get(email_row).publish(Message(message.text)): if await spawner.get(email_row).publish(Message(message.text)):
pass logger.warning("Message was accepted: " + message.text)
else: else:
logger.warning("Message was't accepted: " + message.text)
raise HTTPException(status_code=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS) raise HTTPException(status_code=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS)

View file

@ -84,7 +84,9 @@ def hood_id(client, auth_header):
@fixture(scope='function') @fixture(scope='function')
def trigger_id(client, hood_id, auth_header): def trigger_id(client, hood_id, auth_header):
response = client.post( response = client.post(
'/api/hoods/%d/triggers/' % hood_id, json={'pattern': 'te'}, headers=auth_header '/api/hoods/%d/triggers/' % hood_id,
json={'pattern': 'test'},
headers=auth_header,
) )
assert response.status_code == status.HTTP_201_CREATED assert response.status_code == status.HTTP_201_CREATED
trigger_id = int(response.headers['Location']) trigger_id = int(response.headers['Location'])
@ -127,7 +129,4 @@ def email_row(client, hood_id, auth_header):
response = client.post('/api/hoods/%d/email/' % hood_id, headers=auth_header) response = client.post('/api/hoods/%d/email/' % hood_id, headers=auth_header)
assert response.status_code == status.HTTP_409_CONFLICT assert response.status_code == status.HTTP_409_CONFLICT
yield email_row yield email_row
# not sure if necessary; it raises problems at least client.delete('/api/hoods/%d/email/' % hood_id, headers=auth_header)
client.delete(
'/api/hoods/%d/email/%d' % (hood_id, email_row['id']), headers=auth_header
)

View file

@ -11,7 +11,7 @@ def test_email_create_unauthorized(client, hood_id):
def test_email_delete_unauthorized(client, hood_id, email_row): def test_email_delete_unauthorized(client, hood_id, email_row):
response = client.delete('/api/hoods/%d/email/%d' % (hood_id, email_row['id'])) response = client.delete('/api/hoods/%d/email/' % hood_id)
assert response.status_code == status.HTTP_401_UNAUTHORIZED assert response.status_code == status.HTTP_401_UNAUTHORIZED
@ -20,7 +20,5 @@ def test_email_delete_unauthorized(client, hood_id, email_row):
def test_email_message_unauthorized(client, hood_id, email_row): def test_email_message_unauthorized(client, hood_id, email_row):
body = {"text": "test", "author": "author", "secret": "wrong"} body = {"text": "test", "author": "author", "secret": "wrong"}
response = client.post( response = client.post('/api/hoods/%d/email/messages/' % hood_id, json=body)
'/api/hoods/%d/email/messages/%d' % (hood_id, email_row['id']), json=body
)
assert response.status_code == status.HTTP_401_UNAUTHORIZED assert response.status_code == status.HTTP_401_UNAUTHORIZED

View file

@ -34,9 +34,7 @@ def test_email_message_wrong(client, hood_id, email_row):
'author': "test@localhost", 'author': "test@localhost",
'secret': email_row['secret'], 'secret': email_row['secret'],
} }
response = client.post( response = client.post('/api/hoods/%d/email/messages/' % hood_id, json=body)
'/api/hoods/%d/email/messages/%d' % (hood_id, email_row['id']), json=body
)
assert response.status_code == status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS assert response.status_code == status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS