2020-06-22 09:39:46 +01:00
|
|
|
from collections import defaultdict
|
|
|
|
|
from functools import partial
|
|
|
|
|
from threading import RLock
|
|
|
|
|
|
|
|
|
|
import cachetools
|
2021-06-02 10:58:57 +01:00
|
|
|
from flask import current_app
|
2020-06-22 09:39:47 +01:00
|
|
|
from notifications_utils.clients.redis import RequestCache
|
2020-07-03 14:27:28 +01:00
|
|
|
from notifications_utils.serialised_model import (
|
|
|
|
|
SerialisedModel,
|
|
|
|
|
SerialisedModelCollection,
|
|
|
|
|
)
|
2020-06-26 14:10:12 +01:00
|
|
|
from werkzeug.utils import cached_property
|
|
|
|
|
|
|
|
|
|
from app import db, redis_store
|
|
|
|
|
from app.dao.api_key_dao import get_model_api_keys
|
|
|
|
|
from app.dao.services_dao import dao_fetch_service_by_id
|
2020-06-22 10:20:51 +01:00
|
|
|
|
2020-06-22 09:39:46 +01:00
|
|
|
caches = defaultdict(partial(cachetools.TTLCache, maxsize=1024, ttl=2))
|
|
|
|
|
locks = defaultdict(RLock)
|
2020-06-22 09:39:47 +01:00
|
|
|
redis_cache = RequestCache(redis_store)
|
2020-06-22 09:39:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def memory_cache(func):
|
|
|
|
|
@cachetools.cached(
|
|
|
|
|
cache=caches[func.__qualname__],
|
|
|
|
|
lock=locks[func.__qualname__],
|
|
|
|
|
key=ignore_first_argument_cache_key,
|
|
|
|
|
)
|
|
|
|
|
def wrapper(*args, **kwargs):
|
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return wrapper
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def ignore_first_argument_cache_key(cls, *args, **kwargs):
|
|
|
|
|
return cachetools.keys.hashkey(*args, **kwargs)
|
|
|
|
|
|
2020-06-22 10:20:51 +01:00
|
|
|
|
2020-06-22 10:20:53 +01:00
|
|
|
class SerialisedTemplate(SerialisedModel):
|
2020-06-22 10:20:51 +01:00
|
|
|
ALLOWED_PROPERTIES = {
|
|
|
|
|
'archived',
|
2020-06-22 10:20:52 +01:00
|
|
|
'content',
|
2020-06-22 10:20:51 +01:00
|
|
|
'id',
|
|
|
|
|
'process_type',
|
|
|
|
|
'reply_to_text',
|
2020-06-22 10:20:52 +01:00
|
|
|
'subject',
|
2020-06-22 10:20:51 +01:00
|
|
|
'template_type',
|
|
|
|
|
'version',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2020-06-22 09:39:46 +01:00
|
|
|
@memory_cache
|
2020-09-26 15:11:38 +01:00
|
|
|
def from_id_and_service_id(cls, template_id, service_id, version=None):
|
|
|
|
|
return cls(cls.get_dict(template_id, service_id, version)['data'])
|
2020-06-22 10:20:51 +01:00
|
|
|
|
|
|
|
|
@staticmethod
|
2020-09-26 15:11:38 +01:00
|
|
|
@redis_cache.set('service-{service_id}-template-{template_id}-version-{version}')
|
|
|
|
|
def get_dict(template_id, service_id, version):
|
2020-06-26 14:10:21 +01:00
|
|
|
from app.dao import templates_dao
|
2020-06-22 10:20:51 +01:00
|
|
|
from app.schemas import template_schema
|
|
|
|
|
|
|
|
|
|
fetched_template = templates_dao.dao_get_template_by_id_and_service_id(
|
|
|
|
|
template_id=template_id,
|
2020-09-26 15:11:38 +01:00
|
|
|
service_id=service_id,
|
|
|
|
|
version=version,
|
2020-06-22 10:20:51 +01:00
|
|
|
)
|
|
|
|
|
|
2022-05-06 15:52:44 +01:00
|
|
|
template_dict = template_schema.dump(fetched_template)
|
2020-06-26 14:10:12 +01:00
|
|
|
db.session.commit()
|
2020-06-22 10:20:51 +01:00
|
|
|
|
2020-06-23 15:09:38 +01:00
|
|
|
return {'data': template_dict}
|
2020-06-26 14:10:12 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class SerialisedService(SerialisedModel):
|
|
|
|
|
ALLOWED_PROPERTIES = {
|
|
|
|
|
'id',
|
2021-02-16 14:24:40 +00:00
|
|
|
'name',
|
2020-06-26 14:10:12 +01:00
|
|
|
'active',
|
|
|
|
|
'contact_link',
|
|
|
|
|
'email_from',
|
2020-06-26 13:38:58 +01:00
|
|
|
'message_limit',
|
2023-04-28 12:37:06 -07:00
|
|
|
'total_message_limit',
|
2020-06-26 14:10:12 +01:00
|
|
|
'permissions',
|
2020-06-26 13:38:58 +01:00
|
|
|
'rate_limit',
|
2020-06-26 14:10:12 +01:00
|
|
|
'research_mode',
|
|
|
|
|
'restricted',
|
2021-02-16 14:24:40 +00:00
|
|
|
'prefix_sms',
|
|
|
|
|
'email_branding'
|
2020-06-26 14:10:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
@memory_cache
|
|
|
|
|
def from_id(cls, service_id):
|
|
|
|
|
return cls(cls.get_dict(service_id)['data'])
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
@redis_cache.set('service-{service_id}')
|
|
|
|
|
def get_dict(service_id):
|
|
|
|
|
from app.schemas import service_schema
|
|
|
|
|
|
2022-05-06 15:52:44 +01:00
|
|
|
service_dict = service_schema.dump(dao_fetch_service_by_id(service_id))
|
2020-06-26 14:10:12 +01:00
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
|
|
return {'data': service_dict}
|
|
|
|
|
|
|
|
|
|
@cached_property
|
|
|
|
|
def api_keys(self):
|
|
|
|
|
return SerialisedAPIKeyCollection.from_service_id(self.id)
|
|
|
|
|
|
2021-06-02 10:58:57 +01:00
|
|
|
@property
|
|
|
|
|
def high_volume(self):
|
|
|
|
|
return self.id in current_app.config['HIGH_VOLUME_SERVICE']
|
|
|
|
|
|
2020-06-26 14:10:12 +01:00
|
|
|
|
|
|
|
|
class SerialisedAPIKey(SerialisedModel):
|
|
|
|
|
ALLOWED_PROPERTIES = {
|
|
|
|
|
'id',
|
|
|
|
|
'secret',
|
|
|
|
|
'expiry_date',
|
|
|
|
|
'key_type',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SerialisedAPIKeyCollection(SerialisedModelCollection):
|
|
|
|
|
model = SerialisedAPIKey
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
@memory_cache
|
|
|
|
|
def from_service_id(cls, service_id):
|
|
|
|
|
keys = [
|
|
|
|
|
{k: getattr(key, k) for k in SerialisedAPIKey.ALLOWED_PROPERTIES}
|
|
|
|
|
for key in get_model_api_keys(service_id)
|
|
|
|
|
]
|
|
|
|
|
db.session.commit()
|
|
|
|
|
return cls(keys)
|