def init_game(self): self.game = get_day_game() self.letters = get_letters(16, random_seed=self.game) self.act_letters = [False for _ in range(16)] self.last_pos = None self.played = False self.state = State.PLAY game = storage.get_value("game") if game == self.game: # Game in progress self.score = storage.get_value("score") self.countdown = storage.get_value("countdown") self.guesses = storage.get_guesses() self.word_counts = storage.get_word_counts() self.area_content = storage.get_area() else: # A new game self.score = 0 storage.set_value("score", self.score) self.countdown = 180 storage.set_value("countdown", self.countdown) self.guesses = [] storage.set_guesses(self.guesses) self.word_counts = [0 for i in range(6)] storage.set_word_counts(self.word_counts) self.area_content = "" storage.set_value("area", self.area_content)
def home_get(): """ Endpoint for the homepage """ cookie = request.cookies.get('session') if cookie is None or cookie != util.get_session_cookie(): return render_template("start.html") config = bunq.retrieve_config() bunqkeymode = config.get("mode") iftttkeyset = (util.get_ifttt_service_key("") is not None) accounts = util.get_bunq_accounts_with_permissions(config) enableexternal = util.get_external_payment_enabled() bunq_oauth = storage.get_value("bunq2IFTTT", "bunq_oauth") if bunq_oauth is not None and bunqkeymode != "APIkey": expire = arrow.get(bunq_oauth["timestamp"] + 90 * 24 * 3600) oauth_expiry = "{} ({})".format(expire.humanize(), expire.isoformat()) else: oauth_expiry = None # Google AppEngine does not provide fixed ip addresses defaultallips = (os.getenv("GAE_INSTANCE") is not None) return render_template("main.html",\ iftttkeyset=iftttkeyset, bunqkeymode=bunqkeymode, accounts=accounts,\ enableexternal=enableexternal, defaultallips=defaultallips,\ oauth_expiry=oauth_expiry)
def check_state(self): game = storage.get_value("game") if not game: # User never played tort.ooo before self.about() elif self.countdown == 0: # User already played today self.state = State.GAME_OVER self.game_over() storage.set_value("game", self.game)
def bunq_oauth_reauthorize(): """ Reauthorize OAuth using the same client id/secret """ oauthdata = storage.get_value("bunq2IFTTT", "bunq_oauth") storage.store_large("bunq2IFTTT", "bunq_oauth_new", oauthdata) redirect_url = request.url_root + "auth" url = "https://oauth.bunq.com/auth?response_type=code"\ "&client_id=" + oauthdata["client_id"] + \ "&redirect_uri=" + redirect_url return render_template("message.html", msgtype="primary", msg=\ "Make sure the following URL is included as a redirect url:"\ "<br><br><b>" + redirect_url + "</b><br><br>"\ 'Then click <a href="' + url + '">this link</a>')
def trigger_oauth_expires(): """ Callback for IFTTT trigger bunq_oauth_expires """ try: data = request.get_json() print("[trigger_oauthexp] input: {}".format(json.dumps(data))) if "triggerFields" not in data or \ "hours" not in data["triggerFields"]: print("[trigger_oauthexp] ERROR: hours field missing!") return json.dumps({"errors": [{"message": "Invalid data"}]}), 400 hours = data["triggerFields"]["hours"] if "trigger_identity" not in data: print("[trigger_oauthexp] ERROR: trigger_identity field missing!") return json.dumps({"errors": [{"message": "Invalid data"}]}), 400 limit = 50 if "limit" in data: limit = data["limit"] if hours == "9876543210": return trigger_oauth_expires_test(limit) timezone = "UTC" if "user" in data and "timezone" in data["user"]: timezone = data["user"]["timezone"] transactions = [] value = storage.get_value("bunq2IFTTT", "bunq_oauth") if value is not None: timestamp = value["timestamp"] + 3600 * (90 * 24 - int(hours)) if timestamp <= time.time(): transactions = [{ "created_at": arrow.get(timestamp)\ .to(timezone).isoformat(), "expires_at": arrow.get(value["timestamp"] + 90*24*3600)\ .to(timezone).isoformat(), "meta": { "id": str(timestamp), "timestamp": str(timestamp), } }] print("[trigger_oauthexp] Found {} transactions".format( len(transactions))) return json.dumps({"data": transactions[:limit]}) except Exception: traceback.print_exc() print("[trigger_oauthexp] ERROR: cannot retrieve oauth expiry data") return json.dumps({"errors": [{"message": \ "Cannot retrieve oauth expiry data"}]}), 400
def set_bunq_oauth_response(): """ Handles the bunq OAuth redirect """ try: oauthdata = storage.get_value("bunq2IFTTT", "bunq_oauth_new") code = request.args["code"] if len(code) != 64: print("Invalid code: ", code) return render_template("message.html", msgtype="danger", msg=\ 'Invalid code! <br><br>'\ '<a href="/">Click here to try again</a>') url = "https://api.oauth.bunq.com/v1/token?grant_type="\ "authorization_code&code={}&redirect_uri={}"\ "&client_id={}&client_secret={}"\ .format(code, request.url_root + "auth", oauthdata["client_id"], oauthdata["client_secret"]) req = requests.post(url) key = req.json()["access_token"] oauthdata["timestamp"] = int(time.time()) oauthdata["triggers"] = [] storage.store_large("bunq2IFTTT", "bunq_oauth", oauthdata) config = bunq.install(key, allips=oauthdata["allips"], urlroot=request.url_root, mode="OAuth") util.sync_permissions(config) bunq.save_config(config) return render_template("message.html", msgtype="success", msg=\ 'OAuth successfully setup <br><br>'\ '<a href="/">Click here to return home</a>') except Exception: traceback.print_exc() return render_template("message.html", msgtype="danger", msg=\ 'An unknown exception occurred. See the logs. <br><br>'\ '<a href="/">Click here to return home</a>')
def retrieve_config(config={}): """ Retrieve the configuration parameters from storage """ for key in list(config.keys()): del config[key] toload = storage.get_value("bunq2IFTTT", "bunq_config") if toload is not None: for key in toload: config[key] = toload[key] # Convert strings back to keys if "server_key_enc" in config: config["server_key"] = serialization.load_pem_public_key( config["server_key_enc"].encode("ascii"), backend=default_backend()) if "public_key_enc" in config: config["public_key"] = serialization.load_pem_public_key( config["public_key_enc"].encode("ascii"), backend=default_backend()) if "private_key_enc" in config: config["private_key"] = serialization.load_pem_private_key( config["private_key_enc"].encode("ascii"), password=None, backend=default_backend()) return config
def trigger_request(): """ Callback for IFTTT trigger bunq_request """ try: data = request.get_json() print("[trigger_request] input: {}".format(json.dumps(data))) if "triggerFields" not in data or \ "account" not in data["triggerFields"]: print("[trigger_request] ERROR: account field missing!") return json.dumps({"errors": [{"message": "Invalid data"}]}), 400 account = data["triggerFields"]["account"] fields = data["triggerFields"] fieldsstr = json.dumps(fields) if "trigger_identity" not in data: print("[trigger_request] ERROR: trigger_identity field missing!") return json.dumps({"errors": [{"message": "Invalid data"}]}), 400 identity = data["trigger_identity"] limit = 50 if "limit" in data: limit = data["limit"] if account == "NL42BUNQ0123456789": return trigger_request_test(limit) timezone = "UTC" if "user" in data and "timezone" in data["user"]: timezone = data["user"]["timezone"] entity = storage.retrieve("trigger_request", identity) if entity is not None: if entity["account"] != account or \ json.dumps(entity["fields"]) != fieldsstr: storage.store("trigger_request", identity, { "account": account, "identity": identity, "fields": fields }) print("[trigger_request] updating trigger {} {}".format( account, fieldsstr)) else: storage.store("trigger_request", identity, { "account": account, "identity": identity, "fields": fields }) print("[trigger_request] storing new trigger {} {}".format( account, fieldsstr)) transactions = storage.get_value("trigger_request", identity + "_t") if transactions is None: transactions = [] for trans in transactions: trans["created_at"] = arrow.get(trans["created_at"])\ .to(timezone).isoformat() print("[trigger_request] Found {} transactions".format( len(transactions))) return json.dumps({"data": transactions[:limit]}) except Exception: traceback.print_exc() print("[trigger_request] ERROR: cannot retrieve requests") return json.dumps({"errors": [{"message": \ "Cannot retrieve requests"}]}), 400