|
15 | 15 | """Firebase credentials module."""
|
16 | 16 | import collections
|
17 | 17 | import json
|
| 18 | +import six |
18 | 19 |
|
19 | 20 | import google.auth
|
20 | 21 | from google.auth.transport import requests
|
@@ -55,32 +56,41 @@ class Certificate(Base):
|
55 | 56 |
|
56 | 57 | _CREDENTIAL_TYPE = 'service_account'
|
57 | 58 |
|
58 |
| - def __init__(self, file_path): |
59 |
| - """Initializes a credential from a certificate file. |
| 59 | + def __init__(self, cert): |
| 60 | + """Initializes a credential from a Google service account certificate. |
60 | 61 |
|
61 |
| - Parses the specified certificate file (service account file), and |
62 |
| - creates a credential instance from it. |
| 62 | + Service account certificates can be downloaded as JSON files from the Firebase console. |
| 63 | + To instantiate a credential from a certificate file, either specify the file path or a |
| 64 | + dict representing the parsed contents of the file. |
63 | 65 |
|
64 | 66 | Args:
|
65 |
| - file_path: Path to a service account certificate file. |
| 67 | + cert: Path to a certificate file or a dict representing the contents of a certificate. |
66 | 68 |
|
67 | 69 | Raises:
|
68 |
| - IOError: If the specified file doesn't exist or cannot be read. |
69 |
| - ValueError: If the certificate file is invalid. |
| 70 | + IOError: If the specified certificate file doesn't exist or cannot be read. |
| 71 | + ValueError: If the specified certificate is invalid. |
70 | 72 | """
|
71 | 73 | super(Certificate, self).__init__()
|
72 |
| - with open(file_path) as json_keyfile: |
73 |
| - json_data = json.load(json_keyfile) |
| 74 | + if isinstance(cert, six.string_types): |
| 75 | + with open(cert) as json_file: |
| 76 | + json_data = json.load(json_file) |
| 77 | + elif isinstance(cert, dict): |
| 78 | + json_data = cert |
| 79 | + else: |
| 80 | + raise ValueError( |
| 81 | + 'Invalid certificate argument: "{0}". Certificate argument must be a file path, ' |
| 82 | + 'or a dict containing the parsed file contents.'.format(cert)) |
| 83 | + |
74 | 84 | if json_data.get('type') != self._CREDENTIAL_TYPE:
|
75 |
| - raise ValueError('Invalid certificate file: "{0}". File must contain a ' |
76 |
| - '"type" field set to "{1}".'.format(file_path, self._CREDENTIAL_TYPE)) |
| 85 | + raise ValueError('Invalid service account certificate. Certificate must contain a ' |
| 86 | + '"type" field set to "{0}".'.format(self._CREDENTIAL_TYPE)) |
77 | 87 | self._project_id = json_data.get('project_id')
|
78 | 88 | try:
|
79 | 89 | self._g_credential = service_account.Credentials.from_service_account_info(
|
80 | 90 | json_data, scopes=_scopes)
|
81 | 91 | except ValueError as error:
|
82 |
| - raise ValueError('Failed to initialize a certificate credential from file "{0}". ' |
83 |
| - 'Caused by: "{1}"'.format(file_path, error)) |
| 92 | + raise ValueError('Failed to initialize a certificate credential. ' |
| 93 | + 'Caused by: "{0}"'.format(error)) |
84 | 94 |
|
85 | 95 | @property
|
86 | 96 | def project_id(self):
|
@@ -132,29 +142,43 @@ class RefreshToken(Base):
|
132 | 142 |
|
133 | 143 | _CREDENTIAL_TYPE = 'authorized_user'
|
134 | 144 |
|
135 |
| - def __init__(self, file_path): |
136 |
| - """Initializes a refresh token credential from the specified JSON file. |
| 145 | + def __init__(self, refresh_token): |
| 146 | + """Initializes a credential from a refresh token JSON file. |
| 147 | +
|
| 148 | + The JSON must consist of client_id, client_secert and refresh_token fields. Refresh |
| 149 | + token files are typically created and managed by the gcloud SDK. To instantiate |
| 150 | + a credential from a refresh token file, either specify the file path or a dict |
| 151 | + representing the parsed contents of the file. |
137 | 152 |
|
138 | 153 | Args:
|
139 |
| - file_path: File path to a refresh token JSON file. |
| 154 | + refresh_token: Path to a refresh token file or a dict representing the contents of a |
| 155 | + refresh token file. |
140 | 156 |
|
141 | 157 | Raises:
|
142 | 158 | IOError: If the specified file doesn't exist or cannot be read.
|
143 |
| - ValueError: If the refresh token file is invalid. |
| 159 | + ValueError: If the refresh token configuration is invalid. |
144 | 160 | """
|
145 | 161 | super(RefreshToken, self).__init__()
|
146 |
| - with open(file_path) as json_keyfile: |
147 |
| - json_data = json.load(json_keyfile) |
| 162 | + if isinstance(refresh_token, six.string_types): |
| 163 | + with open(refresh_token) as json_file: |
| 164 | + json_data = json.load(json_file) |
| 165 | + elif isinstance(refresh_token, dict): |
| 166 | + json_data = refresh_token |
| 167 | + else: |
| 168 | + raise ValueError( |
| 169 | + 'Invalid refresh token argument: "{0}". Refresh token argument must be a file ' |
| 170 | + 'path, or a dict containing the parsed file contents.'.format(refresh_token)) |
| 171 | + |
148 | 172 | if json_data.get('type') != self._CREDENTIAL_TYPE:
|
149 |
| - raise ValueError('Invalid refresh token file: "{0}". File must contain a ' |
150 |
| - '"type" field set to "{1}".'.format(file_path, self._CREDENTIAL_TYPE)) |
| 173 | + raise ValueError('Invalid refresh token configuration. JSON must contain a ' |
| 174 | + '"type" field set to "{0}".'.format(self._CREDENTIAL_TYPE)) |
151 | 175 | try:
|
152 | 176 | client_id = json_data['client_id']
|
153 | 177 | client_secret = json_data['client_secret']
|
154 | 178 | refresh_token = json_data['refresh_token']
|
155 | 179 | except KeyError as error:
|
156 |
| - raise ValueError('Failed to initialize a refresh token credential from file "{0}". ' |
157 |
| - 'Caused by: "{1}"'.format(file_path, error)) |
| 180 | + raise ValueError('Failed to initialize a refresh token credential. ' |
| 181 | + 'Caused by: "{0}"'.format(error)) |
158 | 182 | self._g_credential = credentials.Credentials(
|
159 | 183 | token=None, refresh_token=refresh_token,
|
160 | 184 | token_uri='https://accounts.google.com/o/oauth2/token',
|
|
0 commit comments