X-Git-Url: http://dolda2000.com/gitweb/?p=fulbank.git;a=blobdiff_plain;f=fulbank%2Ffsb.py;h=834536af7e3e2b9f55863b165a33751f44076886;hp=2b9ce7e1ebadc9e4e14e970460fd83d1d02424e2;hb=f99c3f74981b17803a3b4beb5f186008e188fa36;hpb=d791f2f2551b646668b24de95afffbf03c5dbc88 diff --git a/fulbank/fsb.py b/fulbank/fsb.py index 2b9ce7e..834536a 100644 --- a/fulbank/fsb.py +++ b/fulbank/fsb.py @@ -1,7 +1,7 @@ -import json, http.cookiejar, binascii, time, datetime, pickle, hashlib +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 +from . import currency, auth, data soupify = lambda cont: soup(cont, "html.parser") apibase = "https://online.swedbank.se/TDE_DAP_Portal_REST_WEB/api/" @@ -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: @@ -52,7 +66,7 @@ def getdsid(): def base64(data): return binascii.b2a_base64(data).decode("ascii").strip().rstrip("=") -class transaction(object): +class transaction(data.transaction): def __init__(self, account, data): self.account = account self._data = data @@ -68,19 +82,7 @@ class transaction(object): p = time.strptime(resolve(self._data, ("accountingDate",)), self._datefmt) return datetime.date(p.tm_year, p.tm_mon, p.tm_mday) - @property - def hash(self): - dig = hashlib.sha256() - dig.update(str(self.date.toordinal()).encode("ascii") + b"\0") - dig.update(self.message.encode("utf-8") + b"\0") - dig.update(str(self.value.amount).encode("ascii") + b"\0") - dig.update(self.value.currency.symbol.encode("ascii") + b"\0") - return dig.hexdigest() - - def __repr__(self): - return "#" % (self.value, self.message) - -class txnaccount(object): +class txnaccount(data.txnaccount): def __init__(self, sess, id, idata): self.sess = sess self.id = id @@ -116,10 +118,7 @@ class txnaccount(object): yield transaction(self, tx) page += 1 - def __repr__(self): - return "#" % (self.fullnumber, self.name) - -class cardtransaction(object): +class cardtransaction(data.transaction): def __init__(self, account, data): self.account = account self._data = data @@ -137,19 +136,7 @@ class cardtransaction(object): p = time.strptime(resolve(self._data, ("date",)), self._datefmt) return datetime.date(p.tm_year, p.tm_mon, p.tm_mday) - @property - def hash(self): - dig = hashlib.sha256() - dig.update(str(self.date.toordinal()).encode("ascii") + b"\0") - dig.update(self.message.encode("utf-8") + b"\0") - dig.update(str(self.value.amount).encode("ascii") + b"\0") - dig.update(self.value.currency.symbol.encode("ascii") + b"\0") - return dig.hexdigest() - - def __repr__(self): - return "#" % (self.value, self.message) - -class cardaccount(object): +class cardaccount(data.cardaccount): def __init__(self, sess, id, idata): self.sess = sess self.id = id @@ -183,9 +170,6 @@ class cardaccount(object): yield cardtransaction(self, tx) page += 1 - def __repr__(self): - return "#" % (self.fullnumber, self.name) - class session(object): def __init__(self, dsid): self.dsid = dsid @@ -224,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): @@ -242,10 +230,19 @@ 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}) + 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 if data.get("status") != "USER_SIGN": raise fmterror("unexpected bankid status: " + str(data.get("status"))) vfy = linkurl(resolve(data, ("links", "next", "uri")))