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)
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, )
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, )
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, )
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
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)
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"))
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, )
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)
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 )
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)
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, )
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 )
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
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
def test_email_safe_return_dot_separated_email_domain(service_name, safe_email): assert email_safe(service_name) == safe_email
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')