Just trying to login jeez

This commit is contained in:
Carlos Sanchez 2023-04-30 21:58:02 -04:00
parent 2a0fbfe4a1
commit 94e203d1ba
2 changed files with 72 additions and 16 deletions

View File

@ -1,19 +1,17 @@
import requests
import logging
# Exception for 401 errors, meaning your token was bad (expired maybe?)
class AuthenticationError(Exception):
pass
""" Exception for 401 errors, meaning your token was bad (expired maybe?) """
# Exception for 400 errors, meaning you gave something funky to the API
# (maybe your search was malformed?)
class BadRequestError(Exception):
pass
"""Exception for 400 errors, meaning you gave something funky to the API
(maybe your search was malformed?) """
# Exception for 404 errors, meaning whatever you were looking for wasn't found
# (This is rare from the API)
class NotFoundError(Exception):
pass
"""Exception for 404 errors, meaning whatever you were looking for wasn't found
(This is rare from the API) """
# Your gateway to the static endpoints for contentapi. It's a context because it needs
# to track stuff like "which api am I contacting" and "which user am I authenticating as (if any)"
@ -22,16 +20,18 @@ class ApiContext:
# You MUST define the endpoint when creating the API context! You can optionally set
# the token on startup, or you can set it at any time. Set to a "falsey" value to
# to browse as an anonymous user
def __init__(self, endpoint, logger, token = False):
def __init__(self, endpoint: str, logger: logging.Logger, token = False):
self.endpoint = endpoint
self.logger = logger
self.token = token
# Generate the standard headers we use for most requests. You usually don't need to
# change anything here, just make sure your token is set if you want to be logged in
def gen_header(self, content_type = "application/json"):
headers = {
"Content-Type" : content_type
"Content-Type" : content_type,
"Accept" : content_type
}
if self.token:
headers["Authorization"] = "Bearer" + self.token
@ -43,18 +43,26 @@ class ApiContext:
if response.status_code == 200:
return response.json()
elif response.status_code == 400:
raise BadRequestError(format("Bad request: {}", response.content))
raise BadRequestError("Bad request: %s" % response.content)
elif response.status_code == 401:
raise AuthenticationError("Your token is bad!")
elif response.status_code == 404:
raise NotFoundError("Could not find content!")
else:
raise Exception(format("Unknown error ({}) - {}", response.status_code, response.content))
raise Exception("Unknown error (%s) - %s" % (response.status_code, response.content))
# Perform a standard get request and return the pre-parsed object (all contentapi endpoints
# return objects). Throws exception on error
def get(self, endpoint):
response = requests.get(self.endpoint + "/" + endpoint, headers = self.gen_header())
url = self.endpoint + "/" + endpoint
# self.logger.debug("GET: " + url) # Not necessary, DEBUG in requests does this
response = requests.get(url, headers = self.gen_header())
return self.parse_response(response)
def post(self, endpoint, data):
url = self.endpoint + "/" + endpoint
# self.logger.debug("POST: " + url)
response = requests.post(url, headers = self.gen_header(), json = data)
return self.parse_response(response)
# Connect to the API to determine if your token is still valid.
@ -62,6 +70,20 @@ class ApiContext:
try:
return self.token and self.get("user/me")
except Exception as ex:
self.logger.debug(format("Error from endpoint: {}", ex))
self.logger.debug("Error from endpoint: %s" % ex)
return False
# Basic login endpoint, should return your token on success
def login(self, username, password, expire_seconds = False):
data = {
"username" : username,
"password" : password
}
if expire_seconds:
data["expireSeconds"] = expire_seconds
return self.post("user/login", data)
# Get information about the API. Very useful to test your connection to the API
def api_status(self):
return self.get("status")

38
main.py
View File

@ -2,8 +2,10 @@
import os
import json
import logging
import contentapi
import toml
import getpass
import contentapi
import myutils
CONFIGFILE="config.toml"
@ -21,6 +23,9 @@ def main():
load_or_create_global_config()
logging.info("Config: " + json.dumps(config, indent = 2))
context = contentapi.ApiContext(config["api"], logging)
logging.info("Testing connection to API at " + config["api"])
logging.debug(json.dumps(context.api_status(), indent = 2))
authenticate(config, context)
print("Program end")
# Loads the config from file into the global config var. If the file
@ -29,7 +34,7 @@ def main():
def load_or_create_global_config():
global config
# Check if the config file exists
if os.path.exists(CONFIGFILE):
if os.path.isfile(CONFIGFILE):
# Read and deserialize the config file
with open(CONFIGFILE, 'r', encoding='utf-8') as f:
temp_config = toml.load(f)
@ -43,6 +48,35 @@ def load_or_create_global_config():
myutils.set_logging_level(config["default_loglevel"])
# Either pull the token from a file, or get the login from the command
# line if that doesn't work. WILL test your token against the real API
# even if it's pulled from file!
def authenticate(config, context: contentapi.ApiContext):
message = "No token file found"
if os.path.isfile(config["tokenfile"]):
with open(config["tokenfile"], 'r') as f:
token = f.read()
if context.is_token_valid():
context.token = token
logging.info("Logged in using token file " + config["tokenfile"])
return
else:
message = "Token file expired"
while True:
print(message + ", Please enter login for " + config["api"])
username = input("Username: ")
password = getpass.getpass("Password: ")
try:
token = context.login(username, password, config["expire_seconds"])
with open(config["tokenfile"], 'w') as f:
f.write(token)
logging.info("Token accepted, written to " + config["tokenfile"])
context.token = token
except Exception as ex:
print("ERROR: Could not login: %s" % ex)
# Because python reasons
if __name__ == "__main__":
main()