[email] Add start, stop, status REST endpoints

This commit is contained in:
Cathy Hu 2020-07-18 13:53:11 +02:00
parent 9e765e970a
commit 268e1d6853
4 changed files with 31 additions and 14 deletions

View file

@ -7,7 +7,7 @@
from databases import Database from databases import Database
from kibicara.config import config from kibicara.config import config
from ormantic import Integer, ForeignKey, Model, Text from ormantic import Boolean, Integer, ForeignKey, Model, Text
from sqlalchemy import create_engine, MetaData from sqlalchemy import create_engine, MetaData
@ -39,6 +39,7 @@ class Hood(Model):
id: Integer(primary_key=True) = None id: Integer(primary_key=True) = None
name: Text(unique=True) name: Text(unique=True)
landingpage: Text() landingpage: Text()
email_enabled: Boolean() = True
class Mapping(Mapping): class Mapping(Mapping):
table_name = 'hoods' table_name = 'hoods'

View file

@ -20,6 +20,7 @@ logger = getLogger(__name__)
class EmailBot(Censor): class EmailBot(Censor):
def __init__(self, hood): def __init__(self, hood):
super().__init__(hood) super().__init__(hood)
self.enabled = hood.email_enabled
async def run(self): async def run(self):
""" Loop which waits for new messages and sends emails to all subscribers. """ """ Loop which waits for new messages and sends emails to all subscribers. """
@ -28,7 +29,6 @@ class EmailBot(Censor):
logger.debug( logger.debug(
'Received message from censor (%s): %s' % (self.hood.name, message.text) 'Received message from censor (%s): %s' % (self.hood.name, message.text)
) )
logger.debug('a')
for subscriber in await EmailSubscribers.objects.filter( for subscriber in await EmailSubscribers.objects.filter(
hood=self.hood hood=self.hood
).all(): ).all():

View file

@ -15,7 +15,7 @@ from kibicara.webapi.hoods import get_hood, get_hood_unauthorized
from logging import getLogger from logging import getLogger
from ormantic.exceptions import NoMatch from ormantic.exceptions import NoMatch
from os import urandom from os import urandom
from pydantic import BaseModel from pydantic import BaseModel, validator
from smtplib import SMTPException from smtplib import SMTPException
from sqlite3 import IntegrityError from sqlite3 import IntegrityError
@ -26,6 +26,12 @@ logger = getLogger(__name__)
class BodyEmail(BaseModel): class BodyEmail(BaseModel):
name: str name: str
@validator('name')
def valid_prefix(cls, value):
if not value.startswith('kibicara-'):
raise ValueError('Recipient address didn\'t start with kibicara-')
return value
class BodyMessage(BaseModel): class BodyMessage(BaseModel):
""" This model shows which values are supplied by the MDA listener script. """ """ This model shows which values are supplied by the MDA listener script. """
@ -76,32 +82,40 @@ async def email_create(values: BodyEmail, response: Response, hood=Depends(get_h
:param hood: Hood row of the hood the Email bot is supposed to belong to. :param hood: Hood row of the hood the Email bot is supposed to belong to.
:return: Email row of the new email bot. :return: Email row of the new email bot.
""" """
if not values.name.startswith('kibicara-'):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Recipient address didn\'t start with kibicara-',
)
try: try:
email = await Email.objects.create( email = await Email.objects.create(
hood=hood, secret=urandom(32).hex(), **values.__dict__ hood=hood, secret=urandom(32).hex(), **values.__dict__
) )
spawner.start(email)
response.headers['Location'] = '%d' % hood.id response.headers['Location'] = '%d' % hood.id
return email return email
except IntegrityError: except IntegrityError:
raise HTTPException(status_code=status.HTTP_409_CONFLICT) raise HTTPException(status_code=status.HTTP_409_CONFLICT)
@router.get('/status', status_code=status.HTTP_200_OK)
async def email_status(hood=Depends(get_hood)):
return {'status': spawner.get(hood).status.name}
@router.post('/start', status_code=status.HTTP_200_OK)
async def email_start(hood=Depends(get_hood)):
await hood.update(email_enabled=True)
spawner.get(hood).start()
return {}
@router.post('/stop', status_code=status.HTTP_200_OK)
async def email_stop(hood=Depends(get_hood)):
await hood.update(email_enabled=False)
spawner.get(hood).stop()
return {}
@router.get('/{email_id}') @router.get('/{email_id}')
async def email_read(email=Depends(get_email)): async def email_read(email=Depends(get_email)):
return email return email
@router.put('/{email_id}', status_code=status.HTTP_204_NO_CONTENT)
async def email_update(email=Depends(get_email)):
await email.update() # TODO
@router.delete('/{email_id}', status_code=status.HTTP_204_NO_CONTENT) @router.delete('/{email_id}', status_code=status.HTTP_204_NO_CONTENT)
async def email_delete(email=Depends(get_email)): async def email_delete(email=Depends(get_email)):
""" Delete an Email bot. """ Delete an Email bot.

View file

@ -7,6 +7,7 @@
from fastapi import APIRouter, Depends, HTTPException, Response, status from fastapi import APIRouter, Depends, HTTPException, Response, status
from kibicara.model import AdminHoodRelation, Hood from kibicara.model import AdminHoodRelation, Hood
from kibicara.platforms.email.bot import spawner
from kibicara.webapi.admin import get_admin from kibicara.webapi.admin import get_admin
from ormantic.exceptions import NoMatch from ormantic.exceptions import NoMatch
from pydantic import BaseModel from pydantic import BaseModel
@ -58,6 +59,7 @@ async def hood_create(values: BodyHood, response: Response, admin=Depends(get_ad
try: try:
hood = await Hood.objects.create(**values.__dict__) hood = await Hood.objects.create(**values.__dict__)
await AdminHoodRelation.objects.create(admin=admin.id, hood=hood.id) await AdminHoodRelation.objects.create(admin=admin.id, hood=hood.id)
spawner.start(hood)
response.headers['Location'] = '%d' % hood.id response.headers['Location'] = '%d' % hood.id
return hood return hood
except IntegrityError: except IntegrityError: