예제 #1
0
def create_api_key(service_id):
    key_names = [
        key['name'] for key in api_key_api_client.get_api_keys(
            service_id=service_id)['apiKeys']
    ]
    form = CreateKeyForm(key_names)
    form.key_type.choices = [
        (KEY_TYPE_NORMAL, 'Live – sends to anyone'),
        (KEY_TYPE_TEAM, 'Team and whitelist – limits who you can send to'),
        (KEY_TYPE_TEST, 'Test – pretends to send messages'),
    ]
    disabled_options, option_hints = [], {}
    if current_service['restricted']:
        disabled_options = [KEY_TYPE_NORMAL]
        option_hints[KEY_TYPE_NORMAL] = Markup(
            'Not available because your service is in '
            '<a href="{}#trial-mode">trial mode</a>'.format(
                url_for(".using_notify")))
    if 'letter' in current_service['permissions']:
        option_hints[KEY_TYPE_TEAM] = 'Can’t be used to send letters'
    if form.validate_on_submit():
        if form.key_type.data in disabled_options:
            abort(400)
        secret = api_key_api_client.create_api_key(service_id=service_id,
                                                   key_name=form.key_name.data,
                                                   key_type=form.key_type.data)
        return render_template('views/api/keys/show.html',
                               secret=secret,
                               service_id=service_id,
                               key_name=email_safe(form.key_name.data,
                                                   whitespace='_'))
    return render_template('views/api/keys/create.html',
                           form=form,
                           disabled_options=disabled_options,
                           option_hints=option_hints)
예제 #2
0
def create_api_key(service_id):
    form = CreateKeyForm(current_service.api_keys)
    form.key_type.choices = [
        (KEY_TYPE_NORMAL, _l("Live – sends to anyone")),
        (KEY_TYPE_TEAM, _l("Team and safelist – limits who you can send to")),
        (KEY_TYPE_TEST, _l("Test – pretends to send messages")),
    ]
    disabled_options, option_hints = [], {}
    if current_service.trial_mode:
        disabled_options = [KEY_TYPE_NORMAL]
        option_hints[KEY_TYPE_NORMAL] = Markup(
            _l("Not available because your service is in trial mode."))
    if current_service.has_permission("letter"):
        option_hints[KEY_TYPE_TEAM] = ""
    if form.validate_on_submit():
        if form.key_type.data in disabled_options:
            abort(400)
        secret = api_key_api_client.create_api_key(
            service_id=service_id,
            key_name=form.key_name.data,
            key_type=form.key_type.data,
        )
        return render_template(
            "views/api/keys/show.html",
            secret=secret,
            service_id=service_id,
            key_name=email_safe(form.key_name.data, whitespace="_"),
        )
    return render_template(
        "views/api/keys/create.html",
        form=form,
        disabled_options=disabled_options,
        option_hints=option_hints,
    )
예제 #3
0
def add_service():
    default_organisation_type = "central"
    form = CreateServiceForm(organisation_type=default_organisation_type)
    heading = _('Name your service in both official languages')

    if form.validate_on_submit():
        email_from = email_safe(form.name.data)
        service_name = form.name.data

        service_id, error = _create_service(
            service_name,
            default_organisation_type,
            email_from,
            form,
        )
        if error:
            return render_template('views/add-service.html',
                                   form=form,
                                   heading=heading)

        return redirect(
            url_for('main.service_dashboard', service_id=service_id))

    else:
        return render_template(
            'views/add-service.html',
            form=form,
            heading=heading,
            default_organisation_type=default_organisation_type,
        )
예제 #4
0
def create_api_key(service_id):
    key_names = [
        key['name'] for key in api_key_api_client.get_api_keys(service_id=service_id)['apiKeys']
    ]
    form = CreateKeyForm(key_names)
    form.key_type.choices = filter(None, [
        (KEY_TYPE_NORMAL, 'Send messages to anyone')
        if not current_service['restricted'] else None,
        (KEY_TYPE_TEST, 'Simulate sending messages to anyone'),
        (KEY_TYPE_TEAM, 'Only send messages to your team or whitelist')
    ])
    if form.validate_on_submit():
        secret = api_key_api_client.create_api_key(
            service_id=service_id,
            key_name=form.key_name.data,
            key_type=form.key_type.data
        )
        return render_template(
            'views/api/keys/show.html',
            secret=secret,
            service_id=service_id,
            key_name=email_safe(form.key_name.data, whitespace='_')
        )
    return render_template(
        'views/api/keys/create.html',
        form=form
    )
def service_name_change_confirm(service_id):
    # Validate password for form
    def _check_password(pwd):
        return user_api_client.verify_password(current_user.id, pwd)

    form = ConfirmPasswordForm(_check_password)

    if form.validate_on_submit():
        current_service['name'] = session['service_name_change']
        current_service['email_from'] = email_safe(session['service_name_change'])
        try:
            service_api_client.update_service(
                current_service['id'],
                current_service['name'],
                current_service['active'],
                current_service['message_limit'],
                current_service['restricted'],
                current_service['users'],
                current_service['email_from'])
        except HTTPError as e:
            error_msg = "Duplicate service name '{}'".format(session['service_name_change'])
            if e.status_code == 400 and error_msg in e.message['name']:
                # Redirect the user back to the change service name screen
                flash('This service name is already in use', 'error')
                return redirect(url_for('main.service_name_change', service_id=service_id))
            else:
                raise e
        else:
            session.pop('service_name_change')
            return redirect(url_for('.service_settings', service_id=service_id))
    return render_template(
        'views/service-settings/confirm.html',
        heading='Change your service name',
        form=form)
def service_name_change_confirm(service_id):
    if 'service_name_change' not in session:
        flash("The change you made was not saved. Please try again.", 'error')
        return redirect(
            url_for('main.service_name_change', service_id=service_id))

    # Validate password for form
    def _check_password(pwd):
        return user_api_client.verify_password(current_user.id, pwd)

    form = ConfirmPasswordForm(_check_password)

    if form.validate_on_submit():
        try:
            current_service.update(name=session['service_name_change'],
                                   email_from=email_safe(
                                       session['service_name_change']))
        except HTTPError as e:
            error_msg = "Duplicate service name '{}'".format(
                session['service_name_change'])
            if e.status_code == 400 and error_msg in e.message['name']:
                # Redirect the user back to the change service name screen
                flash('This service name is already in use', 'error')
                return redirect(
                    url_for('main.service_name_change', service_id=service_id))
            else:
                raise e
        else:
            session.pop('service_name_change')
            return redirect(url_for('.service_settings',
                                    service_id=service_id))
    return render_template('views/service-settings/confirm.html',
                           heading='Change your service name',
                           form=form)
def service_name_change(service_id):
    form = RenameServiceForm()

    if request.method == 'GET':
        form.name.data = current_service.name

    if form.validate_on_submit():

        if form.name.data == current_service.name:
            return redirect(url_for('.service_settings',
                                    service_id=service_id))

        unique_name = service_api_client.is_service_name_unique(
            service_id, form.name.data, email_safe(form.name.data))

        if not unique_name:
            form.name.errors.append("This service name is already in use")
            return render_template('views/service-settings/name.html',
                                   form=form)

        session['service_name_change'] = form.name.data
        return redirect(
            url_for('.service_name_change_confirm', service_id=service_id))

    if current_service.organisation_type == 'local':
        return render_template(
            'views/service-settings/name-local.html',
            form=form,
        )

    return render_template(
        'views/service-settings/name.html',
        form=form,
    )
예제 #8
0
def add_service():
    current_step = request.args.get("current_step", None)
    # if nothing supplied or bad data in the querystring, default
    if not current_step or current_step not in WIZARD_ORDER:
        current_step = DEFAULT_STEP
    # init session
    if SESSION_FORM_KEY not in session:
        session[SESSION_FORM_KEY] = {}
    # get the right form class
    form_cls = WIZARD_DICT[current_step]["form_cls"]
    # as the form always does a 302 after success, GET is a fresh form with possible re-use of session data i.e. Back
    if request.method == "GET":
        return _renderTemplateStep(form_cls(data=session[SESSION_FORM_KEY]), current_step)
    # must be a POST, continue to validate
    form = form_cls(request.form)
    if not form.validate_on_submit():
        # invalid form, re-render with validation response
        return _renderTemplateStep(form, current_step)
    # valid form, save data and move on or finalize
    # get the current place in the wizard based on ordering
    idx = WIZARD_ORDER.index(current_step)
    if idx < len(WIZARD_ORDER) - 1:
        # more steps to go, save valid submitted data to session and redirct to next form
        current_step = WIZARD_ORDER[idx + 1]
        session[SESSION_FORM_KEY].update(form.data)
        return redirect(url_for(".add_service", current_step=current_step))
    # no more steps left, re-validate validate session in case of stale session data
    data = session[SESSION_FORM_KEY]
    data.update(form.data)  # add newly submitted data from POST
    # iterate through all forms and validate
    for step in WIZARD_ORDER:
        temp_form_cls = WIZARD_DICT[step]["form_cls"]
        temp_form = temp_form_cls(data=data)
        if not temp_form.validate():  # something isn't right, jump to the form with bad / missing data
            return redirect(url_for(".add_service", current_step=step))

    # all forms valid from session data, time to transact
    email_from = email_safe(data["email_from"])
    service_name = data["name"]
    default_branding_is_french = data["default_branding"] == FieldWithLanguageOptions.FRENCH_OPTION_VALUE

    service_result: ServiceResult = _create_service(
        service_name,
        DEFAULT_ORGANISATION_TYPE,
        email_from,
        default_branding_is_french,
    )

    # clear session after API POST
    session.pop(SESSION_FORM_KEY, None)

    if service_result.is_success():
        return redirect(url_for("main.service_dashboard", service_id=service_result.service_id))
    form_cls = WIZARD_DICT[current_step]["form_cls"]
    form = form_cls(request.form)
    session[SESSION_FORM_KEY] = form.data
    if isinstance(service_result, DuplicateNameResult):
        form.validate()  # Necessary to make the `errors` field mutable!
        form.name.errors.append(_("This service name is already in use"))
    return _renderTemplateStep(form, current_step)
def test_should_redirect_after_service_name_confirmation(
    app_,
    active_user_with_permissions,
    service_one,
    mocker,
    mock_update_service,
    mock_verify_password,
    mock_get_organisation
):
    with app_.test_request_context():
        with app_.test_client() as client:
            client.login(active_user_with_permissions, mocker, service_one)
            service_id = service_one['id']
            service_new_name = 'New Name'
            with client.session_transaction() as session:
                session['service_name_change'] = service_new_name
            response = client.post(url_for(
                'main.service_name_change_confirm', service_id=service_id))

        assert response.status_code == 302
        settings_url = url_for('main.service_settings', service_id=service_id, _external=True)
        assert settings_url == response.location
        mock_update_service.assert_called_once_with(
            service_id,
            name=service_new_name,
            email_from=email_safe(service_new_name)
        )
        assert mock_verify_password.called
예제 #10
0
def create_api_key(service_id):
    form = CreateKeyForm(current_service.api_keys)
    form.key_type.choices = [
        (KEY_TYPE_NORMAL, 'Live – sends to anyone'),
        (KEY_TYPE_TEAM, 'Team and whitelist – limits who you can send to'),
        (KEY_TYPE_TEST, 'Test – pretends to send messages'),
    ]
    disabled_options, option_hints = [], {}
    if current_service.trial_mode:
        disabled_options = [KEY_TYPE_NORMAL]
        option_hints[KEY_TYPE_NORMAL] = Markup(
            'Not available because your service is in '
            '<a href="/features/trial-mode">trial mode</a>')
    if current_service.has_permission('letter'):
        option_hints[KEY_TYPE_TEAM] = 'Cannot be used to send letters'
    if form.validate_on_submit():
        if form.key_type.data in disabled_options:
            abort(400)
        secret = api_key_api_client.create_api_key(service_id=service_id,
                                                   key_name=form.key_name.data,
                                                   key_type=form.key_type.data)
        return render_template('views/api/keys/show.html',
                               secret=secret,
                               service_id=service_id,
                               key_name=email_safe(form.key_name.data,
                                                   whitespace='_'))
    return render_template('views/api/keys/create.html',
                           form=form,
                           disabled_options=disabled_options,
                           option_hints=option_hints)
예제 #11
0
def validate_email_from(form, field):
    if email_safe(field.data) != field.data.lower():
        raise ValidationError(_l("This entry must contain valid characters for an email address."))
    if len(field.data) > 64:
        raise ValidationError(_l("This cannot exceed 64 characters in length"))
    # this filler is used because service id is not available when validating a new service to be created
    service_id = getattr(form, "service_id", current_app.config["NOTIFY_BAD_FILLER_UUID"])
    unique_name = service_api_client.is_service_email_from_unique(service_id, field.data)
    if not unique_name:
        raise ValidationError(_l("This email address is already in use"))
예제 #12
0
def add_service():
    default_organisation_type = current_user.default_organisation_type
    if default_organisation_type == 'nhs':
        form = CreateNhsServiceForm()
        default_organisation_type = None
    else:
        form = CreateServiceForm(organisation_type=default_organisation_type)
    heading = 'About your service'

    if form.validate_on_submit():
        email_from = email_safe(form.name.data)
        service_name = form.name.data

        service_id, error = _create_service(
            service_name,
            default_organisation_type or form.organisation_type.data,
            email_from,
            form,
        )
        if error:
            return render_template('views/add-service.html',
                                   form=form,
                                   heading=heading)
        if len(
                service_api_client.get_active_services({
                    'user_id':
                    session['user_id']
                }).get('data', [])) > 1:
            return redirect(
                url_for('main.service_dashboard', service_id=service_id))

        example_sms_template = _create_example_template(service_id)

        return redirect(
            url_for('main.begin_tour',
                    service_id=service_id,
                    template_id=example_sms_template['data']['id']))
    else:
        if default_organisation_type == 'local':
            return render_template(
                'views/add-service-local.html',
                form=form,
                heading=heading,
                default_organisation_type=default_organisation_type,
            )

        return render_template(
            'views/add-service.html',
            form=form,
            heading=heading,
            default_organisation_type=default_organisation_type,
        )
예제 #13
0
def add_service():
    invited_user = session.get('invited_user')
    if invited_user:
        invitation = InvitedUser(**invited_user)
        # if invited user add to service and redirect to dashboard
        user = user_api_client.get_user(session['user_id'])
        service_id = invited_user['service']
        user_api_client.add_user_to_service(service_id, user.id,
                                            invitation.permissions)
        invite_api_client.accept_invite(service_id, invitation.id)
        return redirect(
            url_for('main.service_dashboard', service_id=service_id))

    form = AddServiceForm(service_api_client.find_all_service_email_from)
    heading = 'Which service do you want to set up notifications for?'
    if form.validate_on_submit():
        email_from = email_safe(form.name.data)
        service_id = service_api_client.create_service(
            service_name=form.name.data,
            active=False,
            message_limit=current_app.config['DEFAULT_SERVICE_LIMIT'],
            restricted=True,
            user_id=session['user_id'],
            email_from=email_from)
        session['service_id'] = service_id

        if (len(
                service_api_client.get_services({
                    'user_id': session['user_id']
                }).get('data', [])) > 1):
            return redirect(
                url_for('main.service_dashboard', service_id=service_id))

        example_sms_template = service_api_client.create_service_template(
            'Example text message template', 'sms',
            'Hey ((name)), I’m trying out Notify. Today is ((day of week)) and my favourite colour is ((colour)).',
            service_id)

        return redirect(
            url_for('main.send_test',
                    service_id=service_id,
                    template_id=example_sms_template['data']['id'],
                    help=1))
    else:
        return render_template('views/add-service.html',
                               form=form,
                               heading=heading)
예제 #14
0
def add_service():
    invited_user = session.get('invited_user')
    if invited_user:
        invitation = InvitedUser(**invited_user)
        # if invited user add to service and redirect to dashboard
        user = user_api_client.get_user(session['user_id'])
        service_id = invited_user['service']
        user_api_client.add_user_to_service(service_id, user.id, invitation.permissions)
        invite_api_client.accept_invite(service_id, invitation.id)
        return redirect(url_for('main.service_dashboard', service_id=service_id))

    form = AddServiceForm(service_api_client.find_all_service_email_from)
    heading = 'Which service do you want to set up notifications for?'
    if form.validate_on_submit():
        email_from = email_safe(form.name.data)
        service_id = service_api_client.create_service(service_name=form.name.data,
                                                       active=False,
                                                       message_limit=current_app.config['DEFAULT_SERVICE_LIMIT'],
                                                       restricted=True,
                                                       user_id=session['user_id'],
                                                       email_from=email_from)
        session['service_id'] = service_id

        if (len(service_api_client.get_services({'user_id': session['user_id']}).get('data', [])) > 1):
            return redirect(url_for('main.service_dashboard', service_id=service_id))

        example_sms_template = service_api_client.create_service_template(
            'Example text message template',
            'sms',
            'Hey ((name)), I’m trying out Notify. Today is ((day of week)) and my favourite colour is ((colour)).',
            service_id
        )

        return redirect(url_for(
            'main.send_test',
            service_id=service_id,
            template_id=example_sms_template['data']['id'],
            help=1
        ))
    else:
        return render_template(
            'views/add-service.html',
            form=form,
            heading=heading
        )
예제 #15
0
def add_service():
    invited_user = session.get('invited_user')
    if invited_user:
        service_id = _add_invited_user_to_service(invited_user)
        return redirect(
            url_for('main.service_dashboard', service_id=service_id))

    if not is_gov_user(current_user.email_address):
        abort(403)

    form = CreateServiceForm()
    heading = 'About your service'

    if form.validate_on_submit():
        email_from = email_safe(form.name.data)
        service_name = form.name.data

        service_id, error = _create_service(service_name,
                                            form.organisation_type.data,
                                            email_from, form)
        if error:
            return render_template('views/add-service.html',
                                   form=form,
                                   heading=heading)
        if len(
                service_api_client.get_active_services({
                    'user_id':
                    session['user_id']
                }).get('data', [])) > 1:
            return redirect(
                url_for('main.service_dashboard', service_id=service_id))

        example_sms_template = _create_example_template(service_id)

        return redirect(
            url_for(
                'main.start_tour',
                service_id=service_id,
                template_id=example_sms_template['data']['id'],
            ))
    else:
        return render_template('views/add-service.html',
                               form=form,
                               heading=heading)
예제 #16
0
def add_service():
    default_organisation_type = "central"
    form = CreateServiceForm(organisation_type=default_organisation_type)
    heading = _('Name your service in both official languages')

    if form.validate_on_submit():
        email_from = email_safe(form.name.data)
        service_name = form.name.data

        service_id, error = _create_service(
            service_name,
            default_organisation_type,
            email_from,
            form,
        )
        if error:
            return render_template('views/add-service.html',
                                   form=form,
                                   heading=heading)
        if len(
                service_api_client.get_active_services({
                    'user_id':
                    session['user_id']
                }).get('data', [])) > 1:
            return redirect(
                url_for('main.service_dashboard', service_id=service_id))

        example_email_template = _create_example_template(service_id)

        return redirect(
            url_for('main.start_tour',
                    service_id=service_id,
                    template_id=example_email_template['data']['id']))
    else:
        return render_template(
            'views/add-service.html',
            form=form,
            heading=heading,
            default_organisation_type=default_organisation_type,
        )
예제 #17
0
def add_service():
    invited_user = session.get('invited_user')
    if invited_user:
        service_id = _add_invited_user_to_service(invited_user)
        return redirect(url_for('main.service_dashboard', service_id=service_id))

    if not is_gov_user(current_user.email_address):
        abort(403)

    form = AddServiceForm(service_api_client.find_all_service_email_from)
    heading = 'Which service do you want to set up notifications for?'

    if form.validate_on_submit():
        email_from = email_safe(form.name.data)
        service_name = form.name.data
        service_id = _create_service(service_name, email_from)

        if (len(service_api_client.get_active_services({'user_id': session['user_id']}).get('data', [])) > 1):
            return redirect(url_for('main.service_dashboard', service_id=service_id))

        example_sms_template = service_api_client.create_service_template(
            'Example text message template',
            'sms',
            'Hey ((name)), I’m trying out Notify. Today is ((day of week)) and my favourite colour is ((colour)).',
            service_id
        )

        return redirect(url_for(
            'main.send_test',
            service_id=service_id,
            template_id=example_sms_template['data']['id'],
            help=1
        ))
    else:
        return render_template(
            'views/add-service.html',
            form=form,
            heading=heading
        )
예제 #18
0
def create_api_key(service_id):
    key_names = [
        key['name'] for key in api_key_api_client.get_api_keys(service_id=service_id)['apiKeys']
    ]
    form = CreateKeyForm(key_names)
    form.key_type.choices = [
        (KEY_TYPE_NORMAL, 'Send messages to anyone'),
        (KEY_TYPE_TEAM, 'Send messages to anyone on my whitelist'),
        (KEY_TYPE_TEST, 'Pretend to send messages to anyone'),
    ]
    if current_service['restricted']:
        disabled_options = [KEY_TYPE_NORMAL]
        option_hints = {KEY_TYPE_NORMAL: Markup(
            'This option is not available because your service is in '
            '<a href="{}">trial mode</a>'.format(url_for(".trial_mode"))
        )}
    else:
        disabled_options, option_hints = [], {}
    if form.validate_on_submit():
        if form.key_type.data in disabled_options:
            abort(400)
        secret = api_key_api_client.create_api_key(
            service_id=service_id,
            key_name=form.key_name.data,
            key_type=form.key_type.data
        )
        return render_template(
            'views/api/keys/show.html',
            secret=secret,
            service_id=service_id,
            key_name=email_safe(form.key_name.data, whitespace='_')
        )
    return render_template(
        'views/api/keys/create.html',
        form=form,
        disabled_options=disabled_options,
        option_hints=option_hints
    )
def test_should_redirect_after_service_name_confirmation(
        app_, active_user_with_permissions, service_one, mocker,
        mock_update_service, mock_verify_password, mock_get_organisation):
    with app_.test_request_context():
        with app_.test_client() as client:
            client.login(active_user_with_permissions, mocker, service_one)
            service_id = service_one['id']
            service_new_name = 'New Name'
            with client.session_transaction() as session:
                session['service_name_change'] = service_new_name
            response = client.post(
                url_for('main.service_name_change_confirm',
                        service_id=service_id))

        assert response.status_code == 302
        settings_url = url_for('main.service_settings',
                               service_id=service_id,
                               _external=True)
        assert settings_url == response.location
        mock_update_service.assert_called_once_with(
            service_id,
            name=service_new_name,
            email_from=email_safe(service_new_name))
        assert mock_verify_password.called
예제 #20
0
def test_email_safe_return_dot_separated_email_domain():
    test_name = 'SOME service  with+stuff+ b123'
    expected = 'some.service.withstuff.b123'
    actual = email_safe(test_name)
    assert actual == expected
예제 #21
0
def test_email_safe_return_dot_separated_email_domain(service_name,
                                                      safe_email):
    assert email_safe(service_name) == safe_email
예제 #22
0
 def validate_name(self, a):
     from app.utils import email_safe
     # make sure the email_from will be unique to all services
     if email_safe(a.data) in self._names_func():
         raise ValidationError('This service name is already in use')
예제 #23
0
def test_email_safe_return_dot_separated_email_domain(service_name, safe_email):
    assert email_safe(service_name) == safe_email
예제 #24
0
 def validate_name(self, a):
     from app.utils import email_safe
     # make sure the email_from will be unique to all services
     if email_safe(a.data) in self._names_func():
         raise ValidationError('This service name is already in use')
예제 #25
0
def test_email_safe_return_dot_separated_email_domain():
    test_name = 'SOME service  with+stuff+ b123'
    expected = 'some.service.withstuff.b123'
    actual = email_safe(test_name)
    assert actual == expected