2016-02-03 13:16:19 +00:00
|
|
|
import re
|
2016-02-01 10:48:33 +00:00
|
|
|
from flask_marshmallow.fields import fields
|
2016-01-11 15:07:13 +00:00
|
|
|
from . import ma
|
2016-01-08 17:51:46 +00:00
|
|
|
from . import models
|
2016-02-26 15:57:24 +00:00
|
|
|
from app.dao.permissions_dao import permission_dao
|
2016-02-03 13:16:19 +00:00
|
|
|
from marshmallow import (post_load, ValidationError, validates, validates_schema)
|
2016-03-01 14:21:28 +00:00
|
|
|
from marshmallow_sqlalchemy import field_for
|
2016-02-03 13:16:19 +00:00
|
|
|
|
|
|
|
|
mobile_regex = re.compile("^\\+44[\\d]{10}$")
|
2016-02-01 10:48:33 +00:00
|
|
|
|
2016-02-22 17:17:29 +00:00
|
|
|
email_regex = re.compile("(^[^@^\\s]+@[^@^\\.^\\s]+(\\.[^@^\\.^\\s]*)*\.(.+))")
|
|
|
|
|
|
2016-01-08 17:51:46 +00:00
|
|
|
|
2016-01-11 15:07:13 +00:00
|
|
|
# TODO I think marshmallow provides a better integration and error handling.
|
|
|
|
|
# Would be better to replace functionality in dao with the marshmallow supported
|
|
|
|
|
# functionality.
|
|
|
|
|
# http://marshmallow.readthedocs.org/en/latest/api_reference.html
|
2016-01-08 17:51:46 +00:00
|
|
|
|
2016-01-11 15:07:13 +00:00
|
|
|
|
2016-01-29 11:11:00 +00:00
|
|
|
class BaseSchema(ma.ModelSchema):
|
2016-01-28 11:41:21 +00:00
|
|
|
def __init__(self, *args, load_json=False, **kwargs):
|
|
|
|
|
self.load_json = load_json
|
2016-01-29 11:11:00 +00:00
|
|
|
super(BaseSchema, self).__init__(*args, **kwargs)
|
2016-01-11 15:07:13 +00:00
|
|
|
|
2016-02-26 12:00:16 +00:00
|
|
|
__envelope__ = {
|
|
|
|
|
'single': None,
|
|
|
|
|
'many': None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def get_envelope_key(self, many):
|
|
|
|
|
"""Helper to get the envelope key."""
|
|
|
|
|
key = self.__envelope__['many'] if many else self.__envelope__['single']
|
|
|
|
|
assert key is not None, "Envelope key undefined"
|
|
|
|
|
return key
|
|
|
|
|
|
|
|
|
|
# Code to envelope the input and response.
|
|
|
|
|
# TOBE added soon.
|
|
|
|
|
|
|
|
|
|
# @pre_load(pass_many=True)
|
|
|
|
|
# def unwrap_envelope(self, data, many):
|
|
|
|
|
# key = self.get_envelope_key(many)
|
|
|
|
|
# return data[key]
|
|
|
|
|
|
|
|
|
|
# @post_dump(pass_many=True)
|
|
|
|
|
# def wrap_with_envelope(self, data, many):
|
|
|
|
|
# key = self.get_envelope_key(many)
|
|
|
|
|
# return {key: data}
|
|
|
|
|
|
2016-01-28 11:41:21 +00:00
|
|
|
@post_load
|
|
|
|
|
def make_instance(self, data):
|
|
|
|
|
"""Deserialize data to an instance of the model. Update an existing row
|
|
|
|
|
if specified in `self.instance` or loaded by primary key(s) in the data;
|
|
|
|
|
else create a new row.
|
|
|
|
|
:param data: Data to deserialize.
|
|
|
|
|
"""
|
|
|
|
|
if self.load_json:
|
|
|
|
|
return data
|
2016-01-29 11:11:00 +00:00
|
|
|
return super(BaseSchema, self).make_instance(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserSchema(BaseSchema):
|
2016-02-26 15:57:24 +00:00
|
|
|
|
|
|
|
|
permissions = fields.Method("user_permissions", dump_only=True)
|
|
|
|
|
|
|
|
|
|
def user_permissions(self, usr):
|
|
|
|
|
retval = {}
|
|
|
|
|
for x in permission_dao.get_query({'user': usr.id}):
|
|
|
|
|
service_id = str(x.service_id)
|
|
|
|
|
if service_id not in retval:
|
|
|
|
|
retval[service_id] = []
|
|
|
|
|
retval[service_id].append(x.permission)
|
|
|
|
|
return retval
|
|
|
|
|
|
2016-01-29 11:11:00 +00:00
|
|
|
class Meta:
|
|
|
|
|
model = models.User
|
|
|
|
|
exclude = (
|
|
|
|
|
"updated_at", "created_at", "user_to_service",
|
|
|
|
|
"_password", "verify_codes")
|
2016-01-28 11:41:21 +00:00
|
|
|
|
2016-01-08 17:51:46 +00:00
|
|
|
|
2016-01-29 11:11:00 +00:00
|
|
|
class ServiceSchema(BaseSchema):
|
2016-01-08 17:51:46 +00:00
|
|
|
class Meta:
|
|
|
|
|
model = models.Service
|
2016-02-02 14:16:08 +00:00
|
|
|
exclude = ("updated_at", "created_at", "api_keys", "templates", "jobs", 'old_id')
|
2016-01-13 11:04:13 +00:00
|
|
|
|
|
|
|
|
|
2016-01-29 11:11:00 +00:00
|
|
|
class TemplateSchema(BaseSchema):
|
2016-01-13 11:04:13 +00:00
|
|
|
class Meta:
|
|
|
|
|
model = models.Template
|
2016-01-15 15:48:05 +00:00
|
|
|
exclude = ("updated_at", "created_at", "service_id", "jobs")
|
2016-01-11 15:07:13 +00:00
|
|
|
|
2016-01-08 17:51:46 +00:00
|
|
|
|
2016-01-29 11:11:00 +00:00
|
|
|
class ApiKeySchema(BaseSchema):
|
2016-01-13 09:25:46 +00:00
|
|
|
class Meta:
|
2016-01-19 12:07:00 +00:00
|
|
|
model = models.ApiKey
|
2016-01-20 15:23:32 +00:00
|
|
|
exclude = ("service", "secret")
|
2016-01-14 11:30:45 +00:00
|
|
|
|
2016-01-13 09:25:46 +00:00
|
|
|
|
2016-01-29 11:11:00 +00:00
|
|
|
class JobSchema(BaseSchema):
|
2016-01-15 15:48:05 +00:00
|
|
|
class Meta:
|
|
|
|
|
model = models.Job
|
|
|
|
|
|
|
|
|
|
|
2016-02-19 11:37:35 +00:00
|
|
|
class RequestVerifyCodeSchema(ma.Schema):
|
|
|
|
|
to = fields.Str(required=False)
|
|
|
|
|
|
|
|
|
|
|
2016-02-03 13:16:19 +00:00
|
|
|
class NotificationSchema(ma.Schema):
|
2016-02-29 11:23:34 +00:00
|
|
|
personalisation = fields.Dict(required=False)
|
2016-02-03 13:16:19 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SmsNotificationSchema(NotificationSchema):
|
|
|
|
|
to = fields.Str(required=True)
|
|
|
|
|
|
|
|
|
|
@validates('to')
|
|
|
|
|
def validate_to(self, value):
|
|
|
|
|
if not mobile_regex.match(value):
|
|
|
|
|
raise ValidationError('Invalid phone number, must be of format +441234123123')
|
|
|
|
|
|
|
|
|
|
|
2016-02-22 17:17:29 +00:00
|
|
|
class EmailNotificationSchema(NotificationSchema):
|
|
|
|
|
to = fields.Str(required=True)
|
|
|
|
|
template = fields.Int(required=True)
|
|
|
|
|
|
|
|
|
|
@validates('to')
|
|
|
|
|
def validate_to(self, value):
|
|
|
|
|
if not email_regex.match(value):
|
|
|
|
|
raise ValidationError('Invalid email')
|
|
|
|
|
|
|
|
|
|
|
2016-02-03 13:16:19 +00:00
|
|
|
class SmsTemplateNotificationSchema(SmsNotificationSchema):
|
|
|
|
|
template = fields.Int(required=True)
|
2016-02-08 14:54:15 +00:00
|
|
|
job = fields.String()
|
2016-02-03 13:16:19 +00:00
|
|
|
|
|
|
|
|
|
2016-02-23 17:30:50 +00:00
|
|
|
class JobSmsTemplateNotificationSchema(SmsNotificationSchema):
|
|
|
|
|
template = fields.Int(required=True)
|
|
|
|
|
job = fields.String(required=True)
|
|
|
|
|
|
|
|
|
|
|
2016-02-24 09:55:05 +00:00
|
|
|
class JobEmailTemplateNotificationSchema(EmailNotificationSchema):
|
|
|
|
|
template = fields.Int(required=True)
|
|
|
|
|
job = fields.String(required=True)
|
|
|
|
|
|
|
|
|
|
|
2016-02-03 13:16:19 +00:00
|
|
|
class SmsAdminNotificationSchema(SmsNotificationSchema):
|
|
|
|
|
content = fields.Str(required=True)
|
|
|
|
|
|
|
|
|
|
|
2016-02-09 14:17:42 +00:00
|
|
|
class NotificationStatusSchema(BaseSchema):
|
|
|
|
|
|
|
|
|
|
class Meta:
|
2016-02-16 14:06:56 +00:00
|
|
|
model = models.Notification
|
2016-02-09 14:17:42 +00:00
|
|
|
|
|
|
|
|
|
2016-02-24 14:01:19 +00:00
|
|
|
class InvitedUserSchema(BaseSchema):
|
2016-02-29 09:49:12 +00:00
|
|
|
|
2016-02-24 14:01:19 +00:00
|
|
|
class Meta:
|
|
|
|
|
model = models.InvitedUser
|
|
|
|
|
|
|
|
|
|
@validates('email_address')
|
|
|
|
|
def validate_to(self, value):
|
|
|
|
|
if not email_regex.match(value):
|
|
|
|
|
raise ValidationError('Invalid email')
|
|
|
|
|
|
|
|
|
|
|
2016-02-26 12:00:16 +00:00
|
|
|
class PermissionSchema(BaseSchema):
|
|
|
|
|
|
2016-03-01 14:21:28 +00:00
|
|
|
# Override generated fields
|
|
|
|
|
user = field_for(models.Permission, 'user', dump_only=True)
|
|
|
|
|
service = field_for(models.Permission, 'service', dump_only=True)
|
|
|
|
|
permission = field_for(models.Permission, 'permission')
|
|
|
|
|
|
2016-02-26 12:00:16 +00:00
|
|
|
__envelope__ = {
|
|
|
|
|
'single': 'permission',
|
|
|
|
|
'many': 'permissions',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = models.Permission
|
|
|
|
|
exclude = ("created_at",)
|
|
|
|
|
|
|
|
|
|
|
2016-03-07 15:21:05 +00:00
|
|
|
class EmailDataSchema(ma.Schema):
|
|
|
|
|
email = fields.Str(required=False)
|
|
|
|
|
|
|
|
|
|
@validates('email')
|
|
|
|
|
def validate_to(self, value):
|
|
|
|
|
if not email_regex.match(value):
|
|
|
|
|
raise ValidationError('Invalid email')
|
|
|
|
|
|
2016-01-11 15:07:13 +00:00
|
|
|
user_schema = UserSchema()
|
2016-01-28 11:41:21 +00:00
|
|
|
user_schema_load_json = UserSchema(load_json=True)
|
2016-01-08 17:51:46 +00:00
|
|
|
service_schema = ServiceSchema()
|
2016-01-29 11:11:00 +00:00
|
|
|
service_schema_load_json = ServiceSchema(load_json=True)
|
2016-01-13 11:04:13 +00:00
|
|
|
template_schema = TemplateSchema()
|
2016-01-29 11:11:00 +00:00
|
|
|
template_schema_load_json = TemplateSchema(load_json=True)
|
2016-01-19 12:07:00 +00:00
|
|
|
api_key_schema = ApiKeySchema()
|
2016-01-29 11:11:00 +00:00
|
|
|
api_key_schema_load_json = ApiKeySchema(load_json=True)
|
2016-01-15 15:48:05 +00:00
|
|
|
job_schema = JobSchema()
|
2016-01-29 11:11:00 +00:00
|
|
|
job_schema_load_json = JobSchema(load_json=True)
|
2016-02-01 10:48:33 +00:00
|
|
|
request_verify_code_schema = RequestVerifyCodeSchema()
|
2016-02-03 13:16:19 +00:00
|
|
|
sms_admin_notification_schema = SmsAdminNotificationSchema()
|
|
|
|
|
sms_template_notification_schema = SmsTemplateNotificationSchema()
|
2016-02-23 17:30:50 +00:00
|
|
|
job_sms_template_notification_schema = JobSmsTemplateNotificationSchema()
|
2016-02-03 13:16:19 +00:00
|
|
|
email_notification_schema = EmailNotificationSchema()
|
2016-02-24 09:55:05 +00:00
|
|
|
job_email_template_notification_schema = JobEmailTemplateNotificationSchema()
|
2016-02-09 14:17:42 +00:00
|
|
|
notification_status_schema = NotificationStatusSchema()
|
|
|
|
|
notification_status_schema_load_json = NotificationStatusSchema(load_json=True)
|
2016-02-24 14:01:19 +00:00
|
|
|
invited_user_schema = InvitedUserSchema()
|
2016-02-26 12:00:16 +00:00
|
|
|
permission_schema = PermissionSchema()
|
2016-03-07 15:21:05 +00:00
|
|
|
email_data_request_schema = EmailDataSchema()
|