New table to store the inbound api information for a service. The table is versioned.

There is a new endpoint to create the inbound api and one to update it.
This commit is contained in:
Rebecca Law
2017-06-15 11:32:51 +01:00
parent 3fdd180515
commit 828d5cd493
12 changed files with 384 additions and 70 deletions

View File

@@ -1,10 +1,26 @@
from app import db
from datetime import datetime
from app import db, create_uuid
from app.authentication.utils import generate_secret
from app.dao.dao_utils import transactional
from app.dao.dao_utils import transactional, version_class
from app.models import ServiceInboundApi
@transactional
@version_class(ServiceInboundApi)
def save_service_inbound_api(service_inbound_api):
service_inbound_api.id = create_uuid()
service_inbound_api.created_at == datetime.utcnow()
service_inbound_api.bearer_token = generate_secret(service_inbound_api.bearer_token)
db.session.add(service_inbound_api)
@transactional
@version_class(ServiceInboundApi)
def reset_service_inbound_api(service_inbound_api):
db.session.add(service_inbound_api)
def get_service_inbound_api(service_inbound_api_id, service_id):
return ServiceInboundApi.query.filter_by(id=service_inbound_api_id,
service_id=service_id).one()

View File

@@ -295,18 +295,33 @@ class ServiceWhitelist(db.Model):
return 'Recipient {} of type: {}'.format(self.recipient, self.recipient_type)
class ServiceInboundApi(db.Model):
class ServiceInboundApi(db.Model, Versioned):
__tablename__ = 'service_inbound_api'
id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), index=True, nullable=False)
service = db.relationship('Service')
url = db.Column(db.String(255), nullable=False)
bearer_token = db.Column(db.String(255), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.datetime.utcnow, nullable=False)
updated_at = db.Column(db.DateTime, nullable=True)
updated_by = db.relationship('User')
updated_by_id = db.Column(UUID(as_uuid=True), db.ForeignKey('users.id'), index=True, nullable=False)
@property
def unsigned_bearer_token(self):
return get_secret(self.bearer_token)
def serialize(self):
return {
"id": self.id,
"service_id": self.service_id,
"url": self.url,
"bearer_token": self.bearer_token,
"updated_by_id": self.updated_by_id,
"created_at": self.created_at.strftime(DATETIME_FORMAT),
"updated_at": self.updated_at.strftime(DATETIME_FORMAT) if self.updated_at else None
}
class ApiKey(db.Model, Versioned):
__tablename__ = 'api_keys'

View File

@@ -53,12 +53,20 @@ def build_error_message(errors):
fields.append({"error": "ValidationError", "message": field})
message = {
"status_code": 400,
"errors": fields
"errors": unique_errors(fields)
}
return json.dumps(message)
def unique_errors(dups):
unique = []
for x in dups:
if x not in unique:
unique.append(x)
return unique
def __format_message(e):
def get_path(e):
error_path = None

View File

@@ -18,3 +18,13 @@ personalisation = {
"code": "1001", # yet to be implemented
"link": "link to our error documentation not yet implemented"
}
https_url = {
"type": "string",
"format": "uri",
"pattern": "^https.*",
"validationMessage": "is not a valid https url",
"code": "1001", # yet to be implemented
"link": "link to our error documentation not yet implemented"
}

View File

@@ -11,6 +11,7 @@ from flask import (
from sqlalchemy.orm.exc import NoResultFound
from app import redis_store
from app.authentication.utils import generate_secret
from app.dao import notification_usage_dao, notifications_dao
from app.dao.dao_utils import dao_rollback
from app.dao.api_key_dao import (
@@ -20,7 +21,11 @@ from app.dao.api_key_dao import (
expire_api_key)
from app.dao.date_util import get_financial_year
from app.dao.notification_usage_dao import get_total_billable_units_for_sent_sms_notifications_in_date_range
from app.dao.service_inbound_api_dao import save_service_inbound_api
from app.dao.service_inbound_api_dao import (
save_service_inbound_api,
reset_service_inbound_api,
get_service_inbound_api
)
from app.dao.services_dao import (
dao_fetch_service_by_id,
dao_fetch_all_services,
@@ -51,7 +56,9 @@ from app.errors import (
register_errors
)
from app.models import Service, ServiceInboundApi
from app.schema_validation import validate
from app.service import statistics
from app.service.service_inbound_api_schema import service_inbound_api, update_service_inbound_api_schema
from app.service.utils import get_whitelist_objects
from app.service.sender import send_notification_to_service_users
from app.schemas import (
@@ -535,9 +542,29 @@ def get_yearly_monthly_usage(service_id):
@service_blueprint.route('/<uuid:service_id>/inbound-api', methods=['POST'])
def set_service_inbound_api(service_id):
def create_service_inbound_api(service_id):
data = request.get_json()
validate(data, service_inbound_api)
data["service_id"] = service_id
save_service_inbound_api(ServiceInboundApi(**data))
inbound_api = ServiceInboundApi(**data)
save_service_inbound_api(inbound_api)
return jsonify(data="Service inbound api data saved"), 201
return jsonify(data=inbound_api.serialize()), 201
@service_blueprint.route('/<uuid:service_id>/inbound-api/<uuid:id>', methods=['POST'])
def update_service_inbound_api(service_id, id):
data = request.get_json()
validate(data, update_service_inbound_api_schema)
to_update = get_service_inbound_api(id, service_id)
if data.get("url", None):
to_update.url = data["url"]
if data.get("bearer_token", None):
to_update.bearer_token = generate_secret(data["bearer_token"])
to_update.updated_by_id = data["updated_by_id"]
to_update.updated_at = datetime.utcnow()
reset_service_inbound_api(to_update)
return jsonify(data=to_update.serialize()), 200

View File

@@ -0,0 +1,27 @@
from app.schema_validation.definitions import uuid, https_url
service_inbound_api = {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "POST service inbound api schema",
"type": "object",
"title": "Create service inbound api",
"properties": {
"url": https_url,
"bearer_token": {"type": "string", "minLength": 10},
"updated_by_id": uuid
},
"required": ["url", "bearer_token", "updated_by_id"]
}
update_service_inbound_api_schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "POST service inbound api schema",
"type": "object",
"title": "Create service inbound api",
"properties": {
"url": https_url,
"bearer_token": {"type": "string", "minLength": 10},
"updated_by_id": uuid
},
"required": ["updated_by_id"]
}