implement 2FA login

This commit is contained in:
lucasheld 2022-08-05 14:33:28 +02:00
parent 59181ddba2
commit 512057ab61
3 changed files with 62 additions and 5 deletions

1
tests/requirements.txt Normal file
View file

@ -0,0 +1 @@
pyotp==2.6.0

56
tests/test_2fa.py Normal file
View file

@ -0,0 +1,56 @@
import unittest
from urllib import parse
import pyotp
from uptime_kuma_test_case import UptimeKumaTestCase
def parse_secret(uri):
query = parse.urlsplit(uri).query
params = dict(parse.parse_qsl(query))
return params["secret"]
def generate_token(secret):
totp = pyotp.TOTP(secret)
return totp.now()
class Test2FA(UptimeKumaTestCase):
def test_2fa(self):
# check 2fa is disabled
r = self.api.twofa_status()
self.assertEqual(r["status"], False)
# prepare 2fa
r = self.api.prepare_2fa(self.password)
uri = r["uri"]
self.assertTrue(uri.startswith("otpauth://totp/"))
secret = parse_secret(uri)
# verify token
token = generate_token(secret)
r = self.api.verify_token(token, self.password)
self.assertEqual(r["valid"], True)
# save 2fa
r = self.api.save_2fa(self.password)
self.assertEqual(r["msg"], "2FA Enabled.")
# check 2fa is enabled
r = self.api.twofa_status()
self.assertEqual(r["status"], True)
# relogin using the totp token
self.api.logout()
token = generate_token(secret)
self.api.login(self.username, self.password, token)
# disable 2fa
r = self.api.disable_2fa(self.password)
self.assertEqual(r["msg"], "2FA Disabled.")
if __name__ == '__main__':
unittest.main()

View file

@ -801,6 +801,9 @@ class UptimeKumaApi(object):
def prepare_2fa(self, password: str):
return self._call('prepare2FA', password)
def verify_token(self, token: str, password: str):
return self._call('verifyToken', (token, password))
def save_2fa(self, password: str):
return self._call('save2FA', password)
@ -809,19 +812,16 @@ class UptimeKumaApi(object):
# login
def login(self, username: str, password: str):
def login(self, username: str, password: str, twofa_token: str = ""):
return self._call('login', {
"username": username,
"password": password,
"token": ""
"token": twofa_token
})
def login_by_token(self, token: str):
return self._call('loginByToken', token)
def verify_token(self, token: str, password: str):
return self._call('verifyToken', (token, password))
def logout(self):
return self._call('logout')