From e2e24d0e5a1b28138d93bec0bba5015002397065 Mon Sep 17 00:00:00 2001 From: NavaL Date: Thu, 3 Nov 2016 15:24:18 +0100 Subject: [#792] refactor pixelated-register and removed leap.auth dependency --- service/pixelated/register.py | 21 +++--- service/test/load/locustfile.py | 121 ------------------------------ service/test/reactor/create_users.py | 79 ++++++++++++------- service/test/unit/config/test_register.py | 11 +-- service/test_requirements.txt | 1 - 5 files changed, 69 insertions(+), 164 deletions(-) delete mode 100644 service/test/load/locustfile.py (limited to 'service') diff --git a/service/pixelated/register.py b/service/pixelated/register.py index 58798476..b6faf454 100644 --- a/service/pixelated/register.py +++ b/service/pixelated/register.py @@ -49,36 +49,39 @@ def _set_provider(provider_cert, provider_cert_fingerprint, server_name, leap_ho return provider +def _set_leap_provider(args): + return _set_provider(args.leap_provider_cert, args.leap_provider_cert_fingerprint, args.provider, args.leap_home) + + def _bonafide_session(username, password, provider): srp_provider = Api(provider.api_uri) credentials = Credentials(username, password) return Session(credentials, srp_provider, provider.local_ca_crt) -def log_results(created, username, server_name): +def log_results(created, username): if created: - logger.info('User %s@%s successfully registered' % (username, server_name)) + logger.info('User %s successfully registered' % username) else: logger.error("Register failed") @inlineCallbacks -def register(server_name, username, password, leap_home, provider_cert, provider_cert_fingerprint, invite=None): +def register(username, password, leap_provider, invite=None): if not password: password = getpass.getpass('Please enter password for %s: ' % username) _validate(username, password) logger.info('password validated...') - leap_provider = _set_provider(provider_cert, provider_cert_fingerprint, server_name, leap_home) srp_auth = _bonafide_session(username, password, leap_provider) created, user = yield srp_auth.signup(username, password, invite) - log_results(created, username, server_name) + log_results(created, username) def validate_username(username): accepted_characters = '^[a-z0-9\-\_\.]*$' - if (not re.match(accepted_characters, username)): + if not re.match(accepted_characters, username): raise ValueError('Only lowercase letters, digits, . - and _ allowed.') @@ -91,6 +94,7 @@ def validate_password(password): def initialize(): logger_config.init(debug=False) args = arguments.parse_register_args() + leap_provider = _set_leap_provider(args) def show_error(err): logger.info('error: %s' % err) @@ -100,12 +104,9 @@ def initialize(): def _register(): d = register( - args.provider, args.username, args.password, - args.leap_home, - args.leap_provider_cert, - args.leap_provider_cert_fingerprint, + leap_provider, args.invite_code) d.addErrback(show_error) d.addBoth(shut_down) diff --git a/service/test/load/locustfile.py b/service/test/load/locustfile.py deleted file mode 100644 index 2969a218..00000000 --- a/service/test/load/locustfile.py +++ /dev/null @@ -1,121 +0,0 @@ -import os -import json -from random import randint - -from leap.auth import SRPAuth -from leap.exceptions import SRPAuthenticationError -from locust import HttpLocust, TaskSet, task -from pixelated.resources.login_resource import LoginResource - -import requests -from requests.packages.urllib3.exceptions import InsecureRequestWarning -requests.packages.urllib3.disable_warnings(InsecureRequestWarning) - -LEAP_PROVIDER = os.environ.get('LEAP_PROVIDER', 'dev.pixelated-project.org') -LEAP_SERVER_HOST = os.environ.get( - 'LEAP_SERVER_HOST', - 'https://api.%s:4430' % LEAP_PROVIDER) -LEAP_VERIFY_CERTIFICATE = os.environ.get( - 'LEAP_VERIFY_CERTIFICATE', - '~/.leap/ca.crt') -MAX_NUMBER_USER = os.environ.get('MAX_NUMBER_USER', 80) -INVITES_FILENAME = os.environ.get('INVITES_FILENAME', '/tmp/invite_codes.txt') -INVITES_ENABLED = os.environ.get('INVITES_ENABLED', 'true') == 'true' - - -def load_invite_from_number(number): - with open(INVITES_FILENAME) as invites_file: - lines = invites_file.readlines() - return lines[number].strip() - - -class UserBehavior(TaskSet): - def __init__(self, *args, **kwargs): - super(UserBehavior, self).__init__(*args, **kwargs) - self.cookies = {} - - def on_start(self): - self.login() - - def _get_or_create_user(self, number): - srp_auth = SRPAuth( - LEAP_SERVER_HOST, - os.path.expanduser(LEAP_VERIFY_CERTIFICATE)) - username, password = ('loadtest%d' % number), ('password_%d' % number) - try: - srp_auth.authenticate(username, password) - except SRPAuthenticationError: - invite_code = None - if INVITES_ENABLED: - invite_code = load_invite_from_number(number) - - srp_auth.register(username, password, invite_code) - return username, password - - def login(self): - number = randint(1, int(MAX_NUMBER_USER)) - username, password = self._get_or_create_user(number) - response = self.client.post( - "/%s" % LoginResource.BASE_URL, - {"username": username, "password": password}, - verify=False, - cookies=self.cookies) - self.cookies.update(response.cookies.get_dict()) - self.username = username - - @task(1) - def index(self): - self.client.get("/", verify=False) - - @task(2) - def mail_box(self): - self.client.get("/mails?q=tag:'inbox'&p=1&w=25", verify=False) - - @task(3) - def send_mail(self): - payload = { - "tags": ["drafts"], - "body": "some text lorem ipsum", - "attachments": [], - "ident": "", - "header": { - "to": ["%s@%s" % (self.username, LEAP_PROVIDER)], - "cc": [], - "bcc": [], - "subject": "load testing"}} - - self.cookies.update( - self.client.get("/", verify=False).cookies.get_dict()) - with self.client.post( - '/mails', - json=payload, - catch_response=True, - cookies=self.cookies, - headers={ - 'X-Requested-With': 'XMLHttpRequest', - 'X-XSRF-TOKEN': self.cookies.get('XSRF-TOKEN', '')}) as email_response: - if email_response.status_code == 201: - email_id = json.loads(email_response.content)['ident'] - print email_id - self.delete_mail(email_id) - else: - email_response.failure( - 'Error: email not Sent, status code: %s' % ( - email_response.status_code)) - - def delete_mail(self, ident): - payload = {"idents": [ident]} - self.client.post( - '/mails/delete', - json=payload, - cookies=self.cookies, - verify=False, - headers={ - 'X-Requested-With': 'XMLHttpRequest', - 'X-XSRF-TOKEN': self.cookies.get('XSRF-TOKEN', '')}) - - -class WebsiteUser(HttpLocust): - task_set = UserBehavior - min_wait = 1000 - max_wait = 5000 diff --git a/service/test/reactor/create_users.py b/service/test/reactor/create_users.py index 7c35df60..18dc9dcf 100755 --- a/service/test/reactor/create_users.py +++ b/service/test/reactor/create_users.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python # This script is used to mass register users # ATTENTION: this script does not log # the user in, so key creation will only @@ -7,13 +8,15 @@ # python create_users.py -n -p -i import argparse -import os -import tempfile -from leap.auth import SRPAuth -from leap.exceptions import SRPAuthenticationError import requests +from pixelated.authentication import Authenticator +from pixelated.register import register, _set_provider from requests.packages.urllib3.exceptions import InsecureRequestWarning +from twisted.cred.error import UnauthorizedLogin +from twisted.internet import reactor +from twisted.internet.defer import inlineCallbacks, returnValue, gatherResults + requests.packages.urllib3.disable_warnings(InsecureRequestWarning) @@ -21,38 +24,45 @@ class User(object): def __init__(self, number, provider, certificate): self._username = 'loadtest%d' % number self._password = 'password_%d' % number - self._set_srp_auth(provider, certificate) - - def _set_srp_auth(self, leap_provider, certificate): - leap_api_server = 'https://api.%s:4430' % leap_provider - self._srp_auth = SRPAuth(leap_api_server, certificate) + self._leap_provider = _set_provider(provider, None, certificate, None) + self._authenticator = Authenticator(self._leap_provider) + @inlineCallbacks def get_or_create_user(self, invite_code=None): try: - self.authenticate() - except SRPAuthenticationError: - self.register(invite_code) - return self._username, self._password + yield self.authenticate() + except UnauthorizedLogin: + yield self.register(invite_code) + user = (self._username, self._password) + returnValue(user) + @inlineCallbacks def authenticate(self): - self._srp_auth.authenticate(self._username, self._password) + yield self._authenticator.authenticate(self._username, self._password) + @inlineCallbacks def register(self, invite_code=None): - self._srp_auth.register(self._username, self._password, invite_code) + yield register(self._username, self._password, self._leap_provider, invite=invite_code) -def mass_register(number, invite_code, provider, certificate): +def mass_register(number, invite_code, provider): + leap_provider = _set_provider(None, None, provider, None) + deferreds = [] for index in xrange(1, number + 1): - User(index, provider, certificate).register(invite_code) - print 'done registering loadtest%d' % index + _username = 'loadtest%d' % index + _password = 'password_%d' % index + + def success(x, username): + print 'done registering %s ' % username + def failed(err, username): + print 'ERROR registering %s: %s' % (username, err.getErrorMessage()) -def fetch_leap_certificate(leap_provider): - _, certificate_path = tempfile.mkstemp() - certificate = requests.get('https://%s/ca.crt' % leap_provider) - with open(certificate_path, 'w') as cert: - cert.write('%s' % certificate.content) - return certificate_path + d = register(_username, _password, leap_provider, invite=invite_code) + d.addCallback(success, _username) + d.addErrback(failed, _username) + deferreds.append(d) + return gatherResults(deferreds, consumeErrors=True) def _parse_args(): @@ -63,7 +73,22 @@ def _parse_args(): return parser.parse_args() -if __name__ == '__main__': +def run(): args = _parse_args() - certificate_file = fetch_leap_certificate(args.provider) - mass_register(args.number, args.invite_code, args.provider, certificate_file) + + def show_error(err): + print "ERROR: %s" % err.getErrorMessage() + + def shut_down(_): + reactor.stop() + + def _run(): + d = mass_register(args.number, args.invite_code, args.provider) + d.addErrback(show_error) + d.addBoth(shut_down) + + reactor.callWhenRunning(_run) + reactor.run() + +if __name__ == '__main__': + run() diff --git a/service/test/unit/config/test_register.py b/service/test/unit/config/test_register.py index d3999dfd..ca1e3a01 100644 --- a/service/test/unit/config/test_register.py +++ b/service/test/unit/config/test_register.py @@ -2,6 +2,7 @@ import unittest from mock import patch, Mock from pixelated.register import validate_username, validate_password, _set_provider, register +from twisted.internet import defer from twisted.internet.defer import inlineCallbacks @@ -34,15 +35,15 @@ class TestRegister(unittest.TestCase): self.assertTrue(mock_provider.setup_ca.called) self.assertTrue(mock_provider.download_settings.called) - @patch('pixelated.register._set_provider') + @patch('pixelated.register.logger') @inlineCallbacks - def test_register_uses_bonafide_auth(self, mock_set_provider): + def test_register_uses_bonafide_auth(self, mock_logger): mock_provider = Mock() mock_provider.api_uri = 'https://pro.vi.der' - mock_set_provider.return_value = mock_provider mock_bonafide_session = Mock() - mock_bonafide_session.signup.return_value = ('created', 'user') + mock_bonafide_session.signup.return_value = defer.succeed(('created', 'user')) with patch('pixelated.register.Session', return_value=mock_bonafide_session) as mock_instantiate_bonafide_session: - yield register('server_name', 'username', 'password', 'leap_home', 'provider_cert', 'provider_cert_fingerprint', 'invite') + yield register('username', 'password', mock_provider, 'invite') mock_instantiate_bonafide_session.assert_called_once() mock_bonafide_session.signup.assert_called_once_with('username', 'password', 'invite') + mock_logger.info.assert_called_with('User username successfully registered') diff --git a/service/test_requirements.txt b/service/test_requirements.txt index 94b19526..b6b704c7 100644 --- a/service/test_requirements.txt +++ b/service/test_requirements.txt @@ -10,4 +10,3 @@ coverage crochet==1.4.0 poster==0.8.1 locustio==0.7.3 --e 'git+https://github.com/pixelated/leap_auth.git#egg=leap.auth' -- cgit v1.2.3