Improve authentication support.
authorFredrik Tolf <fredrik@dolda2000.com>
Tue, 5 Jun 2018 13:55:12 +0000 (15:55 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Tue, 5 Jun 2018 13:55:29 +0000 (15:55 +0200)
fulbank/auth.py [new file with mode: 0644]
fulbank/fsb.py

diff --git a/fulbank/auth.py b/fulbank/auth.py
new file mode 100644 (file)
index 0000000..1a9f13d
--- /dev/null
@@ -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
index d908f79..eee66be 100644 (file)
@@ -1,7 +1,7 @@
 import json, http.cookiejar, binascii, time, datetime, pickle, hashlib
 from urllib import request, parse
 from bs4 import BeautifulSoup as soup
 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/"
 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")
 
         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,
         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")))
         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")
         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()
                 continue
             elif st == "COMPLETE":
                 self._postlogin()