185 lines
5.7 KiB
Python
185 lines
5.7 KiB
Python
|
import unittest
|
||
|
import sys
|
||
|
import os
|
||
|
import pytest
|
||
|
import pyotp
|
||
|
|
||
|
sys.path.append(
|
||
|
os.path.dirname(
|
||
|
os.path.dirname(os.path.abspath(__file__))
|
||
|
)
|
||
|
)
|
||
|
import app
|
||
|
import config
|
||
|
|
||
|
|
||
|
class TestUOTP(unittest.TestCase):
|
||
|
app_client = None
|
||
|
admin_name = 'admin'
|
||
|
admin_seed = None
|
||
|
admin_realm = 'ungleich-admin'
|
||
|
auth_realm = 'ungleich-auth'
|
||
|
etcd_client = config.etcd_client
|
||
|
|
||
|
@classmethod
|
||
|
def setUpClass(cls):
|
||
|
app.app.config['TESTING'] = True
|
||
|
os.environ['BASE_PREFIX'] = '/test/uotp/'
|
||
|
os.environ['ADMIN_REALM'] = TestUOTP.admin_realm
|
||
|
os.environ['AUTH_REALM'] = TestUOTP.auth_realm
|
||
|
|
||
|
with app.app.test_client() as client:
|
||
|
with app.app.app_context():
|
||
|
app.create_admin_if_dont_exists(TestUOTP.etcd_client)
|
||
|
|
||
|
entry = TestUOTP.etcd_client.get(
|
||
|
os.path.join(
|
||
|
os.environ['BASE_PREFIX'],
|
||
|
os.environ['ADMIN_REALM'],
|
||
|
'admin'
|
||
|
), value_in_json=True
|
||
|
)
|
||
|
|
||
|
assert entry is not None
|
||
|
|
||
|
TestUOTP.app_client = client
|
||
|
TestUOTP.admin_seed = entry.value['seed']
|
||
|
|
||
|
return super().setUpClass()
|
||
|
|
||
|
@classmethod
|
||
|
def tearDownClass(cls):
|
||
|
TestUOTP.etcd_client.client.delete_prefix(os.environ['BASE_PREFIX'])
|
||
|
del os.environ['BASE_PREFIX']
|
||
|
del os.environ['ADMIN_REALM']
|
||
|
del os.environ['AUTH_REALM']
|
||
|
return super().tearDownClass()
|
||
|
|
||
|
def get_otp_list(self):
|
||
|
r = self.app_client.get('/list',
|
||
|
json={
|
||
|
'admin-name': self.admin_name,
|
||
|
'admin-realm': self.admin_realm,
|
||
|
'admin-token': pyotp.TOTP(self.admin_seed).now()
|
||
|
}
|
||
|
)
|
||
|
return r
|
||
|
|
||
|
def create_otp(self, _name, _realm, _admin_name, _admin_realm, _admin_seed):
|
||
|
r = self.app_client.post('/create',
|
||
|
json={
|
||
|
"name": _name,
|
||
|
"realm": _realm,
|
||
|
"admin-name": _admin_name,
|
||
|
"admin-realm": _admin_realm,
|
||
|
"admin-token": pyotp.TOTP(_admin_seed).now()
|
||
|
})
|
||
|
return r
|
||
|
|
||
|
def verify_otp(self, _name, _realm, _seed,
|
||
|
_auth_name, _auth_realm, _auth_seed):
|
||
|
r = self.app_client.get('/verify',
|
||
|
json={
|
||
|
"name": _name,
|
||
|
"realm": _realm,
|
||
|
"token": pyotp.TOTP(_seed).now(),
|
||
|
"auth-name": _auth_name,
|
||
|
"auth-realm": _auth_realm,
|
||
|
"auth-token": pyotp.TOTP(_auth_seed).now()
|
||
|
})
|
||
|
return r
|
||
|
|
||
|
def test_list(self):
|
||
|
r = self.get_otp_list()
|
||
|
self.assertEqual(r.status_code, 200)
|
||
|
self.assertIn(
|
||
|
'{}/{}'.format(self.admin_realm, self.admin_name),
|
||
|
r.json
|
||
|
)
|
||
|
|
||
|
def test_create(self):
|
||
|
_name = 'auth'
|
||
|
_realm = 'ungleich-auth'
|
||
|
|
||
|
# Test Successful case i.e Admin creating OTP Account
|
||
|
r = self.create_otp(_name, _realm,
|
||
|
self.admin_name, self.admin_realm,
|
||
|
self.admin_seed)
|
||
|
|
||
|
self.assertEqual(r.status_code, 200)
|
||
|
|
||
|
r = self.get_otp_list()
|
||
|
self.assertIn(
|
||
|
'{}/{}'.format(_realm, _name),
|
||
|
r.json
|
||
|
)
|
||
|
|
||
|
# Test Unsuccesful Creation i.e User from non-admin realm
|
||
|
# tries to create OTP account
|
||
|
|
||
|
# Get Auth Account
|
||
|
entry = self.etcd_client.get(
|
||
|
os.path.join(
|
||
|
os.environ['BASE_PREFIX'], _realm, _name
|
||
|
), value_in_json=True
|
||
|
)
|
||
|
_adversery_name = 'adversery'
|
||
|
_adversery_realm = 'ungleich-admin'
|
||
|
|
||
|
r = self.create_otp(_adversery_name, _adversery_realm,
|
||
|
_name, _realm, entry.value['seed'])
|
||
|
self.assertEqual(r.status_code, 400)
|
||
|
|
||
|
r = self.get_otp_list()
|
||
|
self.assertNotIn(
|
||
|
'{}/{}'.format(_adversery_realm, _adversery_name),
|
||
|
r.json
|
||
|
)
|
||
|
|
||
|
def test_verify(self):
|
||
|
_auth_name = 'verification-auth'
|
||
|
_auth_realm = 'ungleich-auth'
|
||
|
_auth_seed = None
|
||
|
|
||
|
r = self.create_otp(_auth_name, _auth_realm,
|
||
|
self.admin_name, self.admin_realm,
|
||
|
self.admin_seed)
|
||
|
|
||
|
self.assertEqual(r.status_code, 200)
|
||
|
entry = self.etcd_client.get(
|
||
|
os.path.join(
|
||
|
os.environ['BASE_PREFIX'],
|
||
|
_auth_realm,
|
||
|
_auth_name
|
||
|
),
|
||
|
value_in_json=True
|
||
|
)
|
||
|
self.assertIsNotNone(entry)
|
||
|
_auth_seed = entry.value['seed']
|
||
|
|
||
|
# This should work
|
||
|
r = self.verify_otp(self.admin_name, self.admin_realm,
|
||
|
self.admin_seed, _auth_name, _auth_realm,
|
||
|
_auth_seed)
|
||
|
self.assertEqual(r.status_code, 200)
|
||
|
|
||
|
# This should not work i.e should rerturn 400
|
||
|
# because the auth_seed is not correct
|
||
|
r = self.verify_otp(self.admin_name, self.admin_realm,
|
||
|
self.admin_seed, _auth_name,
|
||
|
_auth_realm, 'meowmeowmeow')
|
||
|
self.assertEqual(r.status_code, 400)
|
||
|
|
||
|
# This should not work i.e should rerturn 400
|
||
|
# because the auth user is not from ungleich-auth realm
|
||
|
r = self.verify_otp(self.admin_name, self.admin_realm,
|
||
|
self.admin_seed, self.admin_name,
|
||
|
self.admin_realm, self.admin_seed)
|
||
|
self.assertEqual(r.status_code, 400)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
unittest.main()
|