コード例 #1
0
ファイル: login.py プロジェクト: warandpeace/lrrbot
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))
コード例 #2
0
ファイル: votes.py プロジェクト: warandpeace/lrrbot
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())
コード例 #3
0
ファイル: votes.py プロジェクト: keab42/lrrbot
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())
コード例 #4
0
ファイル: login.py プロジェクト: keab42/lrrbot
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))