def login(return_to=None): if 'code' not in flask.request.values: if return_to is None: return_to = flask.request.values.get('return_to') flask.session['login_return_to'] = return_to if 'as' in flask.request.values: if flask.request.values['as'] not in SPECIAL_USERS: return utils.error_page("Not a recognised user name: %s" % flask.request.values['as']) scope = SPECIAL_USERS[flask.request.values['as']] else: scope = REQUEST_SCOPES # Generate a random nonce so we can verify that the user who comes back is the same user we sent away flask.session['login_nonce'] = uuid.uuid4().hex return flask.render_template("login.html", clientid=config["twitch_clientid"], scope=' '.join(scope), redirect_uri=REDIRECT_URI, nonce=flask.session['login_nonce'], session=load_session(include_url=False)) else: try: # Check that we're expecting the user to be logging in... expected_nonce = flask.session.pop('login_nonce', None) if not expected_nonce: raise Exception("Not expecting a login here") twitch_state = flask.request.values.get('state', '') # We have to pack the "remember me" flag into the state parameter we send via twitch, since that's where the form points... awkward if ':' in twitch_state: twitch_nonce, remember_me = twitch_state.split(':') remember_me = bool(int(remember_me)) else: # User didn't have JS turned on, so remember me option not available twitch_nonce = twitch_state remember_me = False if expected_nonce != twitch_nonce: raise Exception("Nonce mismatch: %s vs %s" % (expected_nonce, twitch_nonce)) # Call back to Twitch to get our access token oauth_params = { 'client_id': config["twitch_clientid"], 'client_secret': config["twitch_clientsecret"], 'grant_type': 'authorization_code', 'redirect_uri': REDIRECT_URI, 'code': flask.request.values['code'], } res_json = urllib.request.urlopen("https://api.twitch.tv/kraken/oauth2/token", urllib.parse.urlencode(oauth_params).encode()).read().decode() res_object = flask.json.loads(res_json) if not res_object.get('access_token'): raise Exception("No access token from Twitch: %s" % res_json) access_token = res_object['access_token'] granted_scopes = res_object["scope"] # Use that access token to get basic information about the user req = urllib.request.Request("https://api.twitch.tv/kraken/") req.add_header("Authorization", "OAuth %s" % access_token) res_json = urllib.request.urlopen(req).read().decode() res_object = flask.json.loads(res_json) if not res_object.get('token', {}).get('valid'): raise Exception("User object not valid: %s" % res_json) if not res_object.get('token', {}).get('user_name'): raise Exception("No user name from Twitch: %s" % res_json) user_name = res_object['token']['user_name'].lower() # If this is one of our special users, store the access_token in the bot # for future use # If one of our special users logged in *without* using the "as" flag, # Twitch *might* remember them and give us the same permissions anyway # but if not, then we don't have the permissions we need to do our thing # so bounce them back to the login page with the appropriate scopes. if user_name in SPECIAL_USERS: if any(i not in granted_scopes for i in SPECIAL_USERS[user_name]): server.app.logger.error("User %s has not granted us the required permissions" % user_name) flask.session['login_nonce'] = uuid.uuid4().hex return flask.render_template("login.html", clientid=config["twitch_clientid"], scope=' '.join(SPECIAL_USERS[user_name]), redirect_uri=REDIRECT_URI, nonce=flask.session['login_nonce'], session=load_session(include_url=False), special_user=user_name, remember_me=remember_me) from www import botinteract botinteract.set_data(["twitch_oauth", user_name], access_token) # Store the user name into the session # Note: we DON'T store the access_token in the session, as the session contents # are user-visible (for the default Flask implementation) and the token needs # to be kept secret. And we don't need it for anything other than verifying the # user name anyway, for non-special users. flask.session['user'] = user_name flask.session.permanent = remember_me return_to = flask.session.pop('login_return_to', None) return flask.render_template("login_response.html", success=True, return_to=return_to, session=load_session(include_url=False)) except: server.app.logger.exception("Exception in login") return flask.render_template("login_response.html", success=False, session=load_session(include_url=False))
def vote_submit(session): botinteract.set_data( ["shows", flask.request.values["show"], "games", flask.request.values["id"], "votes", session["user"]], bool(int(flask.request.values["vote"])), ) return flask.json.jsonify(success="OK", csrf_token=server.app.csrf_token())
def vote_submit(session): botinteract.set_data([ 'shows', flask.request.values['show'], 'games', flask.request.values['id'], 'votes', session['user'] ], bool(int(flask.request.values['vote']))) return flask.json.jsonify(success='OK', csrf_token=server.app.csrf_token())
def login(return_to=None): if 'code' not in flask.request.values: if return_to is None: return_to = flask.request.values.get('return_to') flask.session['login_return_to'] = return_to if 'as' in flask.request.values: if flask.request.values['as'] not in SPECIAL_USERS: return utils.error_page("Not a recognised user name: %s" % flask.request.values['as']) scope = SPECIAL_USERS[flask.request.values['as']] else: scope = REQUEST_SCOPES # Generate a random nonce so we can verify that the user who comes back is the same user we sent away flask.session['login_nonce'] = uuid.uuid4().hex return flask.render_template("login.html", clientid=config["twitch_clientid"], scope=' '.join(scope), redirect_uri=REDIRECT_URI, nonce=flask.session['login_nonce'], session=load_session(include_url=False)) else: try: # Check that we're expecting the user to be logging in... expected_nonce = flask.session.pop('login_nonce', None) if not expected_nonce: raise Exception("Not expecting a login here") twitch_state = flask.request.values.get('state', '') # We have to pack the "remember me" flag into the state parameter we send via twitch, since that's where the form points... awkward if ':' in twitch_state: twitch_nonce, remember_me = twitch_state.split(':') remember_me = bool(int(remember_me)) else: # User didn't have JS turned on, so remember me option not available twitch_nonce = twitch_state remember_me = False if expected_nonce != twitch_nonce: raise Exception("Nonce mismatch: %s vs %s" % (expected_nonce, twitch_nonce)) # Call back to Twitch to get our access token oauth_params = { 'client_id': config["twitch_clientid"], 'client_secret': config["twitch_clientsecret"], 'grant_type': 'authorization_code', 'redirect_uri': REDIRECT_URI, 'code': flask.request.values['code'], } res_json = urllib.request.urlopen( "https://api.twitch.tv/kraken/oauth2/token", urllib.parse.urlencode(oauth_params).encode()).read().decode() res_object = flask.json.loads(res_json) if not res_object.get('access_token'): raise Exception("No access token from Twitch: %s" % res_json) access_token = res_object['access_token'] granted_scopes = res_object["scope"] # Use that access token to get basic information about the user req = urllib.request.Request("https://api.twitch.tv/kraken/") req.add_header("Authorization", "OAuth %s" % access_token) res_json = urllib.request.urlopen(req).read().decode() res_object = flask.json.loads(res_json) if not res_object.get('token', {}).get('valid'): raise Exception("User object not valid: %s" % res_json) if not res_object.get('token', {}).get('user_name'): raise Exception("No user name from Twitch: %s" % res_json) user_name = res_object['token']['user_name'].lower() # If this is one of our special users, store the access_token in the bot # for future use # If one of our special users logged in *without* using the "as" flag, # Twitch *might* remember them and give us the same permissions anyway # but if not, then we don't have the permissions we need to do our thing # so bounce them back to an error page. if user_name in SPECIAL_USERS: if any(i not in granted_scopes for i in SPECIAL_USERS[user_name]): server.app.logger.error( "User %s has not granted us the required permissions" % user_name) return flask.render_template( "login_response.html", success=False, special_user=user_name, session=load_session(include_url=False)) from www import botinteract botinteract.set_data(["twitch_oauth", user_name], access_token) # Store the user name into the session # Note: we DON'T store the access_token in the session, as the session contents # are user-visible (for the default Flask implementation) and the token needs # to be kept secret. And we don't need it for anything other than verifying the # user name anyway, for non-special users. flask.session['user'] = user_name flask.session.permanent = remember_me return_to = flask.session.pop('login_return_to', None) return flask.render_template( "login_response.html", success=True, return_to=return_to, session=load_session(include_url=False)) except: server.app.logger.exception("Exception in login") return flask.render_template( "login_response.html", success=False, session=load_session(include_url=False))