Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding logout function and context manager into Authentication class #180

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Jypear
Copy link

@Jypear Jypear commented Jan 5, 2024

Hi,

I hope the maintainers accept PRs for this repository still. I recently received a suggestion from Cisco TAC that an issue could potentially be being caused by an API account not terminating its sessions properly. This API account is heavily used and with sessions not being terminated there is a high amount of active authenticated sessions waiting for the standard 30 minute time out. We use this SDK quite heavily in some services and I noticed there is currently no built in way to trigger a logout, so I'm submitting a PR for one.

The logout function is relatively similar to the login function with some subtle differences:

    def logout(self, session=None):
        """Executes a logout query against the vManage to terminate session.

        Args:
            Session: Optionally pass in a session if the login function was run directly.
            If no session is passed in, the logout operation is performed on self.session

        Returns:
            session: Returns the same session object after the logout functionality
            has been performed.

        Raises:
            ConnectionError if failure to connect to vManage for logout query.
        """
        try:
            if not session:
                session = self.session

            version = Utilities(session, self.host, self.port).get_vmanage_version()
            api = f"logout?nocache={randint(1,999)}"
            url = f'https://{self.host}:{self.port}/{api}'
            response = session.get(url=url, timeout=self.timeout)
            if response.status_code != 200:
                raise ConnectionError('Logout operation failed. Recieved non-200 code from vManage')
            if version >= '19.2.0':
                session.headers.pop('X-XSRF-TOKEN', None)

        except requests.exceptions.RequestException as e:
            raise ConnectionError(f'Could not connect to {self.host}: {e}')

        return session

This function can be called directly if the user initiated the class and called login after the fact. However if the user followed the example and called login directly without storing the initiated class the user can pass an optional "session" argument to specify the session they wish to terminate (they would not need to pass credentials on the logout call).

from vmanage.api.authentication import Authentication
# Without storing the initiated class
session = Authentication(
    host=host,
    user=user,
    password=passw,
    ).login()

session = Authentication(host=host).logout(session)

# With storing the initiated class
auth = Authentication(
    host=host,
    user=user,
    password=passw,
    )

session = auth.login()
session = auth.logout()

This correctly terminates the session on the vManage.

The authentication class also includes a context manager to control the session within the context to allow for properly closing the session on an error.

    def __enter__(self):
        self.login()
        return self.session

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.logout()

This then allows the user to control their connection with a with statement instead:

from vmanage.api.authentication import Authentication
from vmanage.api.device import Device

auth = Authentication(
    host=host,
    user=user,
    password=passw,
    )
with auth as session:
    device_object = Device(session, host)
    device_list = device_object.get_device_status_list()
    print(device_list)

Hopefully the PR is okay, if theres anything that needs changing or their are suggested improvements just let me know.

Cheers

…ext manager

- Created logout function which sends a request the the logout endpoint
- Created __enter__ and __exit__ methods which allow for use of a context manager
Copy link

sonarcloud bot commented Jan 5, 2024

Quality Gate Failed Quality Gate failed

Failed conditions

1 Security Hotspot

See analysis details on SonarCloud

@Jypear
Copy link
Author

Jypear commented Jan 5, 2024

It looks like theres a flag with the use of randint on the logout when a random number needs to be generated on the logout.
I believe it still works without this, but I just followed the guideline from the docs when it comes to logging out.

https://developer.cisco.com/docs/sdwan/#!authentication/how-to-authenticate

If this will be a problem I can find an alternative solution if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant