X-Git-Url: http://dolda2000.com/gitweb/?p=fulbank.git;a=blobdiff_plain;f=fulbank%2Ffsb.py;h=8f6280c0e3237bc1cadba287751db7f18afaf94a;hp=145de7b3364c5dba8d7c13c871d08692cefac0d6;hb=HEAD;hpb=3851cd1b9f5e758d8d22bb51c0dde9624d05e9d9 diff --git a/fulbank/fsb.py b/fulbank/fsb.py index 145de7b..7a4a4a8 100644 --- a/fulbank/fsb.py +++ b/fulbank/fsb.py @@ -1,4 +1,5 @@ -import json, http.cookiejar, binascii, time, datetime, pickle, urllib.error +import json, http.cookiejar, binascii, time, datetime, pickle, urllib.error, io +from PIL import Image from urllib import request, parse from bs4 import BeautifulSoup as soup from . import currency, auth, data @@ -170,7 +171,7 @@ class cardaccount(data.cardaccount): yield cardtransaction(self, tx) page += 1 -class session(object): +class session(data.session): def __init__(self, dsid): self.dsid = dsid self.auth = base64((serviceid + ":" + str(int(time.time() * 1000))).encode("ascii")) @@ -227,6 +228,46 @@ class session(object): rolesw = linkurl(resolve(prof["banks"][0], ("privateProfile", "links", "next", "uri"))) self._jreq(rolesw, method="POST") + def auth_token(self, user, conv=None): + if conv is None: + conv = auth.default() + try: + data = self._jreq("v5/identification/securitytoken/challenge", 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("useOneTimePassword"): + raise fmterror("unexpectedly found useOneTimePassword") + if data.get("challenge") != "": + raise fmterror("unexpected challenge: " + str(data.get("challenge"))) + if not isinstance(data.get("imageChallenge"), dict) or resolve(data, ("imageChallenge", "method")) != "GET": + raise fmterror("invalid image challenge: " + str(data.get("imageChallenge"))) + iurl = linkurl(resolve(data, ("imageChallenge", "uri"))) + vfy = linkurl(resolve(data, ("links", "next", "uri"))) + img = Image.open(io.BytesIO(self._req(iurl))) + conv.image(img) + response = conv.prompt("Token response: ", True) + try: + data = self._jreq(vfy, data={"response": response}) + except jsonerror as e: + msgs = resolve(e.data, ("errorMessages", "general"), False) + if isinstance(msgs, list): + for msg in msgs: + if msg.get("message"): + raise autherror(msg.get("message")) + raise + if not data.get("authenticationRole", ""): + raise fmterror("authentication appears to have succeded, but there is no authenticationRole: " + str(data)) + self._postlogin() + def auth_bankid(self, user, conv=None): if conv is None: conv = auth.default() @@ -271,11 +312,12 @@ class session(object): @property def accounts(self): if self._accounts is None: - data = self._jreq("v5/engagement/overview") + txndata = self._jreq("v5/engagement/overview") + crddata = self._jreq("v5/card/creditcard") accounts = [] - for acct in resolve(data, ("transactionAccounts",)): + for acct in resolve(txndata, ("transactionAccounts",)): accounts.append(txnaccount(self, resolve(acct, ("id",)), acct)) - for acct in resolve(data, ("cardAccounts",)): + for acct in resolve(crddata, ("cardAccounts",)): accounts.append(cardaccount(self, resolve(acct, ("id",)), acct)) self._accounts = accounts return self._accounts @@ -289,6 +331,18 @@ class session(object): self.logout() self._req("v5/framework/clientsession", method="DELETE") + def __getstate__(self): + state = dict(self.__dict__) + state["jar"] = list(state["jar"].cookiejar) + return state + + def __setstate__(self, state): + jar = request.HTTPCookieProcessor() + for cookie in state["jar"]: + jar.cookiejar.set_cookie(cookie) + state["jar"] = jar + self.__dict__.update(state) + def __enter__(self): return self @@ -304,12 +358,3 @@ class session(object): @classmethod def create(cls): return cls(getdsid()) - - def save(self, filename): - with open(filename, "wb") as fp: - pickle.dump(self, fp) - - @classmethod - def load(cls, filename): - with open(filename, "rb") as fp: - return pickle.load(fp)