Portal.Views

Note

This does not include API endpoints documented via swagger, as the swagger syntax is incompatable with restructuredText

Auth related view functions

portal.views.auth.deauthorized()

Callback URL configured on facebook when user deauthorizes

We receive POST data when a user deauthorizes the session between TrueNTH and Facebook. The POST includes a signed_request, decoded as seen below.

Configuration set on Facebook Developer pages:
app->settings->advanced->Deauthorize Callback URL
portal.views.auth.next_after_login()

Redirection to appropriate target depending on data and auth status

Multiple authorization paths in, some needing up front information before returning, this attempts to handle such state decisions. In other words, this function represents the state machine to control initial flow.

When client applications (interventions) request OAuth tokens, we sometimes need to postpone the action of authorizing the client while the user logs in to TrueNTH.

After completing authentication with TrueNTH, additional data may need to be obtained, such as a TOU agreement. In such a case, the user will be directed to initial_queries, then back here for redirection to the appropriate ‘next’.

Implemented as a view method for integration with flask-user config.

portal.views.auth.login(blueprint, token)

successful provider login callback

After successful authorization at the provider, control returns here. The blueprint and the oauth bearer token are used to log the user into the portal

:return returns False to disable saving oauth token

portal.views.auth.logout(prevent_redirect=False, reason=None)

logout view function

Logs user out by requesting the previously granted permission to use authenticated resources be deleted from the OAuth server, and clearing the browser session.

Parameters:
  • prevent_redirect – set only if calling this function during another process where redirection after logout is not desired
  • reason – set only if calling from another process where a driving reason should be noted in the audit

Optional query string parameter timed_out should be set to clarify the logout request is the result of a stale session

Cross Domain Decorators

portal.views.crossdomain.crossdomain(origin=None, methods=None, headers=('Authorization', 'X-Requested-With', 'X-CSRFToken', 'Content-Type'), max_age=21600, automatic_options=True)

Decorator to add specified crossdomain headers to response

Parameters:
  • origin – ‘*’ to allow all origins, otherwise a string with a single origin or a list of origins that might access the resource. If no origin is provided, use request.headers[‘Origin’], but ONLY if it validates. If no origin is provided and the request doesn’t include an Origin header, no CORS headers will be added.
  • methods – Optionally a list of methods that are allowed for this view. If not provided it will allow all methods that are implemented.
  • headers – Optionally a list of headers that are allowed for this request.
  • max_age – The number of seconds as integer or timedelta object for which the preflighted request is valid.
  • automatic_options – If enabled the decorator will use the default Flask OPTIONS response and attach the headers there, otherwise the view function will be called to generate an appropriate response.
:raises werkzeug.exceptions.Unauthorized:
if no origin is provided and the one in request.headers[‘Origin’] doesn’t validate as one we know.

Intervention API view functions

portal.views.intervention.intervention_rule_list(*args, **kwargs)

Return the list of intervention rules for named intervention

NB - not documenting in swagger at this time, intended for internal use only. See http://truenth-shared-services.readthedocs.io/en/latest/interventions.html#access

portal.views.intervention.intervention_rule_set(*args, **kwargs)

POST an access rule to the named intervention

Submit a JSON doc with the access strategy details to include for the named intervention.

Only available as a service account API - the named intervention must be associated with the service account sponsor.

NB - interventions have a global ‘public_access’ setting. Only when unset are access rules consulted.

NB - not documenting in swagger at this time, intended for internal use only. See http://truenth-shared-services.readthedocs.io/en/latest/interventions.html#access

Patient view functions (i.e. not part of the API or auth)

portal.views.patients.patient_profile(*args, **kwargs)

individual patient view function, intended for staff

portal.views.patients.patients_root(*args, **kwargs)

patients view function, intended for staff

Present the logged in staff the list of patients matching the staff’s organizations (and any descendant organizations)

Portal view functions (i.e. not part of the API or auth)

class portal.views.portal.ChallengeIdForm(formdata=<object object>, **kwargs)
class portal.views.portal.SettingsForm(formdata=<object object>, **kwargs)
class portal.views.portal.ShortcutAliasForm(formdata=<object object>, **kwargs)
static validate_shortcut_alias(field)

Custom validation to confirm an alias match

portal.views.portal.access_via_token(token, next_step=None)

Limited access users enter here with special token as auth

Tokens contain encrypted data including the user_id and timestamp from when it was generated.

If the token is found to be valid, and the user_id isn’t associated with a privilidged account, the behavior depends on the roles assigned to the token’s user_id: * WRITE_ONLY users will be directly logged into the weak auth account * others will be given a chance to prove their identity

Parameters:next_step – if the user is to be redirected following validation and intial queries, include a value. These come from a controlled vocabulary - see NextStep
portal.views.portal.admin(*args, **kwargs)

user admin view function

portal.views.portal.celery_test(x=16, y=16)

Simple view to test asynchronous tasks via celery

portal.views.portal.challenge_identity(user_id=None, next_url=None, merging_accounts=False, access_on_verify=False, request_path=None)

Challenge the user to verify themselves

Can’t expose the parameters for security reasons - use the session, namespace each variable i.e. session[‘challenge.user_id’] unless calling as a function.

Parameters:
  • user_id – the user_id to verify - invited user or the like
  • next_url – destination url on successful challenge completion
  • merging_accounts – boolean value, set true IFF on success, the user account will be merged into a new account, say from a weak authenicated WRITE_ONLY invite account
  • access_on_verify – boolean value, set true IFF on success, the user should be logged in once validated, i.e. w/o a password
  • request_path – the requested url prior to redirection to here necessary in no cookie situations, to redirect user back
portal.views.portal.communicate(*args, **kwargs)

Direct call to trigger communications to given user.

Typically handled by scheduled jobs, this API enables testing of communications without the wait.

Include a force=True query string parameter to first invalidate the cache and look for fresh messages before triggering the send.

Include a purge=True query string parameter to throw out existing communications for the user first, thus forcing a resend (implies a force)

Include a trace=True query string parameter to get details found during processing - like a debug trace.

portal.views.portal.communications_dashboard(*args, **kwargs)

Communications Dashboard

Displays a list of communication requests from the system; includes a preview mode for specific requests.

portal.views.portal.contact_sent(message_id)

show invite sent

portal.views.portal.get_all_tag_data(*allTags)

query LR based on all required tags

this is an AND condition; all required tags must be present

Parameters:allTags – variable number of tags to be queried, e.g., ‘tag1’, ‘tag2’
portal.views.portal.get_any_tag_data(*anyTags)

query LR based on any tags

this is an OR condition; will match any tag specified

Parameters:anyTag – a variable number of tags to be queried, e.g., ‘tag1’, ‘tag2’
portal.views.portal.initial_queries()

Initial consent terms, initial queries view function

portal.views.portal.invite(*args, **kwargs)

invite other users via form data

see also /api/user/{user_id}/invite

portal.views.portal.invite_sent(*args, **kwargs)

show invite sent

portal.views.portal.patient_invite_email(*args, **kwargs)

Patient Invite Email Content

portal.views.portal.patient_reminder_email(*args, **kwargs)

Patient Reminder Email Content

portal.views.portal.preview_communication(*args, **kwargs)

Communication message preview

portal.views.portal.profile(*args, **kwargs)

profile view function

portal.views.portal.report_error(*args, **kwargs)

Useful from front end, client-side to raise attention to problems

On occasion, an exception will be generated in the front end code worthy of gaining attention on the server side. By making a GET request here, a server side error will be generated (encouraging the system to handle it as configured, such as by producing error email).

OAuth protected to prevent abuse.

Any of the following query string arguments (and their values) will be included in the exception text, to better capture the context. None are required.

Subject_id:User on which action is being attempted
Message:Details of the error event
Page_url:The page requested resulting in the error

actor_id need not be sent, and will always be included - the OAuth protection guarentees and defines a valid current user.

portal.views.portal.report_slow_queries(response)

Log slow database queries

This will only function if BOTH values are set in the config:
DATABASE_QUERY_TIMEOUT = 0.5 # threshold in seconds SQLALCHEMY_RECORD_QUERIES = True
portal.views.portal.reporting_dashboard(*args, **kwargs)

Executive Reporting Dashboard

Only accessible to Admins, or those with the Analyst role (no PHI access).

Usage: graphs showing user registrations and logins per day;
filterable by date and/or by intervention

User Stats: counts of users by role, intervention, etc.

Institution Stats: counts of users per org

Analytics: Usage stats from piwik (time on site, geographic usage,
referral sources for new visitors, etc)
portal.views.portal.require_cookies()

give front end opportunity to verify cookies

Renders HTML including cookie check, then redirects back to target NB - query string ‘cookies_tested=True’ added to target for client to confirm this process happened.

portal.views.portal.research_dashboard(*args, **kwargs)

Research Dashboard

Only accessible to those with the Researcher role.

portal.views.portal.settings(*args, **kwargs)

settings panel for admins

portal.views.portal.spec(*args, **kwargs)

generate swagger friendly docs from code and comments

View function to generate swagger formatted JSON for API documentation. Pulls in a few high level values from the package data (see setup.py) and via flask-swagger, makes use of any yaml comment syntax found in application docstrings.

Point Swagger-UI to this view for rendering

portal.views.portal.specific_clinic_entry()

Entry point with form to insert a coded clinic shortcut

Invited users may start here to obtain a specific clinic assignment, by entering the code or shortcut alias they were given.

Store the clinic in the session for association with the user once registered and redirect to the standard landing page.

NB if already logged in - this will bounce user to home

portal.views.portal.specific_clinic_landing(clinic_alias)

Invited users start here to obtain a specific clinic assignment

Store the clinic in the session for association with the user once registered and redirect to the standard landing page.

Simple view to render default consent with named organization

We generally store the unique URL pointing to the content of the agreement to which the user consents. Special case for organizations without a custom consent agreement on file.

Parameters:org_name – the org_name to include in the agreement text