def sign_user_data(request=None, user=None, url='@@sms-authenticator-token'): """ 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`). :param ZPublisher.HTTPRequest request: :param Products.PlonePAS.tools.memberdata user: :param string url: :return string: """ if request is None: request = getRequest() if user is None: user = api.user.get_current() token_lifetime = get_ska_token_lifetime() # Make sure the secret key always exists get_or_create_secret(user) secret_key = get_ska_secret_key(request=request, user=user) signed_url = sign_url(auth_user=user.getUserId(), secret_key=secret_key, url=url, lifetime=token_lifetime) return signed_url
def sign_user_data(request=None, user=None, url='@@google-authenticator-token'): """ 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_factor_authentication_secret`` (from users' profile). - Browser info (hash of) - The SECRET set for the `ska` (use `plone.app.registry`). :param ZPublisher.HTTPRequest request: :param Products.PlonePAS.tools.memberdata user: :param string url: :return string: """ if request is None: request = getRequest() if user is None: user = api.user.get_current() # Make sure the secret key always exists get_or_create_secret(user) secret_key = get_ska_secret_key(request=request, user=user) signed_url = sign_url( auth_user=user.getUserId(), secret_key=secret_key, url=url ) return signed_url
def _test_obtain_jwt_token_request_signed(self, secret_key, expected_response_code, url, auth_user=None, auth_user_email=None, provider_name=None, check_token=True, debug_info=""): """Test obtain JWT token signed requests. :return: """ if not auth_user: auth_user = self.AUTH_USER if not auth_user_email: auth_user_email = self.AUTH_USER_EMAIL # Testing signed URLs extra = { 'email': auth_user_email, 'first_name': self.AUTH_USER_FIRST_NAME, 'last_name': self.AUTH_USER_LAST_NAME, } if provider_name: extra.update({DEFAULT_PROVIDER_PARAM: provider_name}) signed_url = sign_url( auth_user=auth_user, secret_key=secret_key, url=url, extra=extra ) # if debug_info: # signed_url = '{}&debug_info={}'.format(signed_url, debug_info) data = {} if not isinstance(expected_response_code, (tuple, list)): expected_response_code = [expected_response_code] response = self.client.get(signed_url, data) self.assertIn(response.status_code, expected_response_code) if check_token: self.assertIn('token', response.data)
def _test_obtain_jwt_token_request_signed( self, secret_key, expected_response_code, url, auth_user=None, auth_user_email=None, provider_name=None, check_token=True, debug_info="", ): """Test obtain JWT token signed requests. :return: """ if not auth_user: auth_user = self.AUTH_USER if not auth_user_email: auth_user_email = self.AUTH_USER_EMAIL # Testing signed URLs extra = { "email": auth_user_email, "first_name": self.AUTH_USER_FIRST_NAME, "last_name": self.AUTH_USER_LAST_NAME, } if provider_name: extra.update({DEFAULT_PROVIDER_PARAM: provider_name}) signed_url = sign_url( auth_user=auth_user, secret_key=secret_key, url=url, extra=extra ) # if debug_info: # signed_url = '{}&debug_info={}'.format(signed_url, debug_info) data = {} if not isinstance(expected_response_code, (tuple, list)): expected_response_code = [expected_response_code] response = self.client.get(signed_url, data) self.assertIn(response.status_code, expected_response_code) if check_token: self.assertIn("token", response.data)
def sign_redirect_url(redirect_url, end_datetime): """ This function is used to sign the redirect URL (URL to redirect candidate to our app when candidate clicks on a URL in SMS campaign or Email campaign etc.) This used ska :param redirect_url: URL for redirection. e.g. http://127.0.0.1:8012/redirect/1 :param end_datetime: end_datetime of campaign :type redirect_url: str :type end_datetime: datetime """ if not isinstance(end_datetime, datetime): raise InvalidUsage('end_datetime must be instance of datetime') return sign_url( auth_user='******', secret_key=current_app.config[TalentConfigKeys.SECRET_KEY], url=redirect_url, valid_until=DatetimeUtils.unix_time( end_datetime.replace(tzinfo=tzutc())))
def _test_permissions_request_signed(self, secret_key, expected_response_code, url, auth_user=None, auth_user_email=None, provider_name=None): """Test permissions signed requests. :return: """ if not auth_user: auth_user = self.AUTH_USER if not auth_user_email: auth_user_email = self.AUTH_USER_EMAIL # Testing signed URLs extra = { 'email': auth_user_email, 'first_name': self.AUTH_USER_FIRST_NAME, 'last_name': self.AUTH_USER_LAST_NAME, } if provider_name: extra.update({DEFAULT_PROVIDER_PARAM: provider_name}) signed_list_url_url = sign_url( auth_user=auth_user, secret_key=secret_key, url=url, extra=extra ) data = {} if not isinstance(expected_response_code, (tuple, list)): expected_response_code = [expected_response_code] response = self.client.get(signed_list_url_url, data) self.assertIn(response.status_code, expected_response_code)
def _test_permissions_request_signed( self, secret_key, expected_response_code, url, auth_user=None, auth_user_email=None, provider_name=None, ): """Test permissions signed requests. :return: """ if not auth_user: auth_user = self.AUTH_USER if not auth_user_email: auth_user_email = self.AUTH_USER_EMAIL # Testing signed URLs extra = { "email": auth_user_email, "first_name": self.AUTH_USER_FIRST_NAME, "last_name": self.AUTH_USER_LAST_NAME, } if provider_name: extra.update({DEFAULT_PROVIDER_PARAM: provider_name}) signed_list_url_url = sign_url( auth_user=auth_user, secret_key=secret_key, url=url, extra=extra ) data = {} if not isinstance(expected_response_code, (tuple, list)): expected_response_code = [expected_response_code] response = self.client.get(signed_list_url_url, data) self.assertIn(response.status_code, expected_response_code)
def authenticate_view(request, template_name='foo/authenticate.html'): """Authenticate. :param django.http.HttpRequest request: :param str template_name: :return django.http.HttpResponse: """ # Server ska login URL remote_ska_login_url = reverse('ska.login') # General login URLs remote_ska_login_urls = [] for i in range(3): signed_remote_ska_login_url = sign_url( auth_user='******'.format(i), # Using general secret key secret_key=SECRET_KEY, url=remote_ska_login_url, extra={ 'email': 'test_ska_user_{0}@mail.example.com'.format(i), 'first_name': 'John {0}'.format(i), 'last_name': 'Doe {0}'.format(i), } ) remote_ska_login_urls.append( (i, remote_ska_login_url, signed_remote_ska_login_url) ) # Login URLs by provider remote_ska_login_urls_by_provider = [] for uid, data in PROVIDERS.items(): signed_remote_ska_login_url = sign_url( auth_user='******'.format(uid), # Using provider-specific secret key secret_key=data.get('SECRET_KEY'), url=remote_ska_login_url, extra={ 'email': 'test_ska_user_{0}@mail.example.com'.format(uid), 'first_name': 'John {0}'.format(uid), 'last_name': 'Doe {0}'.format(uid), DEFAULT_PROVIDER_PARAM: uid, } ) remote_ska_login_urls_by_provider.append( (uid, remote_ska_login_url, signed_remote_ska_login_url) ) # Fail-only login URLs by provider fail_only_remote_ska_login_urls_by_provider = [] uid = 'client_1.admins' data = PROVIDERS[uid] signed_remote_ska_login_url_invalid_username = sign_url( auth_user='******', # Using provider-specific secret key secret_key=data.get('SECRET_KEY'), url=remote_ska_login_url, extra={ 'email': 'test_ska_user_{0}@mail.example.com'.format(uid), 'first_name': 'John {0}'.format(uid), 'last_name': 'Doe {0}'.format(uid), DEFAULT_PROVIDER_PARAM: uid, } ) signed_remote_ska_login_url_invalid_email = sign_url( auth_user='******'.format(uid), # Using provider-specific secret key secret_key=data.get('SECRET_KEY'), url=remote_ska_login_url, extra={ 'email': '*****@*****.**', 'first_name': 'John {0}'.format(uid), 'last_name': 'Doe {0}'.format(uid), DEFAULT_PROVIDER_PARAM: uid, } ) fail_only_remote_ska_login_urls_by_provider.append( ( uid, 'invalid username: forbidden_username', signed_remote_ska_login_url_invalid_username, ) ) fail_only_remote_ska_login_urls_by_provider.append( ( uid, 'invalid email: [email protected]', signed_remote_ska_login_url_invalid_email ) ) # Template context context = { 'remote_ska_login_urls': remote_ska_login_urls, 'remote_ska_login_urls_by_provider': remote_ska_login_urls_by_provider, 'fail_only_remote_ska_login_urls_by_provider': fail_only_remote_ska_login_urls_by_provider, } return render(request, template_name, context)
def drf_view(request, template_name='foo/drf.html'): """Django REST Framework permissions view. :param request: :param template_name: :return: """ # ********************************************************* # **************** Provider list URLS ********************* # ********************************************************* drf_remote_ska_provider_list_url = reverse( 'fooitemmodel_provider_signed_request_required-list' ) drf_remote_ska_list_urls_provider = [] for uid, data in PROVIDERS.items(): # Provider specific list URLs signed_remote_ska_login_url = sign_url( auth_user='******'.format(uid), # Using provider-specific secret key secret_key=data.get('SECRET_KEY'), url=drf_remote_ska_provider_list_url, extra={ 'email': 'test_ska_user_{0}@mail.example.com'.format(uid), 'first_name': 'John {0}'.format(uid), 'last_name': 'Doe {0}'.format(uid), DEFAULT_PROVIDER_PARAM: uid, } ) drf_remote_ska_list_urls_provider.append( ( uid, drf_remote_ska_provider_list_url, signed_remote_ska_login_url ) ) # ********************************************************* # *********************** List URLS *********************** # ********************************************************* drf_remote_ska_list_url = reverse( 'fooitemmodel_signed_request_required-list' ) signed_remote_ska_login_url = sign_url( auth_user='******', # Using global secret key secret_key=SECRET_KEY, url=drf_remote_ska_list_url, extra={ 'email': '*****@*****.**', 'first_name': 'John', 'last_name': 'Doe', } ) drf_remote_ska_list_urls = [ ( 'global', drf_remote_ska_list_url, signed_remote_ska_login_url ) ] # ********************************************************* # **************** Provider auth URLS ********************* # ********************************************************* drf_obtain_jwt_token_url = reverse('ska.obtain_jwt_token') drf_remote_ska_jwt_token_urls_provider = [] for uid, data in PROVIDERS.items(): # Provider specific list URLs _drf_signed_obtain_jwt_token_url = sign_url( auth_user='******'.format(uid), # Using provider-specific secret key secret_key=data.get('SECRET_KEY'), url=drf_obtain_jwt_token_url, extra={ 'email': 'test_ska_user_{0}@mail.example.com'.format(uid), 'first_name': 'John {0}'.format(uid), 'last_name': 'Doe {0}'.format(uid), DEFAULT_PROVIDER_PARAM: uid, } ) drf_remote_ska_jwt_token_urls_provider.append( ( uid, drf_obtain_jwt_token_url, _drf_signed_obtain_jwt_token_url, ) ) # ********************************************************* # ***************** Global auth URLS ********************** # ********************************************************* drf_signed_obtain_jwt_token_url = sign_url( auth_user='******', # Using global secret key secret_key=SECRET_KEY, url=drf_obtain_jwt_token_url, extra={ 'email': '*****@*****.**', 'first_name': 'John', 'last_name': 'Doe', } ) drf_remote_ska_jwt_token_urls = [ ( 'global', drf_obtain_jwt_token_url, drf_signed_obtain_jwt_token_url ) ] # ********************************************************* # ****************** Template context ********************* # ********************************************************* context = { 'drf_remote_ska_list_urls': drf_remote_ska_list_urls, 'drf_remote_ska_provider_list_url': drf_remote_ska_list_urls_provider, 'drf_remote_ska_jwt_token_urls_provider': drf_remote_ska_jwt_token_urls_provider, 'drf_remote_ska_jwt_token_urls': drf_remote_ska_jwt_token_urls, } return render(request, template_name, context)
def authenticate_view(request, template_name="foo/authenticate.html"): """Authenticate. :param django.http.HttpRequest request: :param str template_name: :return django.http.HttpResponse: """ # Server ska login URL remote_ska_login_url = reverse("ska.login") # General login URLs remote_ska_login_urls = [] for i in range(3): signed_remote_ska_login_url = sign_url( auth_user="******".format(i), # Using general secret key secret_key=SECRET_KEY, url=remote_ska_login_url, extra={ "email": "test_ska_user_{0}@mail.example.com".format(i), "first_name": "John {0}".format(i), "last_name": "Doe {0}".format(i), }, ) remote_ska_login_urls.append( (i, remote_ska_login_url, signed_remote_ska_login_url)) # Login URLs by provider remote_ska_login_urls_by_provider = [] for uid, data in PROVIDERS.items(): signed_remote_ska_login_url = sign_url( auth_user="******".format(uid), # Using provider-specific secret key secret_key=data.get("SECRET_KEY"), url=remote_ska_login_url, extra={ "email": "test_ska_user_{0}@mail.example.com".format(uid), "first_name": "John {0}".format(uid), "last_name": "Doe {0}".format(uid), DEFAULT_PROVIDER_PARAM: uid, }, ) remote_ska_login_urls_by_provider.append( (uid, remote_ska_login_url, signed_remote_ska_login_url)) # Fail-only login URLs by provider fail_only_remote_ska_login_urls_by_provider = [] uid = "client_1.admins" data = PROVIDERS[uid] signed_remote_ska_login_url_invalid_username = sign_url( auth_user="******", # Using provider-specific secret key secret_key=data.get("SECRET_KEY"), url=remote_ska_login_url, extra={ "email": "test_ska_user_{0}@mail.example.com".format(uid), "first_name": "John {0}".format(uid), "last_name": "Doe {0}".format(uid), DEFAULT_PROVIDER_PARAM: uid, }, ) signed_remote_ska_login_url_invalid_email = sign_url( auth_user="******".format(uid), # Using provider-specific secret key secret_key=data.get("SECRET_KEY"), url=remote_ska_login_url, extra={ "email": "*****@*****.**", "first_name": "John {0}".format(uid), "last_name": "Doe {0}".format(uid), DEFAULT_PROVIDER_PARAM: uid, }, ) fail_only_remote_ska_login_urls_by_provider.append(( uid, "invalid username: forbidden_username", signed_remote_ska_login_url_invalid_username, )) fail_only_remote_ska_login_urls_by_provider.append(( uid, "invalid email: [email protected]", signed_remote_ska_login_url_invalid_email, )) # Template context context = { "remote_ska_login_urls": remote_ska_login_urls, "remote_ska_login_urls_by_provider": remote_ska_login_urls_by_provider, "fail_only_remote_ska_login_urls_by_provider": fail_only_remote_ska_login_urls_by_provider, } return render(request, template_name, context)
def drf_view(request, template_name="foo/drf.html"): """Django REST Framework permissions view. :param request: :param template_name: :return: """ # ********************************************************* # **************** Provider list URLS ********************* # ********************************************************* drf_remote_ska_provider_list_url = reverse( "fooitemmodel_provider_signed_request_required-list") drf_remote_ska_list_urls_provider = [] for uid, data in PROVIDERS.items(): # Provider specific list URLs signed_remote_ska_login_url = sign_url( auth_user="******".format(uid), # Using provider-specific secret key secret_key=data.get("SECRET_KEY"), url=drf_remote_ska_provider_list_url, extra={ "email": "test_ska_user_{0}@mail.example.com".format(uid), "first_name": "John {0}".format(uid), "last_name": "Doe {0}".format(uid), DEFAULT_PROVIDER_PARAM: uid, }, ) drf_remote_ska_list_urls_provider.append(( uid, drf_remote_ska_provider_list_url, signed_remote_ska_login_url, )) # ********************************************************* # *********************** List URLS *********************** # ********************************************************* drf_remote_ska_list_url = reverse( "fooitemmodel_signed_request_required-list") signed_remote_ska_login_url = sign_url( auth_user="******", # Using global secret key secret_key=SECRET_KEY, url=drf_remote_ska_list_url, extra={ "email": "*****@*****.**", "first_name": "John", "last_name": "Doe", }, ) drf_remote_ska_list_urls = [("global", drf_remote_ska_list_url, signed_remote_ska_login_url)] # ********************************************************* # **************** Provider auth URLS ********************* # ********************************************************* drf_obtain_jwt_token_url = reverse("ska.obtain_jwt_token") drf_remote_ska_jwt_token_urls_provider = [] for uid, data in PROVIDERS.items(): # Provider specific list URLs _drf_signed_obtain_jwt_token_url = sign_url( auth_user="******".format(uid), # Using provider-specific secret key secret_key=data.get("SECRET_KEY"), url=drf_obtain_jwt_token_url, extra={ "email": "test_ska_user_{0}@mail.example.com".format(uid), "first_name": "John {0}".format(uid), "last_name": "Doe {0}".format(uid), DEFAULT_PROVIDER_PARAM: uid, }, ) drf_remote_ska_jwt_token_urls_provider.append(( uid, drf_obtain_jwt_token_url, _drf_signed_obtain_jwt_token_url, )) # ********************************************************* # ***************** Global auth URLS ********************** # ********************************************************* drf_signed_obtain_jwt_token_url = sign_url( auth_user="******", # Using global secret key secret_key=SECRET_KEY, url=drf_obtain_jwt_token_url, extra={ "email": "*****@*****.**", "first_name": "John", "last_name": "Doe", }, ) drf_remote_ska_jwt_token_urls = [("global", drf_obtain_jwt_token_url, drf_signed_obtain_jwt_token_url)] # ********************************************************* # ****************** Template context ********************* # ********************************************************* context = { "drf_remote_ska_list_urls": drf_remote_ska_list_urls, "drf_remote_ska_provider_list_url": drf_remote_ska_list_urls_provider, "drf_remote_ska_jwt_token_urls_provider": drf_remote_ska_jwt_token_urls_provider, "drf_remote_ska_jwt_token_urls": drf_remote_ska_jwt_token_urls, } return render(request, template_name, context)
def __test_login( self, secret_key, response_codes, provider_name=None, logout=False, test_email_data=None, do_signature_check=True, debug_info="", ): """Test login. :param secret_key: :param response_codes: First response code is used :param provider_name: :param logout: :param test_email_data: :param do_signature_check: It's a tuple. The second code is used only if both `DB_STORE_SIGNATURES` and `DB_PERFORM_SIGNATURE_CHECK` values are True, which means that users can't use same signatures twice. :return: """ flow = [] first_response_code, second_response_code = response_codes # Testing signed URLs extra = { "email": self.AUTH_USER_EMAIL, "first_name": self.AUTH_USER_FIRST_NAME, "last_name": self.AUTH_USER_LAST_NAME, } if provider_name: extra.update({DEFAULT_PROVIDER_PARAM: provider_name}) signed_login_url = sign_url( auth_user=self.AUTH_USER, secret_key=secret_key, url=self.LOGIN_URL, extra=extra, ) self.assertIsNotNone(signed_login_url) flow.append(("Signed login URL", signed_login_url)) # Testing view with signed URL self._client = Client() response = self._client.get(signed_login_url, {}) response_status_code = getattr(response, "status_code", None) self.assertIn(response_status_code, (first_response_code, )) flow.append( ("Response status code for signed URL", response_status_code)) if test_email_data: self.assertEqual(len(mail.outbox), len(test_email_data["emails"])) for _index, _subject in test_email_data["emails"].items(): self.assertEqual(mail.outbox[_index].subject, _subject) if logout: self.__logout() # If both `DB_STORE_SIGNATURES` and `DB_PERFORM_SIGNATURE_CHECK` # are set to True, second login attempt shall not be successful. if (ska_settings.DB_STORE_SIGNATURES and ska_settings.DB_PERFORM_SIGNATURE_CHECK and do_signature_check): # Testing again with signed URL and this time, it should fail self._client = Client() response = self._client.get(signed_login_url, {}) response_status_code = getattr(response, "status_code", None) self.assertIn(response_status_code, (second_response_code, )) flow.append(( "Response status " "code for signed URL", response_status_code, )) if logout: self.__logout() return flow
def __test_login(self, secret_key, response_codes, provider_name=None, logout=False, test_email_data=None, do_signature_check=True, debug_info=""): """Test login. :param secret_key: :param response_codes: First response code is used :param provider_name: :param logout: :param test_email_data: :param do_signature_check: It's a tuple. The second code is used only if both `DB_STORE_SIGNATURES` and `DB_PERFORM_SIGNATURE_CHECK` values are True, which means that users can't use same signatures twice. :return: """ flow = [] first_response_code, second_response_code = response_codes # Testing signed URLs extra = { 'email': self.AUTH_USER_EMAIL, 'first_name': self.AUTH_USER_FIRST_NAME, 'last_name': self.AUTH_USER_LAST_NAME, } if provider_name: extra.update({DEFAULT_PROVIDER_PARAM: provider_name}) signed_login_url = sign_url( auth_user=self.AUTH_USER, secret_key=secret_key, url=self.LOGIN_URL, extra=extra ) self.assertIsNotNone(signed_login_url) flow.append(('Signed login URL', signed_login_url)) # Testing view with signed URL self._client = Client() response = self._client.get(signed_login_url, {}) response_status_code = getattr(response, 'status_code', None) self.assertIn(response_status_code, (first_response_code,)) flow.append( ( 'Response status code for signed URL', response_status_code ) ) if test_email_data: self.assertEqual( len(mail.outbox), len(test_email_data['emails']) ) for _index, _subject in test_email_data['emails'].items(): self.assertEqual( mail.outbox[_index].subject, _subject ) if logout: self.__logout() # If both `DB_STORE_SIGNATURES` and `DB_PERFORM_SIGNATURE_CHECK` # are set to True, second login attempt shall not be successful. if ska_settings.DB_STORE_SIGNATURES \ and ska_settings.DB_PERFORM_SIGNATURE_CHECK \ and do_signature_check: # Testing again with signed URL and this time, it should fail self._client = Client() response = self._client.get(signed_login_url, {}) response_status_code = getattr(response, 'status_code', None) self.assertIn(response_status_code, (second_response_code,)) flow.append( ( 'Response status ' 'code for signed URL', response_status_code ) ) if logout: self.__logout() return flow