utils.py

About this file

This file defines authentication utilities for NYC OpenRecords.
It also defines a functions for following purposes:

Given a GUID return the associated User object,
Update OpenRecords-specific user attributes,
Determine if a URL is safe to redirect the user to,
Find a user by email address stored in the database,
Create or Update an OpenRecords User based on the data received from the SAML Assertion,
Update a users data with the updated values,
Create and store event object for given response,
Initialize a SAML SP from a dictionary representation of a Flask request,
Convert a Flask request object to a dictionary for use with OneLogin SAML,
Calls the login function in the OneLogin python3-saml library to generate an Assertion Request to the IdP,
Process a SAML LogoutResponse from the IdP,
Generate a SAML LogoutRequest for the user,
Process a SAML Assertion for the user,
Validate email,
Validate whether the user is a NYC Employee,
Log an error message if the specified response's status code is not 200,
Perform a request on an NYC.ID Web Services endpoint,
Generate a string that can be signed to produce an authentication signature,
Generate an NYC.ID Web Services authentication signature using HMAC-SHA1,
Authenticate the provided user with an LDAP Server,
Connect to an LDAP server.

Code Check Report


app/auth/utils.py:133:42: E712 comparison to False should be 'if cond is False:' or 'if not cond:'
app/auth/utils.py:139:35: E712 comparison to True should be 'if cond is True:' or 'if cond:'
app/auth/utils.py:314:121: E501 line too long (127 > 120 characters)
                        

Documentation drawn from source code


.. module:: auth.views.

:synopsis: Authentication utilities for NYC OpenRecords


user_loader(guid: str) -> Users:
Given a GUID return the associated User object.

Args:
guid (str): User ID (GUID) of the user to retrieve from the database.

Returns:
Users: User object from the database or None.

update_openrecords_user(form):

Update OpenRecords-specific user attributes.

Args:
form (app.auth.forms.ManageAgencyUserAccountForm OR app.auth.forms.ManageUserAccountForm): validated form

is_safe_url(target):
Determine if a URL is safe to redirect the user to.

Source: http://flask.pocoo.org/snippets/62/

Args:
target (str): URL to redirect the user to.

Returns:
bool: True if the URL is safe.


find_user_by_email(email):
Find a user by email address stored in the database.

If LDAP login is being used, non-agency users and users without an LDAP auth type are ignored.
If OAuth or SAML login is being used, anonymous users are ignored.

Args:
email (str): Email address to search by.

Returns:
Users: User object or None if no user found.


_process_user_data(guid,

Create or Update an OpenRecords User based on the data received from the SAML Assertion.

If no first_name is provided, the mailbox portion of the email will be used
e.g. jdoe@records.nyc.gov -> first_name: jdoe

If a user cannot be found using the specified guid and user_type, a second attempt is made with the specified email.

NOTE: A user's agency is not determined here. After login, a user's agency supervisor must email us requesting that
user be added to the agency.
TODO (@joelbcastillo): Add endpoint to add user by email to the Agency on the Agency Administration Page

Args:
guid (str): The users unique identifier
email (str): The users email address
first_name (str): The users' first name. If None, then the mailbox part of the email address will be used
middle_initial (str): The users' middle initial. Can be None
last_name (str): The users' last name. Required.
email_validated (bool): Determines whether the users' email has been validated.
is_nyc_employee (bool): Determines
has_nyc_account,
active,
terms_of_use_accepted,
is_anonymous_requester

Returns:
Users: The user that was pulled from the database (and updated) or the new user)

_update_user_data(

Update a users data with the updated values.

Args:
user (Users): User to be updated.
guid (str): Updated GUID (Required)
email (str): Updated email address
first_name (str): Updated first name
middle_initial (str): Updated middle initial
last_name (str): Updated last name
email_validated (bool): Updated email validation status
is_nyc_employee (bool): Updated NYC Employee status
has_nyc_account (bool): Updated NYC Account Status
active (bool): Updated active status (is the user account active in the authentication provider)
terms_of_use_accepted (bool): Terms of Use Accepted Status
is_anonymous_requester (bool): Updated Anonymous Requester status


create_auth_event(auth_event_type: str, user_guid: str, new_value: dict):

Create and store event object for given response.

Args:
auth_event_type (str): one of app.constants.event_type
user_guid (Users): Users object performing the authentication event
new_value (dict): Value to be stored in events table


init_saml_auth(onelogin_request):
Initialize a SAML SP from a dictionary representation of a Flask request.

Args:
onelogin_request (dict): Dictionary representation of a Flask Request object.

Returns:
OneLogin_Saml2_Auth: SAML SP Instance.


prepare_onelogin_request(flask_request):
Convert a Flask request object to a dictionary for use with OneLogin SAML.

Args:
flask_request (Flask.Request): Flask Request object.

Returns:
dict: Dictionary of Flask Request fields for OneLogin


saml_sso(saml_sp):
Handle Single Sign-On for SAML.

Calls the login function in the OneLogin python3-saml library to generate an Assertion Request to the IdP.

Args:
saml_sp (OneLogin_Saml2_Auth): Saml SP Instance

Returns:
Response Object: Redirect the user to the IdP for SSO.


saml_sls(saml_sp, user_guid):
Process a SAML LogoutResponse from the IdP

Args:
saml_sp (OneLogin_Saml2_Auth): SAML SP Instance
user_guid (str): Unique identifier for user being logged out.

Returns:
Response Object: Redirect the user to the Home Page.


saml_slo(saml_sp):
Generate a SAML LogoutRequest for the user.

Args:
saml_sp (OneLogin_Saml2_Auth): SAML SP Instance

Returns:
Response Object: Redirect the user to the IdP for SLO.

saml_acs(saml_sp, onelogin_request):
Process a SAML Assertion for the user

Args:
saml_sp (OneLogin_Saml2_Auth): SAML SP Instance

Returns:
Response Object: Redirect the user to the appropriate page for the next step.
If the user needs to validate their email, they are redirected to the IdP
Otherwise, the user is redirected to a valid RelayState.
If RelayState is invalid, the user is redirected to the home page.


_validate_email(email_validation_flag, guid, email_address):

If the user did not log in via NYC.ID
(i.e. user_type is not 'EDIRSSO'),
no email validation is necessary.

A email is considered to have been validated if the
email validation flag is
- not provided
- 'TRUE
- 'true
- 'Unavailable
- True

If the email validation flag is not one of the above (i.e. FALSE),
the Email Validation Web Service is invoked.

If the returned validation status equals false,
return url to the 'Email Confirmation Required' page
where the user can request a validation email.

:return: redirect url or None

get_nycid_user_data(guid):

Validate whether the user is a NYC Employee.
If the returned validation status equals false,
return url to the 'Email Confirmation Required' page
where the user can request a validation email.

:return: redirect url or None

_check_web_services_response(response, msg=''):

Log an error message if the specified response's
status code is not 200.

_web_services_request(endpoint, params, method='GET'):

Perform a request on an NYC.ID Web Services endpoint.
userName' and 'signature' are added to the specified params.

:param endpoint: web services endpoint (e.g. "/account/validateEmail.htm")
:param params: request parameters excluding 'userName' and 'signature
:param method: HTTP method
:return: request response

_generate_string_to_sign(method, path, params):

Generate a string that can be signed to produce an
authentication signature.

:param method: HTTP method
:param path: path part of HTTP request URI
:param params: querystring parameters
:return: string to sign

_generate_signature(password, string):

Generate an NYC.ID Web Services authentication signature using HMAC-SHA1

https://nyc4d.nycnet/nycid/web-services.shtml#signature

:param password: NYC.ID Service Account password
:param string: string to sign
:return: the authentication signature or None on failure

ldap_authentication(email, password):

Authenticate the provided user with an LDAP Server.
:param email: Users username
:param password: Users password
:return: Boolean

_ldap_server_connect():

Connect to an LDAP server
:return: LDAP Context

Source code