meraki / dashboard-api-python

Official Dashboard API library (SDK) for Python
MIT License
293 stars 154 forks source link

Call to DashboardAPI with invalid API key returns 'valid' Dashboard session #126

Closed seanmathias closed 3 years ago

seanmathias commented 4 years ago

A call to DashboardAPI using a bogus API key returns a seemingly valid session. It is only when making a subsequent API call that the API key is flagged as invalid.

Typically I would expect the key to be flagged as invalid when attempting to establish a session so this condition can be trapped earlier and in the logical place.

In [15]: import meraki                                                                                                                               

In [16]: test = meraki.DashboardAPI('12345')                                                                                                         
2020-11-11 12:01:52       meraki:     INFO > Meraki dashboard API session initialized with these parameters: {'version': '1.3.0', 'api_key': '************************************2345', 'base_url': 'https://api.meraki.com/api/v1', 'single_request_timeout': 60, 'certificate_path': '', 'requests_proxy': '', 'wait_on_rate_limit': True, 'nginx_429_retry_wait_time': 60, 'action_batch_retry_wait_time': 60, 'retry_4xx_error': False, 'retry_4xx_error_wait_time': 60, 'maximum_retries': 2, 'simulate': False, 'be_geo_id': None, 'caller': None}

In [17]: test                                                                                                                                        
Out[17]: <meraki.DashboardAPI at 0x7f62693adeb0>

In [18]: type(test)                                                                                                                                  
Out[18]: meraki.DashboardAPI

In [19]: test.organizations.getOrganizations()                                                                                                       
2020-11-11 12:02:11       meraki:     INFO > GET https://api.meraki.com/api/v1/organizations
2020-11-11 12:02:11       meraki:    ERROR > organizations, getOrganizations - 401 Unauthorized, {'errors': ['Invalid API key']}
---------------------------------------------------------------------------
APIError                                  Traceback (most recent call last)
<ipython-input-19-b91c2726861f> in <module>
----> 1 test.organizations.getOrganizations()

~/.local/lib/python3.8/site-packages/meraki/api/organizations.py in getOrganizations(self)
     17         resource = f'/organizations'
     18 
---> 19         return self._session.get(metadata, resource)
     20 
     21     def createOrganization(self, name: str):

~/.local/lib/python3.8/site-packages/meraki/rest_session.py in get(self, metadata, url, params)
    266         metadata['url'] = url
    267         metadata['params'] = params
--> 268         response = self.request(metadata, 'GET', url, params=params)
    269         ret = None
    270         if response:

~/.local/lib/python3.8/site-packages/meraki/rest_session.py in request(self, metadata, method, url, **kwargs)
    260                         if self._logger:
    261                             self._logger.error(f'{tag}, {operation} - {status} {reason}, {message}')
--> 262                         raise APIError(metadata, response)
    263 
    264     def get(self, metadata, url, params=None):

APIError: organizations, getOrganizations - 401 Unauthorized, {'errors': ['Invalid API key']}
av1m commented 3 years ago

Unless I'm mistaken, there is no endpoint to check if the API is working.

Your suggestion for improvement can be simply carried out (in the meantime) through a function similar to this one:

import meraki

def is_valid_apikey(apikey: str) -> bool:
    try:
        meraki.DashboardAPI(api_key=apikey, suppress_logging=True, print_console=False).organizations.getOrganizations()
    except meraki.exceptions.APIError as e:
        if '401' in str(e).lower():
            return False
    return True
seanmathias commented 3 years ago

Thanks, that is a reasonable approach, I was just looking for buiilt-in functionality rather than adding my own.

TKIPisalegacycipher commented 3 years ago

Consider that since validating the API key requires making an API call, if it is valid, then that's one of your 5 calls per second gone just to validate a key that really should have been known to work in advance.

Customers who are frugal with their API call budget might not be thrilled that a generally unnecessary API call is made on their behalf--so it is a fundamentally better approach to not pre-validate the API key.

On Wed, Dec 9, 2020 at 5:37 PM Sean Mathias notifications@github.com wrote:

Thanks, that is a reasonable approach, I was just looking for buiilt-in functionality rather than adding my own.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/meraki/dashboard-api-python/issues/126#issuecomment-742175767, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA5EUKVPCJKDP3VCVJNATK3SUAQ6DANCNFSM4TSM7YTA .