1111from cachetools import TTLCache
1212from requests .auth import HTTPBasicAuth , AuthBase
1313
14- from c8y_api ._auth import AuthUtil
14+ from c8y_api ._auth import AuthUtil , HTTPBearerAuth
1515from c8y_api ._main_api import CumulocityApi
1616from c8y_api ._util import c8y_keys
1717
1818
1919class _CumulocityAppBase (object ):
20- """Internal class, base for both Per Tenant and Multi Tenant specifc
20+ """Internal class, base for both Per Tenant and Multi Tenant specific
2121 implementation."""
2222
2323 def __init__ (self , log : logging .Logger , cache_size : int = 100 , cache_ttl : int = 3600 , ** kwargs ):
@@ -37,7 +37,7 @@ def get_user_instance(self, headers: dict = None) -> CumulocityApi:
3737 previously created instances are cached.
3838
3939 Args:
40- headers (dict): A dictionarity of HTTP header entries. The user
40+ headers (dict): A dictionary of HTTP header entries. The user
4141 access is based on the Authorization header within.
4242
4343 Returns:
@@ -101,15 +101,15 @@ class SimpleCumulocityApp(_CumulocityAppBase, CumulocityApi):
101101
102102 The SimpleCumulocityApp class is intended to be used as base within
103103 a single-tenant micro service hosted on Cumulocity. It evaluates the
104- environment to teh resolve the authentication information automatically.
104+ environment to the resolve the authentication information automatically.
105105
106106 Note: This class should be used in Cumulocity micro services using the
107107 PER_TENANT authentication mode only. It will not function in environments
108108 using the MULTITENANT mode.
109109
110110 The SimpleCumulocityApp class is an enhanced version of the standard
111111 CumulocityApi class. All Cumulocity functions can be used directly.
112- Additionally it can be used to provide CumulocityApi instances for
112+ Additionally, it can be used to provide CumulocityApi instances for
113113 specific named users via the `get_user_instance` function.
114114 """
115115
@@ -131,10 +131,16 @@ def __init__(self, application_key: str = None, cache_size: int = 100, cache_ttl
131131 """
132132 baseurl = self ._get_env ('C8Y_BASEURL' )
133133 tenant_id = self ._get_env ('C8Y_TENANT' )
134- username = self ._get_env ('C8Y_USER' )
135- password = self ._get_env ('C8Y_PASSWORD' )
134+ # authentication is either token or username/password
135+ try :
136+ token = self ._get_env ('C8Y_TOKEN' )
137+ auth = HTTPBearerAuth (token )
138+ except ValueError :
139+ username = self ._get_env ('C8Y_USER' )
140+ password = self ._get_env ('C8Y_PASSWORD' )
141+ auth = HTTPBasicAuth (f'{ tenant_id } /{ username } ' , password )
136142 super ().__init__ (log = self ._log , cache_size = cache_size , cache_ttl = cache_ttl ,
137- base_url = baseurl , tenant_id = tenant_id , auth = HTTPBasicAuth ( f' { tenant_id } / { username } ' , password ) ,
143+ base_url = baseurl , tenant_id = tenant_id , auth = auth ,
138144 application_key = application_key )
139145
140146 def _build_user_instance (self , auth ) -> CumulocityApi :
@@ -149,7 +155,7 @@ class MultiTenantCumulocityApp(_CumulocityAppBase):
149155
150156 The MultiTenantCumulocityApp class is intended to be used as base within
151157 a multi-tenant micro service hosted on Cumulocity. It evaluates the
152- environment to teh resolve the bootstrap authentication information
158+ environment to the resolve the bootstrap authentication information
153159 automatically.
154160
155161 Note: This class is intended to be used in Cumulocity micro services
@@ -178,25 +184,42 @@ def _get_tenant_auth(self, tenant_id: str) -> AuthBase:
178184 try :
179185 return self ._subscribed_auths [tenant_id ]
180186 except KeyError :
181- self ._subscribed_auths = self ._read_subscriptions (self .bootstrap_instance )
187+ self ._subscribed_auths = self ._read_subscription_auths (self .bootstrap_instance )
182188 return self ._subscribed_auths [tenant_id ]
183189
184190 @classmethod
185- def _read_subscriptions (cls , bootstrap_instance : CumulocityApi ):
191+ def _read_subscriptions (cls , bootstrap_instance : CumulocityApi ) -> list [dict ]:
192+ """Read subscribed tenants details.
193+
194+ Returns:
195+ A list of tenant details dicts.
196+ """
197+ subscriptions = bootstrap_instance .get ('/application/currentApplication/subscriptions' )
198+ return subscriptions ['users' ]
199+
200+ @classmethod
201+ def _read_subscription_auths (cls , bootstrap_instance : CumulocityApi ):
186202 """Read subscribed tenant's auth information.
187203
188204 Returns:
189205 A dict of tenant auth information by ID
190206 """
191- subscriptions = bootstrap_instance .get ('/application/currentApplication/subscriptions' )
192207 cache = {}
193- for subscription in subscriptions [ 'users' ] :
208+ for subscription in cls . _read_subscriptions ( bootstrap_instance ) :
194209 tenant = subscription ['tenant' ]
195210 username = subscription ['name' ]
196211 password = subscription ['password' ]
197212 cache [tenant ] = HTTPBasicAuth (f'{ tenant } /{ username } ' , password )
198213 return cache
199214
215+ def get_subscribers (self ) -> list [str ]:
216+ """Query the subscribed tenants.
217+
218+ Returns:
219+ A list of tenant ID.
220+ """
221+ return [x ['tenant' ] for x in self ._read_subscriptions (self .bootstrap_instance )]
222+
200223 @classmethod
201224 def _create_bootstrap_instance (cls ) -> CumulocityApi :
202225 """Build the bootstrap instance from the environment."""
0 commit comments