Salamek / huawei-lte-api

API For huawei LAN/WAN LTE Modems
GNU Lesser General Public License v3.0
376 stars 92 forks source link

ResponseErrorLoginRequiredException while calling user.login() #118

Open outofsight opened 2 years ago

outofsight commented 2 years ago

Not sure if this a question, an enanchement or a bug. I'm developing a long running service that requires regular access (every 30sec - 5min, to be defined) to a Huawei modem.

I think it was a good idea to save Connection object and reuse among calls to Huawei api.

Looking at source code I noticed I need/can freely call user.login() api before api access to ensure a proper login session is established.

But calling login() after a while from last api access with an already established Connection object raise ResponseErrorLoginRequiredException, which I can't undestand: I'm trying to login, and you tell me I need to login? :)

By the way, what is the the best approach supported by this library? Creating and discarding the Connection object every time, maybe often? There is a supported way to "resurrect" a previously used Connection object and ensure has a valid login context?

Salamek commented 2 years ago

@outofsight We need to implement some user session recycle service, that means when user session time outs, log out-> log in

For you it means to handle the user session time out exception (ResponseErrorLoginRequiredException) or check time of login + session time out time

And call

self.user.login('login', 'password', force_new_login=True)

if that still does not work:

self.user.logout()  # This is needed before every "not really" expired login when it is expired (Don't ask, Huawei router API is a mess)
self.user.login('login', 'password', force_new_login=True)

I would like to implement some "keep me logged in" service, but there was no need for it (until now) and you can easily implement it your self on top of this library... but PRs are welcomed for sure

outofsight commented 2 years ago

@Salamek Thanks for explaining.

I'm not sure how to get session timeout wich I think can be hardware/firmware specific, but checking login time and session timeout seems to me an unreliable way to ensure a valid login session before calling a number of api. Or not?

If I well understand, if I want to ensure a valid login session, after some time from last api call, already having a previusly used and saved Connection object, I can do something like the following code.

from huawei_lte_api.Client import Client as HuaweiClient
from huawei_lte_api.Connection import Connection as HuaweiConnection
from huawei_lte_api.enums.user import LoginStateEnum

with HuaweiConnection(host, user, password) as connection:
    client = HuaweiClient(connection)

    print(client.user.state_login())
    print(client.device.information())  # Needs valid authorization, will throw exception if invalid credentials are passed in URL

    # This was intended to simulate timeout without waiting
    client.user.logout()

    # >>> This block was intended to ensure a valid login context <<<
    try:
        stateLogin = client.user.state_login()['State']    # not sure if user.state_login() can fails if there is an expired login session
    except:
        stateLogin = LoginStateEnum.LOGGED_OUT

    if int(stateLogin) == int(LoginStateEnum.LOGGED_OUT):
        try:
            # This throw exception but has still some side effect because if I miss this call the following user.login(), while succeding, makes the last api call fails
            # I suppose this is the expired-not-expired-login edge case you mentioned
            client.user.logout()
        except:
            pass
        print(client.user.login(user, password, force_new_login=True))

    # This is an example of api call requiring login
    print(client.device.information())  
    # print(client.sms.get_sms_list(1, box_type=BoxTypeEnum.LOCAL_INBOX, read_count=20, sort_type=0, ascending=0, unread_preferred=0))
Salamek commented 2 years ago

@outofsight yea, something like that, it needs a bit of "dark magic" to work properly, as you can see whole login and user session implementation is a mess on the huawei part and i had no other option then reflect that in my code...