Example #1
0
def update_service(service_id):
    try:
        service = get_model_services(service_id=service_id)
    except DataError:
        return jsonify(result="error", message="Invalid service id"), 400
    except NoResultFound:
        return jsonify(result="error", message="Service not found"), 404
    if request.method == 'DELETE':
        status_code = 202
        delete_model_service(service)
    else:
        status_code = 200
        # TODO there has got to be a better way to do the next three lines
        upd_serv, errors = service_schema.load(request.get_json())
        if errors:
            return jsonify(result="error", message=errors), 400
        update_dict, errors = service_schema.dump(upd_serv)
        # TODO FIX ME
        # Remove update_service model which is added to db.session
        db.session.rollback()
        try:
            save_model_service(service, update_dict=update_dict)
        except DAOException as e:
            return jsonify(result="error", message=str(e)), 400
    return jsonify(data=service_schema.dump(service).data), status_code
Example #2
0
def update_service(service_id):
    try:
        service = get_model_services(service_id=service_id)
    except DataError:
        return jsonify(result="error", message="Invalid service id"), 400
    except NoResultFound:
        return jsonify(result="error", message="Service not found"), 404
    if request.method == 'DELETE':
        status_code = 202
        delete_model_service(service)
    else:
        status_code = 200
        # TODO there has got to be a better way to do the next three lines
        upd_serv, errors = service_schema.load(request.get_json())
        if errors:
            return jsonify(result="error", message=errors), 400
        update_dict, errors = service_schema.dump(upd_serv)
        # TODO FIX ME
        # Remove update_service model which is added to db.session
        db.session.rollback()
        try:
            save_model_service(service, update_dict=update_dict)
        except DAOException as e:
            return jsonify(result="error", message=str(e)), 400
    return jsonify(data=service_schema.dump(service).data), status_code
Example #3
0
def update_service(service_id):
    req_json = request.get_json()

    fetched_service = dao_fetch_service_by_id(service_id)
    # Capture the status change here as Marshmallow changes this later
    service_going_live = fetched_service.restricted and not req_json.get(
        'restricted', True)
    current_data = dict(service_schema.dump(fetched_service).data.items())
    current_data.update(request.get_json())

    service = service_schema.load(current_data).data

    if 'email_branding' in req_json:
        email_branding_id = req_json['email_branding']
        service.email_branding = None if not email_branding_id else EmailBranding.query.get(
            email_branding_id)
    if 'letter_branding' in req_json:
        letter_branding_id = req_json['letter_branding']
        service.letter_branding = None if not letter_branding_id else LetterBranding.query.get(
            letter_branding_id)
    dao_update_service(service)

    if service_going_live:
        send_notification_to_service_users(
            service_id=service_id,
            template_id=current_app.config['SERVICE_NOW_LIVE_TEMPLATE_ID'],
            personalisation={
                'service_name': current_data['name'],
                'message_limit': '{:,}'.format(current_data['message_limit'])
            },
            include_user_fields=['name'])

    return jsonify(data=service_schema.dump(fetched_service).data), 200
Example #4
0
def update_service(service_id):
    req_json = request.get_json()
    fetched_service = dao_fetch_service_by_id(service_id)
    # Capture the status change here as Marshmallow changes this later
    service_going_live = fetched_service.restricted and not req_json.get(
        "restricted", True)
    message_limit_changed = fetched_service.message_limit != req_json.get(
        "message_limit", fetched_service.message_limit)
    current_data = dict(service_schema.dump(fetched_service).data.items())

    current_data.update(request.get_json())

    service = service_schema.load(current_data).data

    if "email_branding" in req_json:
        email_branding_id = req_json["email_branding"]
        service.email_branding = None if not email_branding_id else EmailBranding.query.get(
            email_branding_id)
    if "letter_branding" in req_json:
        letter_branding_id = req_json["letter_branding"]
        service.letter_branding = None if not letter_branding_id else LetterBranding.query.get(
            letter_branding_id)

    dao_update_service(service)

    if message_limit_changed:
        redis_store.delete(daily_limit_cache_key(service_id))
        redis_store.delete(near_daily_limit_cache_key(service_id))
        redis_store.delete(over_daily_limit_cache_key(service_id))
        if not fetched_service.restricted:
            _warn_service_users_about_message_limit_changed(
                service_id, current_data)

    if service_going_live:
        _warn_services_users_about_going_live(service_id, current_data)

        try:
            # Two scenarios, if there is a user that has requested to go live, we will use that user
            # to create a user-service/contact-deal pair between notify and zendesk sell
            # If by any chance there is no tracked request to a user, notify will try to identify the user
            # that created the service and then create a user-service/contact-deal relationship
            if service.go_live_user_id:
                user = get_user_by_id(service.go_live_user_id)
            else:
                user = dao_fetch_service_creator(service.id)

            ZenDeskSell().send_go_live_service(service, user)
        except Exception as e:
            current_app.logger.exception(e)

    return jsonify(data=service_schema.dump(fetched_service).data), 200
Example #5
0
def update_service(service_id):
    req_json = request.get_json()
    fetched_service = dao_fetch_service_by_id(service_id)
    # Capture the status change here as Marshmallow changes this later
    service_going_live = fetched_service.restricted and not req_json.get('restricted', True)
    service_go_live_requested = 'go_live_user' in req_json
    current_data = dict(service_schema.dump(fetched_service).data.items())
    current_data.update(request.get_json())

    service = service_schema.load(current_data).data

    if 'email_branding' in req_json:
        email_branding_id = req_json['email_branding']
        service.email_branding = None if not email_branding_id else EmailBranding.query.get(email_branding_id)
    if 'letter_branding' in req_json:
        letter_branding_id = req_json['letter_branding']
        service.letter_branding = None if not letter_branding_id else LetterBranding.query.get(letter_branding_id)
    dao_update_service(service)

    if service_go_live_requested:
        template = dao_get_template_by_id(current_app.config['NOTIFY_ADMIN_OF_GO_LIVE_REQUEST_TEMPLATE_ID'])
        service_url = "{}/services/{}".format(current_app.config['ADMIN_BASE_URL'], str(service.id))
        saved_notification = persist_notification(
            template_id=template.id,
            template_version=template.version,
            recipient=get_or_build_support_email_address(),
            service=template.service,
            personalisation={
                'service_name': service.name,
                'service_dashboard_url': service_url
            },
            notification_type=EMAIL_TYPE,
            api_key_id=None,
            key_type=KEY_TYPE_NORMAL,
            reply_to_text=get_or_build_support_email_address()
        )
        send_notification_to_queue(saved_notification, research_mode=False, queue=QueueNames.NOTIFY)

    if service_going_live:
        send_notification_to_service_users(
            service_id=service_id,
            template_id=current_app.config['SERVICE_NOW_LIVE_TEMPLATE_ID'],
            personalisation={
                'service_name': current_data['name'],
                'message_limit': '{:,}'.format(current_data['message_limit'])
            },
            include_user_fields=['name']
        )

    return jsonify(data=service_schema.dump(fetched_service).data), 200
Example #6
0
def get_services():
    only_active = request.args.get('only_active') == 'True'
    detailed = request.args.get('detailed') == 'True'
    user_id = request.args.get('user_id', None)
    include_from_test_key = request.args.get('include_from_test_key',
                                             'True') != 'False'

    # If start and end date are not set, we are expecting today's stats.
    today = str(datetime.utcnow().date())

    start_date = datetime.strptime(request.args.get('start_date', today),
                                   '%Y-%m-%d').date()
    end_date = datetime.strptime(request.args.get('end_date', today),
                                 '%Y-%m-%d').date()

    if user_id:
        services = dao_fetch_all_services_by_user(user_id, only_active)
    elif detailed:
        result = jsonify(data=get_detailed_services(
            start_date=start_date,
            end_date=end_date,
            only_active=only_active,
            include_from_test_key=include_from_test_key))
        return result
    else:
        services = dao_fetch_all_services(only_active)
    data = service_schema.dump(services, many=True).data
    return jsonify(data=data)
def test_send_sms_to_provider_should_return_template_if_found_in_redis(
        mocker, client, sample_template):
    from app.schemas import service_schema, template_schema
    service_dict = service_schema.dump(sample_template.service).data
    template_dict = template_schema.dump(sample_template).data

    mocker.patch(
        'app.redis_store.get',
        side_effect=[
            json.dumps({
                'data': service_dict
            }).encode('utf-8'),
            json.dumps({
                'data': template_dict
            }).encode('utf-8'),
        ],
    )
    mock_get_template = mocker.patch(
        'app.dao.templates_dao.dao_get_template_by_id_and_service_id')
    mock_get_service = mocker.patch(
        'app.dao.services_dao.dao_fetch_service_by_id')

    send_mock = mocker.patch('app.mmg_client.send_sms')
    notification = create_notification(template=sample_template,
                                       to_field='+447700900855',
                                       normalised_to='447700900855')
    send_to_providers.send_sms_to_provider(notification)
    assert mock_get_template.called is False
    assert mock_get_service.called is False
    send_mock.assert_called_once_with(to=notification.normalised_to,
                                      content=ANY,
                                      reference=str(notification.id),
                                      sender=notification.reply_to_text)
Example #8
0
def create_service():
    data = request.get_json()

    if not data.get("user_id"):
        errors = {"user_id": ["Missing data for required field."]}
        raise InvalidRequest(errors, status_code=400)
    data.pop("service_domain", None)

    # validate json with marshmallow
    service_schema.load(data)

    user = get_user_by_id(data.pop("user_id"))

    # unpack valid json into service object
    valid_service = Service.from_json(data)

    dao_create_service(valid_service, user)

    try:
        # try-catch; just in case, we don't want to error here
        ZenDeskSell().send_create_service(valid_service, user)
    except Exception as e:
        current_app.logger.exception(e)

    return jsonify(data=service_schema.dump(valid_service).data), 201
Example #9
0
def get_services():
    only_active = request.args.get("only_active") == "True"
    detailed = request.args.get("detailed") == "True"
    user_id = request.args.get("user_id", None)
    include_from_test_key = request.args.get("include_from_test_key",
                                             "True") != "False"

    # If start and end date are not set, we are expecting today's stats.
    today = str(datetime.utcnow().date())

    start_date = datetime.strptime(request.args.get("start_date", today),
                                   "%Y-%m-%d").date()
    end_date = datetime.strptime(request.args.get("end_date", today),
                                 "%Y-%m-%d").date()

    if user_id:
        services = dao_fetch_all_services_by_user(user_id, only_active)
    elif detailed:
        result = jsonify(data=get_detailed_services(
            start_date=start_date,
            end_date=end_date,
            only_active=only_active,
            include_from_test_key=include_from_test_key,
        ))
        return result
    else:
        services = dao_fetch_all_services(only_active)
    data = service_schema.dump(services, many=True).data
    return jsonify(data=data)
Example #10
0
def get_service_by_id(service_id):
    if request.args.get('detailed') == 'True':
        data = get_detailed_service(service_id, today_only=request.args.get('today_only') == 'True')
    else:
        fetched = dao_fetch_service_by_id(service_id)

        data = service_schema.dump(fetched).data
    return jsonify(data=data)
Example #11
0
    def get_dict(service_id):
        from app.schemas import service_schema

        service_dict = service_schema.dump(
            dao_fetch_service_by_id(service_id)).data
        db.session.commit()

        return {'data': service_dict}
Example #12
0
def get_service_by_id(service_id):
    if request.args.get("detailed") == "True":
        data = get_detailed_service(
            service_id, today_only=request.args.get("today_only") == "True")
    else:
        fetched = dao_fetch_service_by_id(service_id)

        data = service_schema.dump(fetched).data
    return jsonify(data=data)
Example #13
0
def get_service(service_id=None):
    user_id = request.args.get('user_id', None)
    try:
        services = get_model_services(service_id=service_id, user_id=user_id)
    except DataError:
        return jsonify(result="error", message="Invalid service id"), 400
    except NoResultFound:
        return jsonify(result="error", message="Service not found"), 404
    data, errors = services_schema.dump(services) if isinstance(services, list) else service_schema.dump(services)
    return jsonify(data=data)
Example #14
0
def get_service(service_id=None):
    user_id = request.args.get('user_id', None)
    try:
        services = get_model_services(service_id=service_id, user_id=user_id)
    except DataError:
        return jsonify(result="error", message="Invalid service id"), 400
    except NoResultFound:
        return jsonify(result="error", message="Service not found"), 404
    data, errors = services_schema.dump(services) if isinstance(
        services, list) else service_schema.dump(services)
    return jsonify(data=data)
Example #15
0
def test_services_schema_includes_providers(sample_service, ses_provider,
                                            current_sms_provider):
    from app.schemas import service_schema

    sample_service.email_provider_id = ses_provider.id
    sample_service.sms_provider_id = current_sms_provider.id

    data = service_schema.dump(sample_service).data
    assert data
    assert data['email_provider_id'] == str(ses_provider.id)
    assert data['sms_provider_id'] == str(current_sms_provider.id)
Example #16
0
def create_service():
    # TODO what exceptions get passed from schema parsing?
    service, errors = service_schema.load(request.get_json())
    if errors:
        return jsonify(result="error", message=errors), 400
    # I believe service is already added to the session but just needs a
    # db.session.commit
    try:
        save_model_service(service)
    except DAOException as e:
        return jsonify(result="error", message=str(e)), 400
    return jsonify(data=service_schema.dump(service).data), 201
Example #17
0
def add_user_to_service(service_id, user_id):
    service = dao_fetch_service_by_id(service_id)
    user = get_user_by_id(user_id=user_id)

    if user in service.users:
        error = 'User id: {} already part of service id: {}'.format(user_id, service_id)
        raise InvalidRequest(error, status_code=400)

    permissions = permission_schema.load(request.get_json(), many=True).data
    dao_add_user_to_service(service, user, permissions)
    data = service_schema.dump(service).data
    return jsonify(data=data), 201
Example #18
0
def create_service():
    # TODO what exceptions get passed from schema parsing?
    service, errors = service_schema.load(request.get_json())
    if errors:
        return jsonify(result="error", message=errors), 400
    # I believe service is already added to the session but just needs a
    # db.session.commit
    try:
        save_model_service(service)
    except DAOException as e:
        return jsonify(result="error", message=str(e)), 400
    return jsonify(data=service_schema.dump(service).data), 201
Example #19
0
def test_should_cache_template_and_service_in_redis(mocker, client, sample_template):

    from app.schemas import service_schema, template_schema

    mock_redis_get = mocker.patch(
        'app.redis_store.get',
        return_value=None,
    )
    mock_redis_set = mocker.patch(
        'app.redis_store.set',
    )

    mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')

    data = {
        'phone_number': '+447700900855',
        'template_id': str(sample_template.id),
    }

    auth_header = create_authorization_header(service_id=sample_template.service_id)
    client.post(
        path='/v2/notifications/sms',
        data=json.dumps(data),
        headers=[('Content-Type', 'application/json'), auth_header]
    )

    expected_service_key = f'service-{sample_template.service_id}'
    expected_templates_key = f'service-{sample_template.service_id}-template-{sample_template.id}-version-None'

    assert mock_redis_get.call_args_list == [
        call(expected_service_key),
        call(expected_templates_key),
    ]

    service_dict = service_schema.dump(sample_template.service).data
    template_dict = template_schema.dump(sample_template).data

    assert len(mock_redis_set.call_args_list) == 2

    service_call, templates_call = mock_redis_set.call_args_list

    assert service_call[0][0] == expected_service_key
    assert json.loads(service_call[0][1]) == {'data': service_dict}
    assert service_call[1]['ex'] == 604_800

    assert templates_call[0][0] == expected_templates_key
    assert json.loads(templates_call[0][1]) == {'data': template_dict}
    assert templates_call[1]['ex'] == 604_800
Example #20
0
def get_service_by_user_id(user_id, service_id=None):
    try:
        user = get_model_users(user_id=user_id)
    except DataError:
        return jsonify(result="error", message="Invalid user id"), 400
    except NoResultFound:
        return jsonify(result="error", message="User not found"), 404

    try:
        services = get_model_services(user_id=user.id, service_id=service_id)
    except DataError:
        return jsonify(result="error", message="Invalid service id"), 400
    except NoResultFound:
        return jsonify(result="error", message="Service not found"), 404
    services, errors = services_schema.dump(services) if isinstance(
        services, list) else service_schema.dump(services)
    return jsonify(data=services)
Example #21
0
def create_service():
    data = request.get_json()

    if not data.get('user_id'):
        errors = {'user_id': ['Missing data for required field.']}
        raise InvalidRequest(errors, status_code=400)

    # validate json with marshmallow
    service_schema.load(data)

    user = get_user_by_id(data.pop('user_id'))

    # unpack valid json into service object
    valid_service = Service.from_json(data)

    dao_create_service(valid_service, user)
    return jsonify(data=service_schema.dump(valid_service).data), 201
Example #22
0
def add_user_to_service(service_id, user_id):
    service = dao_fetch_service_by_id(service_id)
    user = get_user_by_id(user_id=user_id)

    if user in service.users:
        error = 'User id: {} already part of service id: {}'.format(user_id, service_id)
        raise InvalidRequest(error, status_code=400)

    data = request.get_json()
    validate(data, post_set_permissions_schema)

    permissions = [
        Permission(service_id=service_id, user_id=user_id, permission=p['permission'])
        for p in data['permissions']
    ]
    folder_permissions = data.get('folder_permissions', [])

    dao_add_user_to_service(service, user, permissions, folder_permissions)
    data = service_schema.dump(service).data
    return jsonify(data=data), 201
Example #23
0
def set_as_broadcast_service(service_id):
    """
    This route does the following
    - adds a service broadcast settings to define which channel broadcasts should go out on
    - removes all current service permissions and adds the broadcast service permission
    - sets the services `count_as_live` to false
    - adds the service to the broadcast organisation
    - puts the service into training mode or live mode
    """
    data = validate(request.get_json(), service_broadcast_settings_schema)
    service = dao_fetch_service_by_id(service_id)

    set_broadcast_service_type(
        service,
        service_mode=data["service_mode"],
        broadcast_channel=data["broadcast_channel"],
        provider_restriction=data["provider_restriction"])

    data = service_schema.dump(service).data
    return jsonify(data=data)
Example #24
0
def create_service():
    data = request.get_json()

    if not data.get('user_id'):
        errors = {'user_id': ['Missing data for required field.']}
        raise InvalidRequest(errors, status_code=400)
    data.pop('service_domain', None)

    # validate json with marshmallow
    service_schema.load(data)

    user = get_user_by_id(data.pop('user_id'))

    # unpack valid json into service object
    valid_service = Service.from_json(data)

    with transaction():
        dao_create_service(valid_service, user)
        set_default_free_allowance_for_service(service=valid_service, year_start=None)

    return jsonify(data=service_schema.dump(valid_service).data), 201
def test_should_return_template_if_found_in_redis(mocker, client,
                                                  sample_template):

    from app.schemas import service_schema, template_schema
    service_dict = service_schema.dump(sample_template.service).data
    template_dict = template_schema.dump(sample_template).data

    mocker.patch(
        'app.redis_store.get',
        side_effect=[
            json.dumps({
                'data': service_dict
            }).encode('utf-8'),
            json.dumps({
                'data': template_dict
            }).encode('utf-8'),
        ],
    )
    mock_get_template = mocker.patch(
        'app.dao.templates_dao.dao_get_template_by_id_and_service_id')
    mock_get_service = mocker.patch(
        'app.dao.services_dao.dao_fetch_service_by_id')

    mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')

    data = {
        'phone_number': '+447700900855',
        'template_id': str(sample_template.id),
    }

    auth_header = create_authorization_header(
        service_id=sample_template.service_id)
    response = client.post(path='/v2/notifications/sms',
                           data=json.dumps(data),
                           headers=[('Content-Type', 'application/json'),
                                    auth_header])

    assert response.status_code == 201
    assert mock_get_template.called is False
    assert mock_get_service.called is False
def test_send_email_to_provider_should_return_template_if_found_in_redis(
        mocker, client, sample_email_template):
    from app.schemas import service_schema, template_schema
    service_dict = service_schema.dump(sample_email_template.service).data
    template_dict = template_schema.dump(sample_email_template).data

    mocker.patch(
        'app.redis_store.get',
        side_effect=[
            json.dumps({
                'data': service_dict
            }).encode('utf-8'),
            json.dumps({
                'data': template_dict
            }).encode('utf-8'),
        ],
    )
    mock_get_template = mocker.patch(
        'app.dao.templates_dao.dao_get_template_by_id_and_service_id')
    mock_get_service = mocker.patch(
        'app.dao.services_dao.dao_fetch_service_by_id')
    send_mock = mocker.patch('app.aws_ses_client.send_email',
                             return_value='reference')
    notification = create_notification(template=sample_email_template,
                                       to_field='*****@*****.**',
                                       normalised_to='*****@*****.**')

    send_to_providers.send_email_to_provider(notification)
    assert mock_get_template.called is False
    assert mock_get_service.called is False
    send_mock.assert_called_once_with(
        ANY,
        notification.normalised_to,
        ANY,
        body=ANY,
        html_body=ANY,
        reply_to_address=notification.reply_to_text)
Example #27
0
def get_service_by_user_id(user_id, service_id=None):
    try:
        user = get_model_users(user_id=user_id)
    except DataError:
        return jsonify(result="error", message="Invalid user id"), 400
    except NoResultFound:
        return jsonify(result="error", message="User not found"), 404

    try:
        services = get_model_services(user_id=user.id, service_id=service_id)
    except DataError:
        return jsonify(result="error", message="Invalid service id"), 400
    except NoResultFound:
        return jsonify(result="error", message="Service not found"), 404
    services, errors = services_schema.dump(services) if isinstance(services, list) else service_schema.dump(services)
    return jsonify(data=services)