11import datetime
22import typing
3+ from abc import ABC , abstractmethod
34
5+ if typing .TYPE_CHECKING :
6+ import boto3 # type: ignore
7+
8+
9+ class ABCCredentialsHolder (ABC ):
10+ """
11+ Abstract base class used to store credentials for establishing a connection to an Amazon Redshift cluster.
12+ """
13+
14+ @abstractmethod
15+ def get_session_credentials (self : "ABCCredentialsHolder" ):
16+ """
17+ A dictionary mapping end-user specified AWS credential value to :func:`boto3.client` parameters.
18+
19+ Returns
20+ _______
21+ A dictionary mapping parameter names to end-user specified values: `typing.Dict[str,str]`
22+ """
23+ pass
24+
25+ @property
26+ def has_associated_session (self : "ABCCredentialsHolder" ) -> bool :
27+ """
28+ A boolean value indicating if the current class stores AWS credentials in a :class:`boto3.Session`.
29+
30+ Returns
31+ -------
32+ `True` if the current class provides a :class:`boto3.Session` object, otherwise `False` : `bool`
33+ """
34+ return False
35+
36+
37+ class ABCAWSCredentialsHolder (ABC ):
38+ """
39+ Abstract base class used to store AWS credentials provided by user.
40+ """
41+
42+ def __init__ (self : "ABCAWSCredentialsHolder" , session : "boto3.Session" ):
43+ self .boto_session = session
44+
45+ @property
46+ def has_associated_session (self : "ABCAWSCredentialsHolder" ) -> bool :
47+ return True
48+
49+ def get_boto_session (self : "ABCAWSCredentialsHolder" ) -> "boto3.Session" :
50+ """
51+ The :class:`boto3.Session` created using the end-user's AWS Credentials.
52+ Returns
53+ -------
54+ A boto3 session created with the end-user's AWS Credentials: :class:`boto3.Session`
55+ """
56+ return self .boto_session
57+
58+
59+ class AWSDirectCredentialsHolder (ABCAWSCredentialsHolder ):
60+ """
61+ Credential class used to store AWS credentials provided in :func:`~redshift_connector.connect`.
62+ """
63+
64+ def __init__ (
65+ self , access_key_id : str , secret_access_key : str , session_token : typing .Optional [str ], session : "boto3.Session"
66+ ):
67+ super ().__init__ (session )
68+ self .access_key_id : str = access_key_id
69+ self .secret_access_key : str = secret_access_key
70+ self .session_token : typing .Optional [str ] = session_token
71+ self ._session : "boto3.Session" = session
72+
73+ def get_session_credentials (self : "AWSDirectCredentialsHolder" ) -> typing .Dict [str , str ]:
74+ creds : typing .Dict [str , str ] = {
75+ "aws_access_key_id" : self .access_key_id ,
76+ "aws_secret_access_key" : self .secret_access_key ,
77+ }
78+
79+ if self .session_token is not None :
80+ creds ["aws_session_token" ] = self .session_token
81+
82+ return creds
83+
84+
85+ class AWSProfileCredentialsHolder (ABCAWSCredentialsHolder ):
86+ """
87+ Credential class used to store AWS Credentials provided in environment IAM credentials.
88+ """
89+
90+ def __init__ (self , profile : str , session : "boto3.Session" ):
91+ super ().__init__ (session )
92+ self .profile = profile
93+
94+ def get_session_credentials (self : "AWSProfileCredentialsHolder" ) -> typing .Dict [str , str ]:
95+ return {"profile" : self .profile }
96+
97+
98+ class CredentialsHolder (ABCCredentialsHolder ):
99+ """
100+ credentials class used to store credentials and metadata from SAML assertion.
101+ """
4102
5- # credentials class used to store credentials
6- # and metadata from SAML assertion
7- class CredentialsHolder :
8103 def __init__ (self : "CredentialsHolder" , credentials : typing .Dict [str , typing .Any ]) -> None :
9104 self .metadata : "CredentialsHolder.IamMetadata" = CredentialsHolder .IamMetadata ()
10105 self .credentials : typing .Dict [str , typing .Any ] = credentials
@@ -28,15 +123,25 @@ def get_aws_secret_key(self: "CredentialsHolder") -> str:
28123 def get_session_token (self : "CredentialsHolder" ) -> str :
29124 return typing .cast (str , self .credentials ["SessionToken" ])
30125
126+ def get_session_credentials (self : "CredentialsHolder" ) -> typing .Dict [str , str ]:
127+ return {
128+ "aws_access_key_id" : self .get_aws_access_key_id (),
129+ "aws_secret_access_key" : self .get_aws_secret_key (),
130+ "aws_session_token" : self .get_session_token (),
131+ }
132+
31133 # The date on which the current credentials expire.
32134 def get_expiration (self : "CredentialsHolder" ) -> datetime .datetime :
33135 return self .expiration
34136
35137 def is_expired (self : "CredentialsHolder" ) -> bool :
36138 return datetime .datetime .now () > self .expiration .replace (tzinfo = None )
37139
38- # metadata used to store information from SAML assertion
39140 class IamMetadata :
141+ """
142+ Metadata used to store information from SAML assertion
143+ """
144+
40145 def __init__ (self : "CredentialsHolder.IamMetadata" ) -> None :
41146 self .auto_create : bool = False
42147 self .db_user : typing .Optional [str ] = None
0 commit comments