implement cookie support
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
venv/
|
||||
__pycache__/
|
||||
.env
|
||||
*.db
|
||||
*.db
|
||||
cookies.txt
|
118
vrcapi.py
118
vrcapi.py
@@ -1,16 +1,55 @@
|
||||
import os
|
||||
import logging
|
||||
import vrchatapi
|
||||
from vrchatapi.api import authentication_api, groups_api
|
||||
from vrchatapi import ApiClient as _ApiClient
|
||||
from vrchatapi import GroupsApi, Configuration, AuthenticationApi
|
||||
from http.cookiejar import LWPCookieJar
|
||||
from vrchatapi.exceptions import UnauthorizedException, ApiException
|
||||
from vrchatapi.models.two_factor_auth_code import TwoFactorAuthCode
|
||||
from vrchatapi.models.two_factor_email_code import TwoFactorEmailCode
|
||||
from totp import get_totp
|
||||
|
||||
# Modded ApiClient with cookie support
|
||||
# Credit: Katsi on the VRC API Community Discord
|
||||
class ApiClient(_ApiClient):
|
||||
def save_cookies(self):
|
||||
# validate env variable and create cookie jar
|
||||
filename = os.getenv("COOKIE_FILE")
|
||||
if filename is not None:
|
||||
cookie_jar = LWPCookieJar(filename=filename)
|
||||
else:
|
||||
raise ValueError("COOKIE_FILE env variable not set")
|
||||
# load cookies from API client into memory
|
||||
for cookie in self.rest_client.cookie_jar:
|
||||
cookie_jar.set_cookie(cookie)
|
||||
|
||||
# save cookies
|
||||
logging.info("Attempting to save cookies")
|
||||
cookie_jar.save()
|
||||
|
||||
def load_cookies(self):
|
||||
# validate env variable and create cookie jar
|
||||
filename = os.getenv("COOKIE_FILE")
|
||||
if filename is not None:
|
||||
cookie_jar = LWPCookieJar(filename=filename)
|
||||
else:
|
||||
raise ValueError("COOKIE_FILE env variable not set")
|
||||
|
||||
# load existing cookies if possible, else create a new cookie jar
|
||||
try:
|
||||
logging.info("Attempting to load cookies")
|
||||
cookie_jar.load()
|
||||
except FileNotFoundError:
|
||||
logging.info("Attempting to save cookies")
|
||||
cookie_jar.save()
|
||||
return
|
||||
# transfer cookies from our session
|
||||
for cookie in cookie_jar:
|
||||
self.rest_client.cookie_jar.set_cookie(cookie)
|
||||
|
||||
def get_group_instances():
|
||||
group_instances = []
|
||||
|
||||
configuration = vrchatapi.Configuration(
|
||||
configuration = Configuration(
|
||||
# Get username/password from env variables
|
||||
username = os.getenv("USER_NAME"),
|
||||
password = os.getenv("USER_PASSWORD"),
|
||||
@@ -18,57 +57,56 @@ def get_group_instances():
|
||||
|
||||
group_id = os.getenv("GROUP_ID")
|
||||
|
||||
with vrchatapi.ApiClient(configuration) as api_client:
|
||||
with ApiClient(configuration) as api_client:
|
||||
# Set our User-Agent as per VRChat Usage Policy and call the Auth API
|
||||
api_client.user_agent = "GroupInstanceLogger/0.1alpha me@williamtpeebles.com"
|
||||
auth_api = authentication_api.AuthenticationApi(api_client)
|
||||
|
||||
# Attempt to load cookies
|
||||
api_client.load_cookies()
|
||||
|
||||
auth_api = AuthenticationApi(api_client)
|
||||
|
||||
try:
|
||||
# Calling getCurrentUser on Authentication API logs you in if the user isn't already logged in.
|
||||
current_user = auth_api.get_current_user()
|
||||
api_client.save_cookies() # Save cookies after successful login
|
||||
except UnauthorizedException as e:
|
||||
handle_auth_exception(auth_api, e)
|
||||
current_user = auth_api.get_current_user()
|
||||
handle_auth_exception(auth_api, e)
|
||||
current_user = auth_api.get_current_user()
|
||||
api_client.save_cookies() # Save cookies after successful login
|
||||
|
||||
# Call groups APIs
|
||||
groups_api_instance = vrchatapi.GroupsApi(api_client)
|
||||
|
||||
try:
|
||||
api_response = groups_api_instance.get_group_instances(group_id) # Get group
|
||||
for instance in api_response:
|
||||
group_instances.append(instance)
|
||||
return group_instances
|
||||
except ApiException as e:
|
||||
print("Exception when calling GroupsApi->get_group: %s\n" % e)
|
||||
logging.info(f"Logged in as: {current_user.display_name}")
|
||||
|
||||
try:
|
||||
api_response = groups_api.GroupsApi(api_client),get_group_instances(group_id)
|
||||
group_instances.extend(api_response)
|
||||
except ApiException as e:
|
||||
logging.error(f"Exception when calling GroupsApi->get_group_instances: {e}")
|
||||
except Exception as e:
|
||||
logging.error(f"Unexpected Error: {e}")
|
||||
return group_instances
|
||||
# Call groups APIs
|
||||
groups_api_instance = GroupsApi(api_client)
|
||||
|
||||
|
||||
try:
|
||||
api_response = groups_api_instance.get_group_instances(group_id) # Get group instances
|
||||
for instance in api_response:
|
||||
group_instances.append(instance)
|
||||
except ApiException as e:
|
||||
logging.error(f"Exception when calling GroupsApi->get_group_instances: {e}")
|
||||
except Exception as e:
|
||||
logging.error(f"Unexpected Error: {e}")
|
||||
|
||||
return group_instances
|
||||
|
||||
def handle_auth_exception(auth_api, e):
|
||||
if e.status == 200:
|
||||
if "Email 2 Factor Authentication" in e.reason:
|
||||
# Calling email verify2fa if the account has 2FA disabled, give warning that automatic runs cannot be done
|
||||
logging.warning("IMPORTANT: Your VRChat Account is only enabled for **email** based 2-factor authentication! "
|
||||
"You will not be able to automate runs of GroupInstanceLogger\n"
|
||||
"Set up your account to use TOTP-based 2FA so the application can log you in automatically\n\n")
|
||||
auth_api.verify2_fa_email_code(two_factor_email_code=TwoFactorEmailCode(input("Email 2FA Code: ")))
|
||||
# Calling email verify2fa if the account has 2FA disabled, give warning that automatic runs cannot be done
|
||||
logging.warning("IMPORTANT: Your VRChat Account is only enabled for **email** based 2-factor authentication! "
|
||||
"You will not be able to automate runs of GroupInstanceLogger\n"
|
||||
"Set up your account to use TOTP-based 2FA so the application can log you in automatically\n\n")
|
||||
auth_api.verify2_fa_email_code(two_factor_email_code=TwoFactorEmailCode(input("Email 2FA Code: ")))
|
||||
elif "2 Factor Authentication" in e.reason:
|
||||
# Check if TOTP code is defined in env variables
|
||||
totp_key = os.getenv("TOTP_KEY")
|
||||
if totp_key:
|
||||
logging.info("Attempting to authenticate with defined TOTP key")
|
||||
auth_api.verify2_fa(two_factor_auth_code=TwoFactorAuthCode(get_totp()))
|
||||
else:
|
||||
logging.info("No TOTP key defined, prompting manual input of 2FA code")
|
||||
auth_api.verify2_fa(two_factor_auth_code=TwoFactorAuthCode(input("Enter 2FA Code: ")))
|
||||
# Check if TOTP code is defined in env variables
|
||||
totp_key = os.getenv("TOTP_KEY")
|
||||
if totp_key:
|
||||
logging.info("Attempting to authenticate with defined TOTP key")
|
||||
auth_api.verify2_fa(two_factor_auth_code=TwoFactorAuthCode(get_totp()))
|
||||
else:
|
||||
logging.info("No TOTP key defined, prompting manual input of 2FA code")
|
||||
auth_api.verify2_fa(two_factor_auth_code=TwoFactorAuthCode(input("Enter 2FA Code: ")))
|
||||
else:
|
||||
logging.error(f"UnauthorizedException: {e}")
|
||||
logging.error(f"UnauthorizedException: {e}")
|
||||
|
Reference in New Issue
Block a user