Skip to content
This repository was archived by the owner on May 5, 2025. It is now read-only.

Commit ad008c6

Browse files
authored
Remove unused token_revoke_url kwarg; add Developer Token support; refactor refresh() method (#126)
1 parent 804a6e0 commit ad008c6

File tree

1 file changed

+54
-16
lines changed

1 file changed

+54
-16
lines changed

pancloud/credentials.py

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
# Constants
2121
API_BASE_URL = 'https://api.paloaltonetworks.com'
2222
AUTH_BASE_URL = 'https://identity.paloaltonetworks.com/as/authorization.oauth2'
23+
DEVELOPER_TOKEN_URL = 'https://app.apiexplorer.rocks'
2324

2425
ReadOnlyCredentials = namedtuple(
2526
'ReadOnlyCredentials',
@@ -31,11 +32,11 @@ class Credentials(object):
3132
"""An Application Framework credentials object."""
3233

3334
def __init__(self, access_token=None, auth_base_url=None, cache_token=True,
34-
client_id=None, client_secret=None, instance_id=None,
35-
profile=None, redirect_uri=None, region=None,
36-
refresh_token=None, scope=None, storage_adapter=None,
37-
storage_params=None, token_url=None, token_revoke_url=None,
38-
**kwargs):
35+
client_id=None, client_secret=None, developer_token=None,
36+
developer_token_url=None, instance_id=None, profile=None,
37+
redirect_uri=None, region=None, refresh_token=None,
38+
scope=None, storage_adapter=None, storage_params=None,
39+
token_url=None, **kwargs):
3940
"""Persist Session() and credentials attributes.
4041
4142
The ``Credentials`` class is an abstraction layer for accessing,
@@ -55,6 +56,8 @@ def __init__(self, access_token=None, auth_base_url=None, cache_token=True,
5556
cache_token (bool): If ``True``, stores ``access_token`` in token store. Defaults to ``True``.
5657
client_id (str): OAuth2 client ID. Defaults to ``None``.
5758
client_secret (str): OAuth2 client secret. Defaults to ``None``.
59+
developer_token (str): Developer Token. Defaults to ``None``.
60+
developer_token_url (str): Developer Token URL. Defaults to ``None``.
5861
instance_id (str): Instance ID. Defaults to ``None``.
5962
profile (str): Credentials profile. Defaults to ``'default'``.
6063
redirect_uri (str): Redirect URI. Defaults to ``None``.
@@ -72,6 +75,8 @@ def __init__(self, access_token=None, auth_base_url=None, cache_token=True,
7275
self.cache_token_ = cache_token
7376
self.client_id_ = client_id
7477
self.client_secret_ = client_secret
78+
self.developer_token_ = developer_token
79+
self.developer_token_url = developer_token_url or DEVELOPER_TOKEN_URL
7580
self.instance_id = instance_id
7681
self.jwt_exp_ = None
7782
self.profile = profile or 'default'
@@ -93,7 +98,8 @@ def __init__(self, access_token=None, auth_base_url=None, cache_token=True,
9398

9499
def __repr__(self):
95100
args = self.__dict__.copy()
96-
for k in ['access_token_', 'refresh_token_', 'client_secret_']:
101+
for k in ['access_token_', 'refresh_token_', 'client_secret_',
102+
'developer_token_']:
97103
if args[k] is not None:
98104
args[k] = '*' * 6
99105
return '{}({})'.format(
@@ -142,6 +148,16 @@ def client_secret(self, client_secret):
142148
"""Set client_secret."""
143149
self.client_secret_ = client_secret
144150

151+
@property
152+
def developer_token(self):
153+
"""Get developer token."""
154+
return self.developer_token_ or os.getenv('PAN_DEVELOPER_TOKEN')
155+
156+
@developer_token.setter
157+
def developer_token(self, developer_token):
158+
"""Set developer token."""
159+
self.developer_token_ = developer_token
160+
145161
@property
146162
def jwt_exp(self):
147163
"""Get JWT exp."""
@@ -416,12 +432,31 @@ def refresh(self, access_token=None, **kwargs):
416432
if not self.token_lock.locked():
417433
with self.token_lock:
418434
if access_token == self.access_token or access_token is None:
419-
c = self.get_credentials()
420-
if c.client_id and c.client_secret and c.refresh_token:
435+
if self.developer_token is not None:
436+
r = self._httpclient.request(
437+
method='POST',
438+
url=self.developer_token_url,
439+
path='/request_token',
440+
headers={
441+
'Authorization': 'Bearer {}'.format(
442+
self.developer_token
443+
)
444+
},
445+
timeout=30,
446+
raise_for_status=True
447+
)
448+
449+
elif all(
450+
[
451+
self.client_id,
452+
self.client_secret,
453+
self.refresh_token
454+
]
455+
):
421456
data = {
422-
'client_id': c.client_id,
423-
'client_secret': c.client_secret,
424-
'refresh_token': c.refresh_token,
457+
'client_id': self.client_id,
458+
'client_secret': self.client_secret,
459+
'refresh_token': self.refresh_token,
425460
'grant_type': 'refresh_token'
426461
}
427462
r = self._httpclient.request(
@@ -431,9 +466,16 @@ def refresh(self, access_token=None, **kwargs):
431466
path='/api/oauth2/RequestToken',
432467
**kwargs
433468
)
469+
else:
470+
raise PartialCredentialsError(
471+
"Missing one or more required credentials"
472+
)
473+
474+
if r:
434475
if not r.ok:
435476
raise PanCloudError(
436-
'%s %s: %s' % (r.status_code, r.reason, r.text)
477+
'%s %s: %s' % (
478+
r.status_code, r.reason, r.text)
437479
)
438480
try:
439481
r_json = r.json()
@@ -456,10 +498,6 @@ def refresh(self, access_token=None, **kwargs):
456498
r_json.get('refresh_token')
457499
self.write_credentials()
458500
return self.access_token_
459-
else:
460-
raise PartialCredentialsError(
461-
"Missing one or more required credentials"
462-
)
463501

464502
def revoke_access_token(self, **kwargs):
465503
"""Revoke access token."""

0 commit comments

Comments
 (0)