Ejemplo n.º 1
0
def update_user_attribute(user_id):
    user_to_update = get_user_by_id(user_id=user_id)
    req_json = request.get_json()
    if 'updated_by' in req_json:
        updated_by = get_user_by_id(user_id=req_json.pop('updated_by'))
    else:
        updated_by = None

    update_dct, errors = user_update_schema_load_json.load(req_json)
    if errors:
        raise InvalidRequest(errors, status_code=400)

    save_user_attribute(user_to_update, update_dict=update_dct)

    service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID'])

    # Alert user that account change took place
    user_alert_dct = update_dct.copy()
    user_alert_dct.pop('blocked', None)
    user_alert_dct.pop('current_session_id', None)
    if not updated_by and user_alert_dct:
        _update_alert(user_to_update, user_alert_dct)

    # Alert that team member edit user
    if updated_by:
        if 'email_address' in update_dct:
            template = dao_get_template_by_id(
                current_app.config['TEAM_MEMBER_EDIT_EMAIL_TEMPLATE_ID'])
            recipient = user_to_update.email_address
            reply_to = template.service.get_default_reply_to_email_address()
        elif 'mobile_number' in update_dct:
            template = dao_get_template_by_id(
                current_app.config['TEAM_MEMBER_EDIT_MOBILE_TEMPLATE_ID'])
            recipient = user_to_update.mobile_number
            reply_to = template.service.get_default_sms_sender()
        else:
            return jsonify(data=user_to_update.serialize()), 200

        saved_notification = persist_notification(
            template_id=template.id,
            template_version=template.version,
            recipient=recipient,
            service=service,
            personalisation={
                'name': user_to_update.name,
                'servicemanagername': updated_by.name,
                'email address': user_to_update.email_address
            },
            notification_type=template.template_type,
            api_key_id=None,
            key_type=KEY_TYPE_NORMAL,
            reply_to_text=reply_to)

        send_notification_to_queue(saved_notification,
                                   False,
                                   queue=QueueNames.NOTIFY)

    return jsonify(data=user_to_update.serialize()), 200
Ejemplo n.º 2
0
def test_get_all_users(notify_api, notify_db, notify_db_session, sample_user):
    assert User.query.count() == 1
    assert len(get_user_by_id()) == 1
    email = "*****@*****.**"
    another_user = create_sample_user(notify_db,
                                      notify_db_session,
                                      email=email)
    assert User.query.count() == 2
    assert len(get_user_by_id()) == 2
def send_user_2fa_code(user_id, code_type):
    user_to_send_to = get_user_by_id(user_id=user_id)

    if (verify_within_time(user_to_send_to, age=timedelta(seconds=10)) >= 1):
        raise InvalidRequest("Code already sent, wait 10 seconds",
                             status_code=400)

    if count_user_verify_codes(user_to_send_to) >= current_app.config.get(
            'MAX_VERIFY_CODE_COUNT'):
        # Prevent more than `MAX_VERIFY_CODE_COUNT` active verify codes at a time
        current_app.logger.warning(
            'Too many verify codes created for user {}'.format(
                user_to_send_to.id))
    else:
        data = request.get_json()
        if code_type == SMS_TYPE:
            validate(data, post_send_user_sms_code_schema)
            send_user_sms_code(user_to_send_to, data)
        elif code_type == EMAIL_TYPE:
            validate(data, post_send_user_email_code_schema)
            send_user_email_code(user_to_send_to, data)
        else:
            abort(404)

    return '{}', 204
Ejemplo n.º 4
0
def fido2_keys_user_validate(user_id):
    keys = list_fido2_keys(user_id)
    credentials = list(map(lambda k: pickle.loads(base64.b64decode(k.key)), keys))

    data = request.get_json()
    cbor_data = cbor.decode(base64.b64decode(data["payload"]))

    credential_id = cbor_data['credentialId']
    client_data = ClientData(cbor_data['clientDataJSON'])
    auth_data = AuthenticatorData(cbor_data['authenticatorData'])
    signature = cbor_data['signature']

    Config.FIDO2_SERVER.authenticate_complete(
        get_fido2_session(user_id),
        credentials,
        credential_id,
        client_data,
        auth_data,
        signature
    )

    user_to_verify = get_user_by_id(user_id=user_id)
    user_to_verify.current_session_id = str(uuid.uuid4())
    user_to_verify.logged_in_at = datetime.utcnow()
    user_to_verify.failed_login_count = 0
    save_model_user(user_to_verify)

    return jsonify({'status': 'OK'})
Ejemplo n.º 5
0
def send_branding_request(user_id):
    to, errors = branding_request_data_schema.load(request.get_json())
    template = dao_get_template_by_id(
        current_app.config['BRANDING_REQUEST_TEMPLATE_ID'])
    service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID'])

    saved_notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient=to['email'],
        service=service,
        personalisation={
            'email': get_user_by_id(user_id=user_id).email_address,
            'service_id': to['serviceID'],
            'service_name': to['service_name'],
            'url': get_logo_url(to['filename']),
        },
        notification_type=template.template_type,
        api_key_id=None,
        key_type=KEY_TYPE_NORMAL,
        reply_to_text=service.get_default_reply_to_email_address())
    send_notification_to_queue(saved_notification,
                               False,
                               queue=QueueNames.NOTIFY)

    return jsonify({}), 204
Ejemplo n.º 6
0
def create_broadcast_message(service_id):
    data = request.get_json()

    validate(data, create_broadcast_message_schema)
    service = dao_fetch_service_by_id(data['service_id'])
    user = get_user_by_id(data['created_by'])
    template = dao_get_template_by_id_and_service_id(data['template_id'], data['service_id'])

    personalisation = data.get('personalisation', {})
    broadcast_message = BroadcastMessage(
        service_id=service.id,
        template_id=template.id,
        template_version=template.version,
        personalisation=personalisation,
        areas={"areas": data.get("areas", []), "simple_polygons": data.get("simple_polygons", [])},
        status=BroadcastStatusType.DRAFT,
        starts_at=_parse_nullable_datetime(data.get('starts_at')),
        finishes_at=_parse_nullable_datetime(data.get('finishes_at')),
        created_by_id=user.id,
        content=template._as_utils_template_with_personalisation(
            personalisation
        ).content_with_placeholders_filled_in,
    )

    dao_save_object(broadcast_message)

    return jsonify(broadcast_message.serialize()), 201
Ejemplo n.º 7
0
def send_user_confirm_new_email(user_id):
    user_to_send_to = get_user_by_id(user_id=user_id)
    email, errors = email_data_request_schema.load(request.get_json())
    if errors:
        raise InvalidRequest(message=errors, status_code=400)

    template = dao_get_template_by_id(current_app.config['CHANGE_EMAIL_CONFIRMATION_TEMPLATE_ID'])
    service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID'])

    saved_notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient=email['email'],
        service=service,
        personalisation={
            'name': user_to_send_to.name,
            'url': _create_confirmation_url(user=user_to_send_to, email_address=email['email']),
            'feedback_url': current_app.config['ADMIN_BASE_URL'] + '/support/ask-question-give-feedback'
        },
        notification_type=template.template_type,
        api_key_id=None,
        key_type=KEY_TYPE_NORMAL,
        reply_to_text=service.get_default_reply_to_email_address()
    )

    send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY)
    return jsonify({}), 204
Ejemplo n.º 8
0
def send_user_sms_code(user_id):
    user_to_send_to = get_user_by_id(user_id=user_id)
    verify_code, errors = request_verify_code_schema.load(request.get_json())

    secret_code = create_secret_code()
    create_user_code(user_to_send_to, secret_code, SMS_TYPE)

    mobile = user_to_send_to.mobile_number if verify_code.get('to', None) is None else verify_code.get('to')
    sms_code_template_id = current_app.config['SMS_CODE_TEMPLATE_ID']
    sms_code_template = dao_get_template_by_id(sms_code_template_id)
    notify_service_id = current_app.config['NOTIFY_SERVICE_ID']

    saved_notification = persist_notification(
        template_id=sms_code_template_id,
        template_version=sms_code_template.version,
        recipient=mobile,
        service_id=notify_service_id,
        personalisation={'verify_code': secret_code},
        notification_type=SMS_TYPE,
        api_key_id=None,
        key_type=KEY_TYPE_NORMAL
    )
    # Assume that we never want to observe the Notify service's research mode
    # setting for this notification - we still need to be able to log into the
    # admin even if we're doing user research using this service:
    send_notification_to_queue(saved_notification, False, queue='notify')

    return jsonify({}), 204
Ejemplo n.º 9
0
def verify_user_code(user_id):
    data = request.get_json()
    validate(data, post_verify_code_schema)

    user_to_verify = get_user_by_id(user_id=user_id)

    code = get_user_code(user_to_verify, data['code'], data['code_type'])

    if(verify_within_time(user_to_verify) >= 2):
        raise InvalidRequest("Code already sent", status_code=400)

    if user_to_verify.failed_login_count >= current_app.config.get('MAX_VERIFY_CODE_COUNT'):
        raise InvalidRequest("Code not found", status_code=404)
    if not code:
        increment_failed_login_count(user_to_verify)
        raise InvalidRequest("Code not found", status_code=404)
    if datetime.utcnow() > code.expiry_datetime:
        # sms and email
        increment_failed_login_count(user_to_verify)
        raise InvalidRequest("Code has expired", status_code=400)
    if code.code_used:
        increment_failed_login_count(user_to_verify)
        raise InvalidRequest("Code has already been used", status_code=400)

    user_to_verify.current_session_id = str(uuid.uuid4())
    user_to_verify.logged_in_at = datetime.utcnow()
    user_to_verify.failed_login_count = 0
    save_model_user(user_to_verify)

    use_user_code(code.id)
    return jsonify({}), 204
Ejemplo n.º 10
0
def send_user_confirm_new_email(user_id):
    user_to_send_to = get_user_by_id(user_id=user_id)
    email, errors = email_data_request_schema.load(request.get_json())
    if errors:
        raise InvalidRequest(message=errors, status_code=400)

    template = dao_get_template_by_id(current_app.config['CHANGE_EMAIL_CONFIRMATION_TEMPLATE_ID'])
    notify_service_id = current_app.config['NOTIFY_SERVICE_ID']

    saved_notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient=email['email'],
        service_id=notify_service_id,
        personalisation={
            'name': user_to_send_to.name,
            'url': _create_confirmation_url(user=user_to_send_to, email_address=email['email']),
            'feedback_url': current_app.config['ADMIN_BASE_URL'] + '/feedback'
        },
        notification_type=EMAIL_TYPE,
        api_key_id=None,
        key_type=KEY_TYPE_NORMAL
    )

    send_notification_to_queue(saved_notification, False, queue='notify')
    return jsonify({}), 204
Ejemplo n.º 11
0
def send_new_user_email_verification(user_id):
    # when registering, we verify all users' email addresses using this function
    user_to_send_to = get_user_by_id(user_id=user_id)

    template = dao_get_template_by_id(current_app.config['NEW_USER_EMAIL_VERIFICATION_TEMPLATE_ID'])
    service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID'])

    saved_notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient=user_to_send_to.email_address,
        service=service,
        personalisation={
            'name': user_to_send_to.name,
            'url': _create_verification_url(user_to_send_to)
        },
        notification_type=template.template_type,
        api_key_id=None,
        key_type=KEY_TYPE_NORMAL,
        reply_to_text=service.get_default_reply_to_email_address()
    )

    send_notification_to_queue(saved_notification, False, queue=QueueNames.NOTIFY)

    return jsonify({}), 204
Ejemplo n.º 12
0
def verify_user_code(user_id):
    user_to_verify = get_user_by_id(user_id=user_id)

    txt_code = None
    resp_json = request.get_json()
    txt_type = None
    errors = {}
    try:
        txt_code = resp_json['code']
    except KeyError:
        errors.update({'code': ['Required field missing data']})
    try:
        txt_type = resp_json['code_type']
    except KeyError:
        errors.update({'code_type': ['Required field missing data']})
    if errors:
        raise InvalidRequest(errors, status_code=400)

    code = get_user_code(user_to_verify, txt_code, txt_type)
    if not code:
        raise InvalidRequest("Code not found", status_code=404)
    if datetime.utcnow() > code.expiry_datetime or code.code_used:
        raise InvalidRequest("Code has expired", status_code=400)
    use_user_code(code.id)
    return jsonify({}), 204
Ejemplo n.º 13
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
Ejemplo n.º 14
0
def activate_user(user_id):
    user = get_user_by_id(user_id=user_id)
    if user.state == 'active':
        raise InvalidRequest('User already active', status_code=400)

    user.state = 'active'
    save_model_user(user)
    return jsonify(data=user.serialize()), 200
Ejemplo n.º 15
0
def validate_created_by(service, created_by_id):
    user = get_user_by_id(created_by_id)
    if service not in user.services:
        message = 'Can’t create notification - {} is not part of the "{}" service'.format(
            user.name,
            service.name
        )
        raise BadRequestError(message=message)
Ejemplo n.º 16
0
def update_user_attribute(user_id):
    user_to_update = get_user_by_id(user_id=user_id)
    req_json = request.get_json()
    update_dct, errors = user_update_schema_load_json.load(req_json)
    if errors:
        raise InvalidRequest(errors, status_code=400)
    save_user_attribute(user_to_update, update_dict=update_dct)
    return jsonify(data=user_to_update.serialize()), 200
Ejemplo n.º 17
0
def update_user_attribute(user_id):
    user_to_update = get_user_by_id(user_id=user_id)
    req_json = request.get_json()
    update_dct, errors = user_update_schema_load_json.load(req_json)
    if errors:
        raise InvalidRequest(errors, status_code=400)
    save_user_attribute(user_to_update, update_dict=update_dct)
    return jsonify(data=user_schema.dump(user_to_update).data), 200
Ejemplo n.º 18
0
def update_password(user_id):
    user = get_user_by_id(user_id=user_id)
    req_json = request.get_json()
    pwd = req_json.get('_password')
    update_dct, errors = user_update_password_schema_load_json.load(req_json)
    if errors:
        raise InvalidRequest(errors, status_code=400)
    update_user_password(user, pwd)
    return jsonify(data=user.serialize()), 200
Ejemplo n.º 19
0
def set_permissions(user_id, service_id):
    # TODO fix security hole, how do we verify that the user
    # who is making this request has permission to make the request.
    user = get_user_by_id(user_id=user_id)
    service = dao_fetch_service_by_id(service_id=service_id)
    permissions, errors = permission_schema.load(request.get_json(), many=True)

    for p in permissions:
        p.user = user
        p.service = service
    permission_dao.set_user_service_permission(user, service, permissions, _commit=True, replace=True)
    return jsonify({}), 204
Ejemplo n.º 20
0
def set_permissions(user_id, service_id):
    # TODO fix security hole, how do we verify that the user
    # who is making this request has permission to make the request.
    user = get_user_by_id(user_id=user_id)
    service = dao_fetch_service_by_id(service_id=service_id)
    permissions, errors = permission_schema.load(request.get_json(), many=True)

    for p in permissions:
        p.user = user
        p.service = service
    permission_dao.set_user_service_permission(user, service, permissions, _commit=True, replace=True)
    return jsonify({}), 204
Ejemplo n.º 21
0
def update_user(user_id):
    user_to_update = get_user_by_id(user_id=user_id)
    req_json = request.get_json()
    update_dct, errors = user_schema_load_json.load(req_json)
    pwd = req_json.get('password', None)
    # TODO password validation, it is already done on the admin app
    # but would be good to have the same validation here.
    if pwd is not None and not pwd:
        errors.update({'password': ['Invalid data for field']})
        raise InvalidRequest(errors, status_code=400)
    save_model_user(user_to_update, update_dict=update_dct, pwd=pwd)
    return jsonify(data=user_schema.dump(user_to_update).data), 200
Ejemplo n.º 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)

    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
Ejemplo n.º 23
0
def update_password(user_id):
    user = get_user_by_id(user_id=user_id)
    req_json = request.get_json()
    password = req_json.get('_password')
    validated_email_access = req_json.pop('validated_email_access', False)
    update_dct, errors = user_update_password_schema_load_json.load(req_json)
    if errors:
        raise InvalidRequest(errors, status_code=400)
    update_user_password(user,
                         password,
                         validated_email_access=validated_email_access)
    return jsonify(data=user.serialize()), 200
Ejemplo n.º 24
0
def remove_user_from_service(service_id, user_id):
    service = dao_fetch_service_by_id(service_id)
    user = get_user_by_id(user_id=user_id)
    if user not in service.users:
        error = 'User not found'
        raise InvalidRequest(error, status_code=404)

    elif len(service.users) == 1:
        error = 'You cannot remove the only user for a service'
        raise InvalidRequest(error, status_code=400)

    dao_remove_user_from_service(service, user)
    return jsonify({}), 204
Ejemplo n.º 25
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
def dao_reduce_sms_provider_priority(identifier, *, time_threshold):
    """
    Will reduce a chosen sms provider's priority, and increase the other provider's priority by 10 points each.
    If either provider has been updated in the last `time_threshold`, then it won't take any action.
    """
    amount_to_reduce_by = 10

    # get current priority of both providers
    q = ProviderDetails.query.filter(
        ProviderDetails.notification_type == 'sms',
        ProviderDetails.active
    ).with_for_update().all()

    providers = {provider.identifier: provider for provider in q}
    other_identifier = get_alternative_sms_provider(identifier)

    # if something updated recently, don't update again. If the updated_at is null, treat it as min time
    if any((provider.updated_at or datetime.min) > datetime.utcnow() - time_threshold for provider in q):
        current_app.logger.info("Not adjusting providers, providers updated less than {} ago.".format(time_threshold))
        return

    reduced_provider = providers[identifier]
    increased_provider = providers[other_identifier]
    pre_reduction_priority = reduced_provider.priority
    pre_increase_priority = increased_provider.priority

    # always keep values between 0 and 100
    reduced_provider.priority = max(0, reduced_provider.priority - amount_to_reduce_by)
    increased_provider.priority = min(100, increased_provider.priority + amount_to_reduce_by)

    current_app.logger.info('Adjusting provider priority - {} going from {} to {}'.format(
        reduced_provider.identifier,
        pre_reduction_priority,
        reduced_provider.priority,
    ))
    current_app.logger.info('Adjusting provider priority - {} going from {} to {}'.format(
        increased_provider.identifier,
        pre_increase_priority,
        increased_provider.priority,
    ))

    # Automatic update so set as notify user
    notify_user = get_user_by_id(current_app.config['NOTIFY_USER_ID'])
    reduced_provider.created_by_id = notify_user.id
    increased_provider.created_by_id = notify_user.id

    # update without commit so that both rows can be changed without ending the transaction
    # and releasing the for_update lock
    _update_provider_details_without_commit(reduced_provider)
    _update_provider_details_without_commit(increased_provider)
Ejemplo n.º 27
0
def switch_providers(current_provider, new_provider):
    # Automatic update so set as notify user
    notify_user = get_user_by_id(current_app.config['NOTIFY_USER_ID'])
    current_provider.created_by_id = new_provider.created_by_id = notify_user.id

    # Swap priority to change primary provider
    if new_provider.priority > current_provider.priority:
        new_provider.priority, current_provider.priority = current_provider.priority, new_provider.priority

    # Increase other provider priority if equal
    elif new_provider.priority == current_provider.priority:
        current_provider.priority += 10

    _print_provider_switch_logs(current_provider, new_provider)
    return current_provider, new_provider
Ejemplo n.º 28
0
def update_broadcast_message_status(service_id, broadcast_message_id):
    data = request.get_json()

    validate(data, update_broadcast_message_status_schema)
    broadcast_message = dao_get_broadcast_message_by_id_and_service_id(broadcast_message_id, service_id)

    new_status = data['status']
    updating_user = get_user_by_id(data['created_by'])

    _update_broadcast_message(broadcast_message, new_status, updating_user)
    dao_save_object(broadcast_message)

    if new_status in {BroadcastStatusType.BROADCASTING, BroadcastStatusType.CANCELLED}:
        _create_broadcast_event(broadcast_message)

    return jsonify(broadcast_message.serialize()), 200
Ejemplo n.º 29
0
def send_user_2fa_code(user_id, code_type):
    user_to_send_to = get_user_by_id(user_id=user_id)

    if count_user_verify_codes(user_to_send_to) >= current_app.config.get('MAX_VERIFY_CODE_COUNT'):
        set_verify_codes_to_used(user_id)

    data = request.get_json()
    if code_type == SMS_TYPE:
        validate(data, post_send_user_sms_code_schema)
        send_user_sms_code(user_to_send_to, data)
    elif code_type == EMAIL_TYPE:
        validate(data, post_send_user_email_code_schema)
        send_user_email_code(user_to_send_to, data)
    else:
        abort(404)

    return '{}', 204
Ejemplo n.º 30
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
Ejemplo n.º 31
0
def verify_user_password(user_id):
    user_to_verify = get_user_by_id(user_id=user_id)

    try:
        txt_pwd = request.get_json()['password']
    except KeyError:
        message = 'Required field missing data'
        errors = {'password': [message]}
        raise InvalidRequest(errors, status_code=400)

    if user_to_verify.check_password(txt_pwd):
        reset_failed_login_count(user_to_verify)
        return jsonify({}), 204
    else:
        increment_failed_login_count(user_to_verify)
        message = 'Incorrect password'
        errors = {'password': [message]}
        raise InvalidRequest(errors, status_code=400)
Ejemplo n.º 32
0
def get_precompiled_letter_template(service_id):
    template = Template.query.filter_by(service_id=service_id,
                                        template_type=LETTER_TYPE,
                                        hidden=True).first()
    if template is not None:
        return template

    template = Template(
        name='Pre-compiled PDF',
        created_by=get_user_by_id(current_app.config['NOTIFY_USER_ID']),
        service_id=service_id,
        template_type=LETTER_TYPE,
        hidden=True,
        subject='Pre-compiled PDF',
        content='',
    )

    dao_create_template(template)

    return template
Ejemplo n.º 33
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
Ejemplo n.º 34
0
def send_user_2fa_code(user_id, code_type):
    user_to_send_to = get_user_by_id(user_id=user_id)

    if count_user_verify_codes(user_to_send_to) >= current_app.config.get(
            'MAX_VERIFY_CODE_COUNT'):
        # Prevent more than `MAX_VERIFY_CODE_COUNT` active verify codes at a time
        current_app.logger.warning(
            'Too many verify codes created for user {}'.format(
                user_to_send_to.id))
    else:
        data = request.get_json()
        if code_type == SMS_TYPE:
            validate(data, post_send_user_sms_code_schema)
            send_user_sms_code(user_to_send_to, data)
        elif code_type == EMAIL_TYPE:
            validate(data, post_send_user_email_code_schema)
            send_user_email_code(user_to_send_to, data)
        else:
            abort(404)

    return '{}', 204
Ejemplo n.º 35
0
def verify_user_password(user_id):
    user_to_verify = get_user_by_id(user_id=user_id)

    txt_pwd = None
    try:
        txt_pwd = request.get_json()['password']
    except KeyError:
        message = 'Required field missing data'
        errors = {'password': [message]}
        raise InvalidRequest(errors, status_code=400)

    if user_to_verify.check_password(txt_pwd):
        user_to_verify.logged_in_at = datetime.utcnow()
        save_model_user(user_to_verify)
        reset_failed_login_count(user_to_verify)
        return jsonify({}), 204
    else:
        increment_failed_login_count(user_to_verify)
        message = 'Incorrect password'
        errors = {'password': [message]}
        raise InvalidRequest(errors, status_code=400)
Ejemplo n.º 36
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
Ejemplo n.º 37
0
def update_password(user_id):
    user = get_user_by_id(user_id=user_id)
    req_json = request.get_json()
    pwd = req_json.get('_password')
    update_dct, errors = user_update_password_schema_load_json.load(req_json)
    if errors:
        raise InvalidRequest(errors, status_code=400)

    response = pwnedpasswords.check(pwd)
    if response > 0:
        errors.update({'password': ['Password is not allowed.']})
        raise InvalidRequest(errors, status_code=400)

    update_user_password(user, pwd)
    changes = {'password': "******"}

    try:
        _update_alert(user, changes)
    except Exception as e:
        current_app.logger.error(e)

    return jsonify(data=user.serialize()), 200
Ejemplo n.º 38
0
def send_support_user_research_consent(user_id):
    user = get_user_by_id(user_id=user_id)

    template = dao_get_template_by_id(
        current_app.config['RESEARCH_CONSENT_TEMPLATE_ID'])
    service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID'])

    notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient=current_app.config['NOTIFY_RESEARCH_EMAIL'],
        service=service,
        personalisation={
            'name': user.name,
            'email_address': user.email_address,
            'phone_number': user.mobile_number
        },
        notification_type=template.template_type,
        api_key_id=None,
        key_type=KEY_TYPE_NORMAL,
        reply_to_text=service.get_default_reply_to_email_address())
    send_notification_to_queue(notification, False, queue=QueueNames.NOTIFY)

    return jsonify({}), 204
Ejemplo n.º 39
0
def send_user_email_verification(user_id):
    user_to_send_to = get_user_by_id(user_id=user_id)
    secret_code = create_secret_code()
    create_user_code(user_to_send_to, secret_code, 'email')

    template = dao_get_template_by_id(current_app.config['EMAIL_VERIFY_CODE_TEMPLATE_ID'])

    saved_notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient=user_to_send_to.email_address,
        service_id=current_app.config['NOTIFY_SERVICE_ID'],
        personalisation={
            'name': user_to_send_to.name,
            'url': _create_verification_url(user_to_send_to, secret_code)
        },
        notification_type=EMAIL_TYPE,
        api_key_id=None,
        key_type=KEY_TYPE_NORMAL
    )

    send_notification_to_queue(saved_notification, False, queue="notify")

    return jsonify({}), 204
Ejemplo n.º 40
0
def test_get_user_invalid_id(notify_api, notify_db, notify_db_session):
    with pytest.raises(DataError):
        get_user_by_id(user_id="blah")
Ejemplo n.º 41
0
def get_user(user_id=None):
    users = get_user_by_id(user_id=user_id)
    result = user_schema.dump(users, many=True) if isinstance(users, list) else user_schema.dump(users)
    return jsonify(data=result.data)
Ejemplo n.º 42
0
def test_get_user(notify_api, notify_db, notify_db_session):
    email = "*****@*****.**"
    another_user = create_sample_user(notify_db,
                                      notify_db_session,
                                      email=email)
    assert get_user_by_id(user_id=another_user.id).email_address == email
Ejemplo n.º 43
0
def test_get_user_not_exists(notify_api, notify_db, notify_db_session, fake_uuid):
    try:
        get_user_by_id(user_id=fake_uuid)
        pytest.fail("NoResultFound exception not thrown.")
    except NoResultFound as e:
        pass