X-Git-Url: http://dolda2000.com/gitweb/?p=fulbank.git;a=blobdiff_plain;f=fulbank%2Ffsb.py;h=44a4849631b7bfe509b7d366bb5805f1cfa9e356;hp=58a54dce6a2aee48c7ddd300731315e4aace902e;hb=86601bc0ad178d310260fa81ff987cf8a12bf383;hpb=717d54fc63dac677f3c19728e0943fdccc510d07 diff --git a/fulbank/fsb.py b/fulbank/fsb.py index 58a54dc..44a4849 100644 --- a/fulbank/fsb.py +++ b/fulbank/fsb.py @@ -1,4 +1,4 @@ -import json, http.cookiejar, binascii, time, datetime, pickle +import json, http.cookiejar, binascii, time, datetime, pickle, urllib.error from urllib import request, parse from bs4 import BeautifulSoup as soup from . import currency, auth, data @@ -11,9 +11,23 @@ serviceid = "B7dZHQcY78VRVz9l" class fmterror(Exception): pass -class autherror(Exception): +class autherror(auth.autherror): pass +class jsonerror(Exception): + def __init__(self, code, data, headers): + self.code = code + self.data = data + self.headers = headers + + @classmethod + def fromerr(cls, err): + cs = err.headers.get_content_charset() + if cs is None: + cs = "utf-8" + data = json.loads(err.read().decode(cs)) + return cls(err.code, data, err.headers) + def resolve(d, keys, default=fmterror): def err(key): if default is fmterror: @@ -194,7 +208,11 @@ class session(object): def _jreq(self, *args, **kwargs): headers = kwargs.pop("headers", {}) headers["Accept"] = "application/json" - ret = self._req(*args, headers=headers, **kwargs) + try: + ret = self._req(*args, headers=headers, **kwargs) + except urllib.error.HTTPError as e: + if e.headers.get_content_type() == "application/json": + raise jsonerror.fromerr(e) return json.loads(ret.decode("utf-8")) def _postlogin(self): @@ -212,18 +230,23 @@ class session(object): 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, - "generateEasyLoginId": False}) - if data.get("status") != "USER_SIGN": - raise fmterror("unexpected bankid status: " + str(data.get("status"))) + try: + data = self._jreq("v5/identification/bankid/mobile", data = { + "userId": user, + "useEasyLogin": False, + "generateEasyLoginId": False}) + except jsonerror as e: + if e.code == 400: + flds = resolve(e.data, ("errorMessages", "fields"), False) + if isinstance(flds, list): + for fld in flds: + if resolve(fld, ("field",), None) == "userId": + raise autherror(fld["message"]) + raise + st = 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 in {"USER_SIGN", "CLIENT_NOT_STARTED"}: if st != fst: conv.message("Status: %s" % (st,), auth.conv.msg_info) @@ -234,8 +257,13 @@ class session(object): return elif st == "CANCELLED": raise autherror("authentication cancelled") + elif st == "OUTSTANDING_TRANSACTION": + raise autherror("another bankid transaction already in progress") else: raise fmterror("unexpected bankid status: " + str(st)) + time.sleep(3) + vdat = self._jreq(vfy) + st = vdat.get("status") def keepalive(self): data = self._jreq("v5/framework/clientsession")