Prepare isolated Firebase push configuration for pre-production
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
"""Offline credential checks inside the configured container; never sends a push."""
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
import stat
|
||||
|
||||
from firebase_admin import credentials
|
||||
|
||||
from notifications import enabled
|
||||
|
||||
|
||||
class PreflightError(Exception):
|
||||
"""Only fixed diagnostic codes, never credential/SDK exception contents."""
|
||||
|
||||
|
||||
def check(expected_service_account):
|
||||
if not enabled():
|
||||
raise PreflightError('push_disabled')
|
||||
project = os.environ.get('FIREBASE_PROJECT_ID', '')
|
||||
if not project:
|
||||
raise PreflightError('project_missing')
|
||||
path = Path(os.environ.get('GOOGLE_APPLICATION_CREDENTIALS', ''))
|
||||
if str(path) != '/run/secrets/firebase-service-account.json':
|
||||
raise PreflightError('container_path_mismatch')
|
||||
try:
|
||||
info = path.stat()
|
||||
if not stat.S_ISREG(info.st_mode):
|
||||
raise PreflightError('credential_not_a_file')
|
||||
if info.st_mode & 0o077:
|
||||
raise PreflightError('credential_permissions_too_broad')
|
||||
if not os.statvfs(path).f_flag & os.ST_RDONLY:
|
||||
raise PreflightError('credential_mount_not_read_only')
|
||||
credential = credentials.Certificate(str(path))
|
||||
except PreflightError:
|
||||
raise
|
||||
except Exception:
|
||||
raise PreflightError('credential_missing_unreadable_or_invalid') from None
|
||||
if credential.project_id != project:
|
||||
raise PreflightError('credential_project_mismatch')
|
||||
if credential.service_account_email != expected_service_account:
|
||||
raise PreflightError('credential_service_account_mismatch')
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--expected-service-account', required=True,
|
||||
help='Expected service-account email, not a token or key')
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
check(args.expected_service_account)
|
||||
except PreflightError as error:
|
||||
print('FAIL: ' + str(error))
|
||||
return 1
|
||||
print('PASS: push enabled; read-only credential; project and service account match. '
|
||||
'No network request; IAM and delivery still require a smoke test.')
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user