def spotify_auth(): try: resp = spotify.authorized_response(spotify=True) except OAuthException as e: log.error(e) log.exception("An exception was caught while authorizing") next_url = get_next_url(request, "state") return redirect(next_url) except Exception as e: log.error(e) log.exception("Unhandled exception while authorizing") return render_template("login_error.html") session["spotify_token"] = (resp["access_token"], ) if resp is None: if "error" in request.args and "error_description" in request.args: log.warning( f"Access denied: reason={request.args['error']}, error={request.args['error_description']}" ) next_url = get_next_url(request, "state") return redirect(next_url) elif type(resp) is OAuthException: log.warning(resp.message) log.warning(resp.data) log.warning(resp.type) next_url = get_next_url(request, "state") return redirect(next_url) data = f'{app.bot_config["spotify"]["client_id"]}:{app.bot_config["spotify"]["client_secret"]}' encoded = str(base64.b64encode(data.encode("utf-8")), "utf-8") headers = {"Authorization": f"Basic {encoded}"} me_api_response = spotify.get("me", headers=headers) redis = RedisManager.get() token_json = UserAccessToken.from_api_response(resp).jsonify() redis.set( f"authentication:spotify-access-token:{me_api_response.data['id']}", json.dumps(token_json)) redis.set( f"authentication:user-refresh-token:{me_api_response.data['id']}", token_json["refresh_token"]) log.info( f"Successfully updated spotify token in redis for user {me_api_response.data['id']}" ) next_url = get_next_url(request, "state") return redirect(next_url)
def refresh_user_access_token(self, refresh_token): response = self.post( "/oauth2/token", { "client_id": self.client_credentials.client_id, "client_secret": self.client_credentials.client_secret, "grant_type": "refresh_token", "refresh_token": refresh_token, }, ) # response = # { # "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxx", # "expires_in": 14346, # "refresh_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # "scope": [ # "user:read:email" # ], # "token_type": "bearer" # } return UserAccessToken.from_api_response(response)
def get_user_access_token(self, code): response = self.post( "/oauth2/token", { "client_id": self.client_credentials.client_id, "client_secret": self.client_credentials.client_secret, "code": code, "redirect_uri": self.client_credentials.redirect_uri, "grant_type": "authorization_code", }, ) # response = # { # "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxx" # "expires_in": 14310, # "refresh_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # "scope": [ # "user:read:email" # ], # "token_type": "bearer" # } return UserAccessToken.from_api_response(response)
def authorized(): try: resp = twitch.authorized_response() except OAuthException as e: log.error(e) log.exception("An exception was caught while authorizing") next_url = get_next_url(request, "state") return redirect(next_url) except Exception as e: log.error(e) log.exception("Unhandled exception while authorizing") return render_template("login_error.html") if resp is None: if "error" in request.args and "error_description" in request.args: log.warning(f"Access denied: reason={request.args['error']}, error={request.args['error_description']}") next_url = get_next_url(request, "state") return redirect(next_url) elif type(resp) is OAuthException: log.warning(resp.message) log.warning(resp.data) log.warning(resp.type) next_url = get_next_url(request, "state") return redirect(next_url) session["twitch_token"] = (resp["access_token"],) session["twitch_token_expire"] = time.time() + resp["expires_in"] * 0.75 me_api_response = twitch.get("users") if len(me_api_response.data["data"]) < 1: return render_template("login_error.html") with DBManager.create_session_scope(expire_on_commit=False) as db_session: me = User.from_basics( db_session, UserBasics( me_api_response.data["data"][0]["id"], me_api_response.data["data"][0]["login"], me_api_response.data["data"][0]["display_name"], ), ) session["user"] = me.jsonify() # bot login if me.login == app.bot_config["main"]["nickname"].lower(): redis = RedisManager.get() token_json = UserAccessToken.from_api_response(resp).jsonify() redis.set(f"authentication:user-access-token:{me.id}", json.dumps(token_json)) log.info("Successfully updated bot token in redis") # streamer login if me.login == app.bot_config["main"]["streamer"].lower(): # there's a good chance the streamer will later log in using the normal login button. # we only update their access token if the returned scope containes the special scopes requested # in /streamer_login # We use < to say "if the granted scope is a proper subset of the required scopes", this can be case # for example when the bot is running in its own channel and you use /bot_login, # then the granted scopes will be a superset of the scopes needed for the streamer. # By doing this, both the streamer and bot token will be set if you complete /bot_login with the bot # account, and if the bot is running in its own channel. if set(resp["scope"]) < set(streamer_scopes): log.info("Streamer logged in but not all scopes present, will not update streamer token") else: redis = RedisManager.get() token_json = UserAccessToken.from_api_response(resp).jsonify() redis.set(f"authentication:user-access-token:{me.id}", json.dumps(token_json)) log.info("Successfully updated streamer token in redis") next_url = get_next_url(request, "state") return redirect(next_url)
def authorized(): try: resp = twitch.authorized_response() except OAuthException: log.exception("An exception was caught while authorizing") next_url = get_next_url(request, "state") return redirect(next_url) except: log.exception("Unhandled exception while authorizing") return render_template("login_error.html") if resp is None: if "error" in request.args and "error_description" in request.args: log.warning("Access denied: reason={}, error={}".format( request.args["error"], request.args["error_description"])) next_url = get_next_url(request, "state") return redirect(next_url) elif type(resp) is OAuthException: log.warning(resp.message) log.warning(resp.data) log.warning(resp.type) next_url = get_next_url(request, "state") return redirect(next_url) session["twitch_token"] = (resp["access_token"], ) me = twitch.get("user", headers={"Accept": "application/vnd.twitchtv.v5+json"}) level = 100 with DBManager.create_session_scope() as db_session: db_user = db_session.query(User).filter_by( username=me.data["name"].lower()).one_or_none() if db_user: level = db_user.level session["user"] = { "username": me.data["name"], "username_raw": me.data["display_name"], "level": level } if me.data["name"].lower() == app.bot_config["main"]["nickname"].lower( ): redis = RedisManager.get() bot_id = me.data["_id"] token_json = UserAccessToken.from_api_response(resp).jsonify() redis.set("authentication:user-access-token:{}".format(bot_id), json.dumps(token_json)) log.info("Successfully updated bot token in redis") # streamer login if me.data["name"].lower() == app.bot_config["main"]["streamer"].lower( ): # there's a good chance the streamer will later log in using the normal login button. # we only update their access token if the returned scope containes the special scopes requested # in /streamer_login if set(resp["scope"]) != set(streamer_scopes): log.info( "Streamer logged in but not all scopes present, will not update streamer token" ) else: redis = RedisManager.get() streamer_id = me.data["_id"] token_json = UserAccessToken.from_api_response(resp).jsonify() redis.set( "authentication:user-access-token:{}".format(streamer_id), json.dumps(token_json)) log.info("Successfully updated streamer token in redis") next_url = get_next_url(request, "state") return redirect(next_url)