smsauthenticator Package

smsauthenticator Package

collective.smsauthenticator.initialize(context)[source]

Initializer called when used as a Zope 2 product.

adapter Module

class collective.smsauthenticator.adapter.CameFromAdapter(request)[source]

Bases: object

Came from handling.

Plone came_from field had to be taken out of the login form, so that users always get the token validation screen, prior to being redirected to page they came from. The came_from is instead extracted from referer and handled in such a way, that Plone functionality stays intact.

In cases your existing package smuggles with came_from (for example, you want users first to accept terms and conditions prior redirection), you would likely need to define a new adapter and make appropriate changes to the getCameFrom method.

Example :
>>> from zope.interface import implements
>>> from plone import api
>>> from collective.smsauthenticator.helpers import extract_next_url_from_referer
>>> from collective.smsauthenticator.adapter import ICameFrom
>>> 
>>> class CameFromAdapter(object):
>>>     implements(ICameFrom)
>>> 
>>>     def __init__(self, request):
>>>         self.request = request
>>> 
>>>     def getCameFrom(self):
>>>         real_referrer = extract_next_url_from_referer(self.request)
>>>         portal = api.portal.get()
>>>         if not real_referrer:
>>>             real_referrer = portal.absolute_url()
>>>         referrer = "{0}/tac-form/?came_from={1}".format(portal.portal_url(), real_referrer)
>>>         return referrer
getCameFrom()[source]

Extracts the came_from value from the referrer (uses global request).

Return string:
class collective.smsauthenticator.adapter.EnhancedUserDataPanelAdapter(context)[source]

Bases: plone.app.users.browser.personalpreferences.UserDataPanelAdapter

Adapter for collective.smsauthenticator.userdataschema.IEnhancedUserDataSchema.

enable_two_step_verification
get_enable_two_step_verification()[source]
get_ips()[source]
get_mobile_number()[source]
get_mobile_number_authentication_code()[source]
get_mobile_number_reset_code()[source]
get_mobile_number_reset_token()[source]
get_two_step_verification_secret()[source]
ips
mobile_number
mobile_number_authentication_code
mobile_number_reset_code
mobile_number_reset_token
set_enable_two_step_verification(value)[source]
set_ips(value)[source]
set_mobile_number(value)[source]
set_mobile_number_authentication_code(value)[source]
set_mobile_number_reset_code(value)[source]
set_mobile_number_reset_token(value)[source]
set_two_step_verification_secret(value)[source]
two_step_verification_secret

helpers Module

The helper module contains various methods for api security and for downloading files

collective.smsauthenticator.helpers.disable_two_step_verification_for_users(users=[])[source]

Disable two-step verification for the list of users given.

collective.smsauthenticator.helpers.enable_two_step_verification_for_users(users=[])[source]

Enable two-step verification for the list of users given.

collective.smsauthenticator.helpers.extract_ip_address_from_request(request=None)[source]

Extracts client’s IP address from request. This is not the safest solution, since client may change headers.

Parameters:request (ZPublisher.HTTPRequest) –
Return string:
collective.smsauthenticator.helpers.extract_next_url_from_referer(request, quote_url=False)[source]

Since we override the default Plone functionality (take out the came_from from the login form for a very strong reason), we want to make sure that for users, the “came from” functionality stays intact. That why, we check the referer for the came_from attributes and if present, redirect to that after successful two-step verification token validation. :param request ZPublisher.HTTPRequest: :return string: Extracted came_from URL.

collective.smsauthenticator.helpers.extract_request_data(request)[source]

Plone seems to strip/escape some special chars (such as ‘+’) from values and those chars are quite important for us. This method extracts the vars from request QUERY_STRING given and returns them unescaped.

Fixme :As stated above, for some reason Plone escapes from special chars from the values. If

you know what the reason is and if it has some effects on security, please make the changes necessary.

Parameters:ZPublisher.HTTPRequest (request) –
Return dict:
collective.smsauthenticator.helpers.extract_request_data_from_query_string(request_qs)[source]

Plone seems to strip/escape some special chars (such as ‘+’) from values and those chars are quite important for us. This method extracts the vars from request QUERY_STRING given and returns them unescaped.

Fixme :As stated above, for some reason Plone escapes from special chars from the values. If

you know what the reason is and if it has some effects on security, please make the changes necessary.

Parameters:request_qs (string) –
Return dict:
collective.smsauthenticator.helpers.generate_code(user, length=6)[source]

Gets a random token to reset the mobile number (time based) + random char.

Parameters:
  • user (Products.PlonePAS.tools.memberdata) –
  • length (int) –
Return string:
collective.smsauthenticator.helpers.generate_secret(user)[source]

Generates secret for the user.

Parameters:user (Products.PlonePAS.tools.memberdata) –
collective.smsauthenticator.helpers.get_app_settings()[source]

Gets the SMS Authenticator settings.

collective.smsauthenticator.helpers.get_base_url(request=None)[source]

Gets domain name (with HTTP).

Parameters:request (ZPublisher.HTTPRequest) –
Return string:
collective.smsauthenticator.helpers.get_browser_hash(request=None)[source]

Gets browser hash. Adds an extra security layer, since browser version is unlikely to be changed.

Parameters:request (ZPublisher.HTTPRequest) –
Return string:
collective.smsauthenticator.helpers.get_domain_name(request=None)[source]

Gets domain name (without HTTP).

Parameters:request (ZPublisher.HTTPRequest) –
Return string:
collective.smsauthenticator.helpers.get_ip_addresses_whitelist(request=None)[source]

Gets IP addresses white list.

Parameters:request (ZPublisher.HTTPRequest) –
Return list:
collective.smsauthenticator.helpers.get_or_create_secret(user, overwrite=False)[source]

Gets or creates token secret for the user given. Checks first if user given has a secret generated. If not, generate it for him and save it in his profile (two_step_verification_secret).

Parameters:user (Products.PlonePAS.tools.memberdata) – If provided, used. Otherwise plone.api.user.get_current is used to obtain the user.
Return string:
collective.smsauthenticator.helpers.get_secret(user=None, hashed=False)[source]

Gets users’ secret code. If hashed is set to True, returned hashed.

Parameters:
  • user (Products.PlonePAS.tools.memberdata) –
  • hashed (bool) – If set to True, hashed version is returned.
Return string:
collective.smsauthenticator.helpers.get_ska_secret_key(request=None, user=None, use_browser_hash=True)[source]

Gets the secret_key to be used in ska package.

  • Value of the two_step_verification_secret (from users’ profile).
  • Browser info (hash of)
  • The SECRET set for the ska (use plone.app.registry).
Parameters:
  • request (ZPublisher.HTTPRequest) –
  • user (Products.PlonePAS.tools.memberdata) –
  • use_browser_hash (bool) – If set to True, browser hash is used. Otherwise - not. Defaults to True.
Return string:
collective.smsauthenticator.helpers.get_ska_token_lifetime(settings=None)[source]

Gets the ska token lifetime (in seconds) from settings.

Return int:
collective.smsauthenticator.helpers.get_updated_ips_for_member_properties_update(user, request=None)[source]

Save IP, from which user is logged in, into the system.

Parameters:
  • user (Products.PlonePAS.tools.memberdata) –
  • request (ZPublisher.HTTPRequest) –
Return bool:

True on success and False on failure.

collective.smsauthenticator.helpers.get_user(username)[source]

Get user by username given and return member object.

collective.smsauthenticator.helpers.get_username(user=None)[source]

Gets the username of the user.

Parameters:user – If given, used to extract the user. Otherwise, plone.api.user.get_current is used.
Return string:
collective.smsauthenticator.helpers.get_white_listed_ip_addresses()[source]

Gets list of white-listed IP addresses.

Return list:
collective.smsauthenticator.helpers.has_enabled_two_step_verification(user)[source]

Checks if user has enabled the two-step verification.

Parameters:user (Products.PlonePAS.tools.memberdata) –
Return bool:
collective.smsauthenticator.helpers.is_two_step_verification_globally_enabled()[source]

Checks if the two-step verification is globally enabled.

Return bool:
collective.smsauthenticator.helpers.is_whitelisted_client(request=None)[source]

Checks if client’s IP address is whitelisted.

Parameters:request (ZPublisher.HTTPRequest) –
Return bool:
collective.smsauthenticator.helpers.save_ip(user, request=None)[source]

Save IP, from which user is logged in, into the system.

Parameters:
  • user (Products.PlonePAS.tools.memberdata) –
  • request (ZPublisher.HTTPRequest) –
Return bool:

True on success and False on failure.

collective.smsauthenticator.helpers.send_login_code_sms(mobile_number, code)[source]

Sends an SMS to the monile number given for mobile number reset confirmation.

Parameters:
  • mobile_number (string) –
  • code (string) –
Return bool:

True on success and False on failure.

collective.smsauthenticator.helpers.send_mobile_number_reset_confirmation_code_sms(mobile_number, code)[source]

Sends an SMS to the monile number given for mobile number reset confirmation.

Parameters:
  • mobile_number (string) –
  • code (string) –
Return bool:

True on success and False on failure.

collective.smsauthenticator.helpers.send_mobile_number_setup_confirmation_code_sms(mobile_number, code)[source]

Sends an SMS to the monile number given for mobile number setup confirmation.

Parameters:
  • mobile_number (string) –
  • code (string) –
Return bool:

True on success and False on failure.

collective.smsauthenticator.helpers.send_sms(mobile_number, message)[source]

Sends an SMS to the monile number given for mobile number reset confirmation.

Parameters:
  • mobile_number (string) –
  • message (string) – Message.
Return bool:

True on success and False on failure.

collective.smsauthenticator.helpers.sign_user_data(request=None, user=None, url='@@sms-authenticator-token')[source]

Signs the user data with ska package. The secret key is secret_key to be used with ska is a combination of:

  • Value of the two_step_verification_secret (from users’ profile).
  • Browser info (hash of)
  • The SECRET set for the ska (use plone.app.registry).
Parameters:
  • request (ZPublisher.HTTPRequest) –
  • user (Products.PlonePAS.tools.memberdata) –
  • url (string) –
Return string:
collective.smsauthenticator.helpers.validate_code(code, prop, user=None)[source]

Validates the given code by matching it with one stored in users’ profile.

Parameters:
  • code (string) –
  • prop (string) –
  • user (Products.PlonePAS.tools.memberdata) –
Return bool:
collective.smsauthenticator.helpers.validate_mobile_number_authentication_code(code, user=None)[source]
collective.smsauthenticator.helpers.validate_mobile_number_reset_code(code, user=None)[source]
collective.smsauthenticator.helpers.validate_user_data(request, user, use_browser_hash=True)[source]

Validates the user data.

Parameters:
  • request (ZPublisher.HTTPRequest) –
  • user (Products.PlonePAS.tools.memberdata) –
Return ska.SignatureValidationResult:
 

interfaces Module

pas_plugin Module

The idea of this PAS plugin is quite simple. It should check the user profile for the user being logged in and if user has enabled two-step verification for his account (enable_two_step_verification is set to True), then redirect him further to a another page, where he would enter his SMS Authenticator token, after successful validation of which the user would be definitely logged in.

If user has not enabled the two-step verification for his account (enable_two_step_verification is set to False), then do nothing so that Plone continues logging in the user normal way.

class collective.smsauthenticator.pas_plugin.SMSAuthenticatorPlugin(id, title=None)[source]

Bases: Products.PluggableAuthService.plugins.BasePlugin.BasePlugin

SMS Authenticator PAS Plugin

authenticateCredentials(credentials)[source]

Place to actually validate the user credentials specified and return a tuple (login, login) on success or (None, None) on failure.

If we find one and two-step verification is not enabled for the account, we consider the authentication passed and log the user in. If two-step verification has been enabled for the account, the first step of authentication is considered to be passed and we go to the next page (having the user and pass remembered), where we check for the token generated by the token generator (SMS Authenticator). If the token is valid too, we log the user in.

meta_type = 'Collective SMS Authenticator PAS'
collective.smsauthenticator.pas_plugin.addSMSAuthenticatorPlugin(self, id, title='', REQUEST=None)[source]

Add a SMS Authenticator PAS Plugin to Plone PAS

setuphandlers Module

collective.smsauthenticator.setuphandlers.setupVarious(context)[source]

@param context: Products.GenericSetup.context.DirectoryImportContext instance

collective.smsauthenticator.setuphandlers.uninstall(context)

Remove the PAS plugin.

testing Module

userdataschema Module

class collective.smsauthenticator.userdataschema.CustomizedUserDataPanel(context, request)[source]

Bases: plone.app.users.browser.personalpreferences.UserDataPanel

Customise the user form shown in personal-preferences.

class collective.smsauthenticator.userdataschema.UserDataSchemaProvider[source]

Bases: object

getSchema()[source]
collective.smsauthenticator.userdataschema.userCreatedHandler(principal, event)[source]

Fired upon creation of each user. If app setting globally_enabled is set to True, two-step verification would be automatically enabled for the registered users (in that case they would have to go through the mobile number recovery procedure.

The principal value is seems to be a user object, although it does not have the setMemberProperties method defined (that’s why we obtain the user using plone.api, ‘cause that one has it).