Skip to content

Commit

Permalink
save sessionid, and recreate session based on this id, w/o new login
Browse files Browse the repository at this point in the history
  • Loading branch information
bbirnbach committed Nov 27, 2024
1 parent db7fbbd commit 2420064
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 19 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,7 @@ cython_debug/
*creds.sec*

# test
test/
test/

#vscode
.history
27 changes: 17 additions & 10 deletions custom_components/homeassistantedupage/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import logging
import asyncio
from datetime import datetime, timedelta
from edupage_api.exceptions import BadCredentialsException, CaptchaException
from edupage_api import Edupage as EdupageApi
from edupage_api.exceptions import BadCredentialsException, CaptchaException, SecondFactorFailedException
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.const import Platform
Expand All @@ -11,7 +12,8 @@
from edupage_api.people import EduTeacher
from edupage_api.people import Gender
from edupage_api.classrooms import Classroom
from .const import DOMAIN
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from .const import DOMAIN, CONF_PHPSESSID, CONF_SUBDOMAIN, CONF_STUDENT_ID, CONF_STUDENT_NAME

_LOGGER = logging.getLogger("custom_components.homeassistant_edupage")

Expand All @@ -20,22 +22,27 @@ async def async_setup(hass: HomeAssistant, config: dict) -> bool:
_LOGGER.debug("INIT called async_setup")
return True

def login_wrapper(edupage: Edupage, username: str, password: str, subdomain: str):
#TODO hier ist noch was unsauber bzgl async und await
edupage.login(username=username, password=password, subdomain=subdomain)

async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""initializin EduPage-integration and validate API-login"""
_LOGGER.debug("INIT called async_setup_entry")
if DOMAIN not in hass.data:
hass.data[DOMAIN] = {}

username = entry.data["username"]
password = entry.data["password"]
subdomain = entry.data["subdomain"]
student_id = entry.data["student_id"]
edupage = Edupage(hass)
username = entry.data[CONF_USERNAME]
password = entry.data[CONF_PASSWORD]
subdomain = entry.data[CONF_SUBDOMAIN]
PHPSESSID = entry.data[CONF_PHPSESSID]
student_id = entry.data[CONF_STUDENT_ID]
edupage = Edupage(hass=hass, sessionid=PHPSESSID)
coordinator = None

try:
try:
login_success = await hass.async_add_executor_job(
edupage.login, username, password, subdomain
login_wrapper, edupage, username, password, subdomain
)
_LOGGER.debug("INIT login_success")

Expand All @@ -48,7 +55,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return False

except Exception as e:
_LOGGER.error("INIT unexpected login error: %s", e)
_LOGGER.error("INIT unexpected login error: %s", e.with_traceback(None))
return False

fetch_lock = asyncio.Lock()
Expand Down
12 changes: 8 additions & 4 deletions custom_components/homeassistantedupage/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@
from homeassistant import config_entries
from homeassistant.core import callback
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from.const import CONF_PHPSESSID, CONF_SUBDOMAIN, CONF_STUDENT_ID, CONF_STUDENT_NAME

_LOGGER = logging.getLogger(__name__)

CONF_SUBDOMAIN = "subdomain" # Lokal definiert

class EdupageConfigFlow(config_entries.ConfigFlow, domain="homeassistantedupage"):
"""Handle a config flow for Edupage."""

Expand All @@ -22,6 +21,7 @@ def login(self, api, user_input):
confirmation_method = "1"

if confirmation_method == "1":
#TODO: waiting does not work, maybe cause of async?! SecondFactorFailedException is raised if no breakpoint debug is set
while not second_factor.is_confirmed():
time.sleep(0.5)
second_factor.finish()
Expand Down Expand Up @@ -72,6 +72,10 @@ async def async_step_user(self, user_input=None):
errors["base"] = "no_students_found"
else:
# Speichere Benutzer-Eingaben
#bla = api.session.cookies["PHPSESSID"]
cookies = api.session.cookies.get_dict()
phpsess = cookies["PHPSESSID"]
user_input[CONF_PHPSESSID] = phpsess
self.user_data = user_input
self.students = {student.person_id: student.name for student in students}

Expand Down Expand Up @@ -107,8 +111,8 @@ async def async_step_select_student(self, user_input=None):
title=f"Edupage ({self.students[student_id]})",
data={
**self.user_data, # Login-Daten hinzufügen
"student_id": student_id,
"student_name": self.students[student_id],
CONF_STUDENT_ID: student_id,
CONF_STUDENT_NAME: self.students[student_id],
},
)

Expand Down
4 changes: 4 additions & 0 deletions custom_components/homeassistantedupage/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@

# Component domain, used to store component data in hass data.
DOMAIN = "homeassistantedupage"
CONF_SUBDOMAIN = "subdomain"
CONF_PHPSESSID = "PHPSESSID"
CONF_STUDENT_ID = "student_id"
CONF_STUDENT_NAME = "student_name"
21 changes: 17 additions & 4 deletions custom_components/homeassistantedupage/homeassistant_edupage.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import logging
import asyncio

from edupage_api import Login
from edupage_api import Edupage as APIEdupage
from edupage_api.classes import Class
from edupage_api.people import EduTeacher
from edupage_api.people import Gender
from edupage_api.classrooms import Classroom
from zoneinfo import ZoneInfo
from edupage_api.exceptions import BadCredentialsException, CaptchaException
from edupage_api.exceptions import BadCredentialsException, CaptchaException, SecondFactorFailedException


from datetime import datetime
Expand All @@ -18,14 +18,22 @@
_LOGGER = logging.getLogger(__name__)

class Edupage:
def __init__(self,hass):
def __init__(self,hass, sessionid = ''):
self.hass = hass
self.sessionid = sessionid
self.api = APIEdupage()

async def login(self, username: str, password: str, subdomain: str):
"""Perform login asynchronously."""
try:
result = await asyncio.to_thread(self.api.login, username, password, subdomain)
result = True
login = Login(self.api)
await asyncio.to_thread(
login.reload_data, subdomain, self.sessionid, username
)
if not self.api.is_logged_in:
#TODO: how to handle 2FA at this point?!
result = await asyncio.to_thread(self.api.login, username, password, subdomain)
_LOGGER.debug(f"EDUPAGE Login successful, result: {result}")
return result
except BadCredentialsException as e:
Expand All @@ -34,6 +42,11 @@ async def login(self, username: str, password: str, subdomain: str):

except CaptchaException as e:
_LOGGER.error("EDUPAGE login failed: CAPTCHA needed. %s", e)
return False

except SecondFactorFailedException as e:
#TODO hier müsste man dann irgendwie abfangen, falls die session mal abgelaufen ist. und dies dann auch irgendwie via HA sauber zum Nutzer bringen!?
_LOGGER.error("EDUPAGE login failed: 2FA error. %s", e)
return False

except Exception as e:
Expand Down

0 comments on commit 2420064

Please sign in to comment.