--- /dev/null
+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
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/"
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,
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()