Validate FCM service account credentials
This commit is contained in:
parent
a7f076514c
commit
6582b61dc4
|
|
@ -332,8 +332,12 @@ fcm_credentials =
|
|||
raise "Set only one of FCM_SERVICE_ACCOUNT_FILE or FCM_SERVICE_ACCOUNT_JSON_BASE64."
|
||||
end
|
||||
|
||||
if fcm_credentials && fcm_credentials["type"] != "service_account" do
|
||||
raise "The configured FCM credentials must be a Google service-account document."
|
||||
if fcm_credentials &&
|
||||
(fcm_credentials["type"] != "service_account" ||
|
||||
Enum.any?(["project_id", "client_email", "private_key"], fn field ->
|
||||
not is_binary(fcm_credentials[field]) or fcm_credentials[field] == ""
|
||||
end)) do
|
||||
raise "The configured FCM credentials must be a complete Google service-account document."
|
||||
end
|
||||
|
||||
fcm_configuration =
|
||||
|
|
|
|||
|
|
@ -70,6 +70,15 @@ contains_template_marker() {
|
|||
"$observed" == *example.com* || "$observed" == *example.invalid* ]]
|
||||
}
|
||||
|
||||
valid_fcm_service_account_json() {
|
||||
jq -e '
|
||||
.type == "service_account" and
|
||||
(.project_id | type == "string" and length > 0) and
|
||||
(.client_email | type == "string" and length > 0) and
|
||||
(.private_key | type == "string" and length > 0)
|
||||
' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
failures=0
|
||||
warnings=0
|
||||
|
||||
|
|
@ -178,16 +187,19 @@ elif [[ -z "$(value FCM_PROJECT_ID)" || (-n "$fcm_file" && -n "$fcm_base64") ||
|
|||
(-z "$fcm_file" && -z "$fcm_base64") ]]; then
|
||||
partial "Android FCM delivery" "project ID and exactly one credential source are required"
|
||||
elif [[ -n "$fcm_file" ]]; then
|
||||
if [[ "$fcm_file" == /* && -r "$fcm_file" ]]; then
|
||||
ready "Android FCM delivery" "readable service-account file is configured"
|
||||
if [[ "$fcm_file" == /* && -r "$fcm_file" ]] &&
|
||||
valid_fcm_service_account_json <"$fcm_file"; then
|
||||
ready "Android FCM delivery" "complete service-account file is configured"
|
||||
else
|
||||
invalid "Android FCM delivery" "FCM_SERVICE_ACCOUNT_FILE must be an absolute readable file"
|
||||
invalid "Android FCM delivery" \
|
||||
"FCM_SERVICE_ACCOUNT_FILE must be an absolute readable complete service-account JSON file"
|
||||
fi
|
||||
elif printf '%s' "$fcm_base64" | base64 --decode 2>/dev/null |
|
||||
jq -e '.type == "service_account" and (.project_id | type == "string")' >/dev/null 2>&1; then
|
||||
ready "Android FCM delivery" "valid Base64 service-account document is configured"
|
||||
valid_fcm_service_account_json; then
|
||||
ready "Android FCM delivery" "complete Base64 service-account document is configured"
|
||||
else
|
||||
invalid "Android FCM delivery" "Base64 credential is not a service-account JSON document"
|
||||
invalid "Android FCM delivery" \
|
||||
"Base64 credential is not a complete service-account JSON document"
|
||||
fi
|
||||
|
||||
if all_empty ANDROID_APP_LINKS_PACKAGE_NAME ANDROID_APP_LINKS_SHA256_CERT_FINGERPRINTS; then
|
||||
|
|
|
|||
|
|
@ -114,6 +114,26 @@ if { [ -n "$fcm_project_id" ] || [ -n "$fcm_service_account_json_base64" ]; } &&
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$fcm_service_account_json_base64" ]; then
|
||||
for command in base64 jq; do
|
||||
command -v "$command" >/dev/null 2>&1 || {
|
||||
echo "Required command is unavailable for FCM validation: $command" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
if ! printf '%s' "$fcm_service_account_json_base64" |
|
||||
base64 --decode 2>/dev/null |
|
||||
jq -e '
|
||||
.type == "service_account" and
|
||||
(.project_id | type == "string" and length > 0) and
|
||||
(.client_email | type == "string" and length > 0) and
|
||||
(.private_key | type == "string" and length > 0)
|
||||
' >/dev/null 2>&1; then
|
||||
echo "Production FCM credential is not a complete service-account JSON document." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$compose_project_name" in
|
||||
*[!a-zA-Z0-9_-]* | '')
|
||||
echo "PRODUCTION_COMPOSE_PROJECT_NAME must contain only letters, numbers, underscores, or hyphens." >&2
|
||||
|
|
|
|||
|
|
@ -125,6 +125,26 @@ if [[ (-n "$fcm_project_id" || -n "$fcm_service_account_json_base64") &&
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "$fcm_service_account_json_base64" ]]; then
|
||||
for command in base64 jq; do
|
||||
command -v "$command" >/dev/null 2>&1 || {
|
||||
echo "Required command is unavailable for FCM validation: $command" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
if ! printf '%s' "$fcm_service_account_json_base64" |
|
||||
base64 --decode 2>/dev/null |
|
||||
jq -e '
|
||||
.type == "service_account" and
|
||||
(.project_id | type == "string" and length > 0) and
|
||||
(.client_email | type == "string" and length > 0) and
|
||||
(.private_key | type == "string" and length > 0)
|
||||
' >/dev/null 2>&1; then
|
||||
echo "Test FCM credential is not a complete service-account JSON document." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
for pair in "HTTP:$http_port" "MAILPIT:$mailpit_port"; do
|
||||
value=${pair#*:}
|
||||
if [[ ! "$value" =~ ^[0-9]+$ ]] || ((value < 1 || value > 65535)); then
|
||||
|
|
|
|||
|
|
@ -117,7 +117,8 @@ test "$(sha256sum "$legacy_load_env" | awk '{print $1}')" = "$legacy_load_hash"
|
|||
|
||||
echo "Checking independent test and production environment initialization"
|
||||
quality_fcm_base64=$(
|
||||
printf '%s' '{"type":"service_account","project_id":"quality-production"}' |
|
||||
printf '%s' \
|
||||
'{"type":"service_account","project_id":"quality-production","client_email":"quality-fcm@quality-production.iam.gserviceaccount.com","private_key":"quality-private-key"}' |
|
||||
base64 -w 0
|
||||
)
|
||||
test_env="$scan_dir/test.env"
|
||||
|
|
@ -206,6 +207,25 @@ PRODUCTION_SUPPORT_INBOX_ADDRESS=support@help.test \
|
|||
test "$(stat -c '%a' "$production_env")" = 600
|
||||
./scripts/validate-production-env.sh "$production_env" help.test >/dev/null
|
||||
./scripts/check-environment-readiness.sh "$production_env" --require-release >/dev/null
|
||||
invalid_fcm_env="$scan_dir/production.invalid-fcm.env"
|
||||
invalid_fcm_base64=$(
|
||||
printf '%s' '{"type":"service_account","project_id":"quality-production"}' |
|
||||
base64 -w 0
|
||||
)
|
||||
cp "$production_env" "$invalid_fcm_env"
|
||||
sed -i \
|
||||
"s|^FCM_SERVICE_ACCOUNT_JSON_BASE64=.*|FCM_SERVICE_ACCOUNT_JSON_BASE64=$invalid_fcm_base64|" \
|
||||
"$invalid_fcm_env"
|
||||
if ./scripts/validate-production-env.sh \
|
||||
"$invalid_fcm_env" help.test >/dev/null 2>&1; then
|
||||
echo "Production validation accepted an incomplete FCM service account." >&2
|
||||
exit 1
|
||||
fi
|
||||
if ./scripts/check-environment-readiness.sh \
|
||||
"$invalid_fcm_env" --require-release >/dev/null 2>&1; then
|
||||
echo "Environment readiness accepted an incomplete FCM service account." >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -Fx 'COMPOSE_PROJECT_NAME=who_need_help_production' "$production_env" >/dev/null
|
||||
grep -E '^APP_IMAGE=who-need-help:production-[0-9a-f]{12}$' "$production_env" >/dev/null
|
||||
grep -Fx 'EDGE_COMPOSE_PROJECT_NAME=who_need_help_edge' "$production_env" >/dev/null
|
||||
|
|
|
|||
|
|
@ -59,6 +59,15 @@ require_value() {
|
|||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
valid_fcm_service_account_json() {
|
||||
jq -e '
|
||||
.type == "service_account" and
|
||||
(.project_id | type == "string" and length > 0) and
|
||||
(.client_email | type == "string" and length > 0) and
|
||||
(.private_key | type == "string" and length > 0)
|
||||
' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
reject_marker() {
|
||||
local key=$1
|
||||
local value=$2
|
||||
|
|
@ -378,10 +387,18 @@ if [[ -n "$fcm_project_id" || -n "$fcm_service_account_file" ||
|
|||
}
|
||||
|
||||
if [[ -n "$fcm_service_account_file" ]]; then
|
||||
command -v jq >/dev/null 2>&1 || {
|
||||
echo "Required command is unavailable for FCM validation: jq" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "$fcm_service_account_file" == /* && -r "$fcm_service_account_file" ]] || {
|
||||
echo "FCM_SERVICE_ACCOUNT_FILE must be an absolute readable file." >&2
|
||||
exit 1
|
||||
}
|
||||
valid_fcm_service_account_json <"$fcm_service_account_file" || {
|
||||
echo "FCM_SERVICE_ACCOUNT_FILE is not a complete service-account JSON document." >&2
|
||||
exit 1
|
||||
}
|
||||
else
|
||||
for command in base64 jq; do
|
||||
command -v "$command" >/dev/null 2>&1 || {
|
||||
|
|
@ -391,9 +408,8 @@ if [[ -n "$fcm_project_id" || -n "$fcm_service_account_file" ||
|
|||
done
|
||||
printf '%s' "$fcm_service_account_json_base64" |
|
||||
base64 --decode 2>/dev/null |
|
||||
jq -e '.type == "service_account" and (.project_id | type == "string")' \
|
||||
>/dev/null 2>&1 || {
|
||||
echo "FCM_SERVICE_ACCOUNT_JSON_BASE64 is not a service-account JSON document." >&2
|
||||
valid_fcm_service_account_json || {
|
||||
echo "FCM_SERVICE_ACCOUNT_JSON_BASE64 is not a complete service-account JSON document." >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -41,6 +41,15 @@ require_value() {
|
|||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
valid_fcm_service_account_json() {
|
||||
jq -e '
|
||||
.type == "service_account" and
|
||||
(.project_id | type == "string" and length > 0) and
|
||||
(.client_email | type == "string" and length > 0) and
|
||||
(.private_key | type == "string" and length > 0)
|
||||
' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
[[ "$(require_value DEPLOYMENT_ENV)" == test ]] || {
|
||||
echo "Test validation requires DEPLOYMENT_ENV=test." >&2
|
||||
exit 1
|
||||
|
|
@ -174,6 +183,34 @@ if [[ -n "$fcm_project_id" || -n "$fcm_service_account_file" ||
|
|||
echo "Test FCM project ID and exactly one credential source are required together." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ -n "$fcm_service_account_file" ]]; then
|
||||
command -v jq >/dev/null 2>&1 || {
|
||||
echo "Required command is unavailable for FCM validation: jq" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "$fcm_service_account_file" == /* && -r "$fcm_service_account_file" ]] || {
|
||||
echo "Test FCM_SERVICE_ACCOUNT_FILE must be an absolute readable file." >&2
|
||||
exit 1
|
||||
}
|
||||
valid_fcm_service_account_json <"$fcm_service_account_file" || {
|
||||
echo "Test FCM_SERVICE_ACCOUNT_FILE is not a complete service-account JSON document." >&2
|
||||
exit 1
|
||||
}
|
||||
else
|
||||
for command in base64 jq; do
|
||||
command -v "$command" >/dev/null 2>&1 || {
|
||||
echo "Required command is unavailable for FCM validation: $command" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
printf '%s' "$fcm_service_account_json_base64" |
|
||||
base64 --decode 2>/dev/null |
|
||||
valid_fcm_service_account_json || {
|
||||
echo "Test FCM_SERVICE_ACCOUNT_JSON_BASE64 is not a complete service-account JSON document." >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
fi
|
||||
|
||||
android_package=$(read_value ANDROID_APP_LINKS_PACKAGE_NAME 2>/dev/null || true)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user