From: Fredrik Tolf Date: Tue, 5 Jun 2018 13:55:12 +0000 (+0200) Subject: Improve authentication support. X-Git-Url: http://dolda2000.com/gitweb/?p=fulbank.git;a=commitdiff_plain;h=f4de0bf1d44ae1db7c4e1bc6d2a664436e12b78f Improve authentication support. --- diff --git a/fulbank/auth.py b/fulbank/auth.py new file mode 100644 index 0000000..1a9f13d --- /dev/null +++ b/fulbank/auth.py @@ -0,0 +1,70 @@ +import sys, os, io, termios + +class conv(object): + msg_notice = 0 + msg_info = 1 + msg_debug = 2 + + def error(self, msg): + pass + def message(self, msg, level=0): + pass + def prompt(self, prompt, echo, default=None): + return default + +class termconv(conv): + def __init__(self, ifp, ofp): + self.ifp = ifp + self.ofp = ofp + + def error(self, msg): + self.ofp.write("%s\n" % (msg,)) + self.ofp.flush() + def message(self, msg, level=0): + if level <= self.msg_info: + self.ofp.write("%s\n" % (msg,)) + self.ofp.flush() + def prompt(self, prompt, echo, default=None): + if echo: + self.ofp.write(prompt) + self.ofp.flush() + ret = self.ifp.readline() + assert ret[-1] == '\n' + return ret[:-1] + else: + attr = termios.tcgetattr(self.ifp.fileno()) + bka = list(attr) + try: + attr[3] &= ~termios.ECHO + termios.tcflush(self.ifp.fileno(), termios.TCIOFLUSH) + termios.tcsetattr(self.ifp.fileno(), termios.TCSANOW, attr) + self.ofp.write(prompt) + self.ofp.flush() + ret = self.ifp.readline() + self.ofp.write("\n") + assert ret[-1] == '\n' + return ret[:-1] + finally: + termios.tcsetattr(self.ifp.fileno(), termios.TCSANOW, bka) + +class ctermconv(conv): + def __init__(self, fp): + super().__init__(fp) + self.cfp = fp + + def close(self): + self.cfp.close() + def __enter__(self): + return self + def __exit__(self, *excinfo): + self.close() + return False + +null = conv() +stdioconv = termconv(sys.stdin, sys.stdout) + +def ttyconv(): + return ctermconv(io.TextIOWrapper(io.FileIO(os.open("/dev/tty", os.O_RDWR | os.O_NCTTY), "r+"))) + +def default(): + return null diff --git a/fulbank/fsb.py b/fulbank/fsb.py index d908f79..eee66be 100644 --- a/fulbank/fsb.py +++ b/fulbank/fsb.py @@ -1,7 +1,7 @@ import json, http.cookiejar, binascii, time, datetime, pickle, hashlib from urllib import request, parse from bs4 import BeautifulSoup as soup -from . import currency +from . import currency, auth soupify = lambda cont: soup(cont, "html.parser") apibase = "https://online.swedbank.se/TDE_DAP_Portal_REST_WEB/api/" @@ -168,7 +168,9 @@ class session(object): rolesw = linkurl(resolve(prof["banks"][0], ("privateProfile", "links", "next", "uri"))) self._jreq(rolesw, method="POST") - def auth_bankid(self, user): + def auth_bankid(self, user, conv=None): + if conv is None: + conv = auth.default() data = self._jreq("v5/identification/bankid/mobile", data = { "userId": user, "useEasyLogin": False, @@ -176,13 +178,15 @@ class session(object): if data.get("status") != "USER_SIGN": raise fmterror("unexpected bankid status: " + str(data.get("status"))) vfy = linkurl(resolve(data, ("links", "next", "uri"))) + fst = None while True: time.sleep(3) vdat = self._jreq(vfy) st = vdat.get("status") - if st == "USER_SIGN": - continue - elif st == "CLIENT_NOT_STARTED": + if st in {"USER_SIGN", "CLIENT_NOT_STARTED"}: + if st != fst: + conv.message("Status: %s" % (st,), auth.conv.msg_info) + fst = st continue elif st == "COMPLETE": self._postlogin()