Skip to content

Commit 82c770b

Browse files
committed
refactor: shared authenticator class with the IAM related functions
1 parent 7fcf4f2 commit 82c770b

File tree

2 files changed

+117
-75
lines changed

2 files changed

+117
-75
lines changed

ibm_cloud_sdk_core/authenticators/iam_authenticator.py

Lines changed: 4 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@
1616

1717
from typing import Dict, Optional
1818

19-
from requests import Request
20-
21-
from .authenticator import Authenticator
19+
from .iam_request_based_authenticator import IAMRequestBasedAuthenticator
2220
from ..iam_token_manager import IAMTokenManager
2321
from ..utils import has_bad_first_or_last_char
2422

25-
class IAMAuthenticator(Authenticator):
23+
class IAMAuthenticator(IAMRequestBasedAuthenticator):
2624
"""The IAMAuthenticator utilizes an apikey, or client_id and client_secret pair to
2725
obtain a suitable bearer token, and adds it to requests.
2826
@@ -81,81 +79,12 @@ def validate(self) -> None:
8179
Raises:
8280
ValueError: The apikey, client_id, and/or client_secret are not valid for IAM token requests.
8381
"""
82+
super().validate()
83+
8484
if self.token_manager.apikey is None:
8585
raise ValueError('The apikey shouldn\'t be None.')
8686

8787
if has_bad_first_or_last_char(self.token_manager.apikey):
8888
raise ValueError(
8989
'The apikey shouldn\'t start or end with curly brackets or quotes. '
9090
'Please remove any surrounding {, }, or \" characters.')
91-
92-
if (self.token_manager.client_id and
93-
not self.token_manager.client_secret) or (
94-
not self.token_manager.client_id and
95-
self.token_manager.client_secret):
96-
raise ValueError(
97-
'Both client_id and client_secret should be initialized.')
98-
99-
def authenticate(self, req: Request) -> None:
100-
"""Adds IAM authentication information to the request.
101-
102-
The IAM bearer token will be added to the request's headers in the form:
103-
104-
Authorization: Bearer <bearer-token>
105-
106-
Args:
107-
req: The request to add IAM authentication information too. Must contain a key to a dictionary
108-
called headers.
109-
"""
110-
headers = req.get('headers')
111-
bearer_token = self.token_manager.get_token()
112-
headers['Authorization'] = 'Bearer {0}'.format(bearer_token)
113-
114-
def set_client_id_and_secret(self, client_id: str, client_secret: str) -> None:
115-
"""Set the client_id and client_secret pair the token manager will use for IAM token requests.
116-
117-
Args:
118-
client_id: The client id to be used in basic auth.
119-
client_secret: The client secret to be used in basic auth.
120-
121-
Raises:
122-
ValueError: The apikey, client_id, and/or client_secret are not valid for IAM token requests.
123-
"""
124-
self.token_manager.set_client_id_and_secret(client_id, client_secret)
125-
self.validate()
126-
127-
def set_disable_ssl_verification(self, status: bool = False) -> None:
128-
"""Set the flag that indicates whether verification of the server's SSL certificate should be
129-
disabled or not. Defaults to False.
130-
131-
Keyword Arguments:
132-
status: Headers to be sent with every IAM token request. Defaults to None.
133-
"""
134-
self.token_manager.set_disable_ssl_verification(status)
135-
136-
def set_headers(self, headers: Dict[str, str]) -> None:
137-
"""Headers to be sent with every IAM token request.
138-
139-
Args:
140-
headers: Headers to be sent with every IAM token request.
141-
"""
142-
self.token_manager.set_headers(headers)
143-
144-
def set_proxies(self, proxies: Dict[str, str]) -> None:
145-
"""Sets the proxies the token manager will use to communicate with IAM on behalf of the host.
146-
147-
Args:
148-
proxies: Dictionary for mapping request protocol to proxy URL.
149-
proxies.http (optional): The proxy endpoint to use for HTTP requests.
150-
proxies.https (optional): The proxy endpoint to use for HTTPS requests.
151-
"""
152-
self.token_manager.set_proxies(proxies)
153-
154-
def set_scope(self, value: str) -> None:
155-
"""Sets the "scope" parameter to use when fetching the bearer token from the IAM token server.
156-
This can be used to obtain an access token with a specific scope.
157-
158-
Args:
159-
value: A space seperated string that makes up the scope parameter.
160-
"""
161-
self.token_manager.set_scope(value)
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# coding: utf-8
2+
3+
# Copyright 2019 IBM All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
from typing import Dict
18+
19+
from requests import Request
20+
21+
from .authenticator import Authenticator
22+
23+
class IAMRequestBasedAuthenticator(Authenticator):
24+
"""The IAMRequestBasedAuthenticator class contains code that is common to all authenticators
25+
that need to interact with the IAM tokens service to obtain an access token.
26+
27+
The bearer token will be sent as an Authorization header in the form:
28+
29+
Authorization: Bearer <bearer-token>
30+
31+
Attributes:
32+
token_manager (TokenManager): Retrives and manages IAM tokens from the endpoint specified by the url.
33+
"""
34+
authentication_type = 'iam'
35+
36+
def validate(self) -> None:
37+
"""Validates the client_id, and client_secret for IAM token requests.
38+
39+
Ensure both the client_id and client_secret are set if either of them are defined.
40+
41+
Raises:
42+
ValueError: The client_id, and/or client_secret are not valid for IAM token requests.
43+
"""
44+
if (self.token_manager.client_id and
45+
not self.token_manager.client_secret) or (
46+
not self.token_manager.client_id and
47+
self.token_manager.client_secret):
48+
raise ValueError(
49+
'Both client_id and client_secret should be initialized.')
50+
51+
def authenticate(self, req: Request) -> None:
52+
"""Adds IAM authentication information to the request.
53+
54+
The IAM bearer token will be added to the request's headers in the form:
55+
56+
Authorization: Bearer <bearer-token>
57+
58+
Args:
59+
req: The request to add IAM authentication information too. Must contain a key to a dictionary
60+
called headers.
61+
"""
62+
headers = req.get('headers')
63+
bearer_token = self.token_manager.get_token()
64+
headers['Authorization'] = 'Bearer {0}'.format(bearer_token)
65+
66+
def set_client_id_and_secret(self, client_id: str, client_secret: str) -> None:
67+
"""Set the client_id and client_secret pair the token manager will use for IAM token requests.
68+
69+
Args:
70+
client_id: The client id to be used in basic auth.
71+
client_secret: The client secret to be used in basic auth.
72+
73+
Raises:
74+
ValueError: The apikey, client_id, and/or client_secret are not valid for IAM token requests.
75+
"""
76+
self.token_manager.set_client_id_and_secret(client_id, client_secret)
77+
self.validate()
78+
79+
def set_disable_ssl_verification(self, status: bool = False) -> None:
80+
"""Set the flag that indicates whether verification of the server's SSL certificate should be
81+
disabled or not. Defaults to False.
82+
83+
Keyword Arguments:
84+
status: Headers to be sent with every IAM token request. Defaults to None.
85+
"""
86+
self.token_manager.set_disable_ssl_verification(status)
87+
88+
def set_headers(self, headers: Dict[str, str]) -> None:
89+
"""Headers to be sent with every IAM token request.
90+
91+
Args:
92+
headers: Headers to be sent with every IAM token request.
93+
"""
94+
self.token_manager.set_headers(headers)
95+
96+
def set_proxies(self, proxies: Dict[str, str]) -> None:
97+
"""Sets the proxies the token manager will use to communicate with IAM on behalf of the host.
98+
99+
Args:
100+
proxies: Dictionary for mapping request protocol to proxy URL.
101+
proxies.http (optional): The proxy endpoint to use for HTTP requests.
102+
proxies.https (optional): The proxy endpoint to use for HTTPS requests.
103+
"""
104+
self.token_manager.set_proxies(proxies)
105+
106+
def set_scope(self, value: str) -> None:
107+
"""Sets the "scope" parameter to use when fetching the bearer token from the IAM token server.
108+
This can be used to obtain an access token with a specific scope.
109+
110+
Args:
111+
value: A space seperated string that makes up the scope parameter.
112+
"""
113+
self.token_manager.set_scope(value)

0 commit comments

Comments
 (0)