Skip to content

Commit

Permalink
feat: gpg sign commits (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
lsagetlethias authored Jan 18, 2025
1 parent fcfbe11 commit 9ce3b2c
Show file tree
Hide file tree
Showing 20 changed files with 199 additions and 67 deletions.
5 changes: 3 additions & 2 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ NEXT_PUBLIC_BRAND_OPERATOR_LOGO_ORIENTATION=horizontal
TEMPLATES_TMPDIR="./templates_tmp"
TEMPLATES_ADMINS="lilian.sagetlethias,julien.bouquillon"
TEMPLATES_GIT_URL="https://github.com/incubateur-ademe/legal-site-templates-test"
TEMPLATES_GIT_GPG_PRIVATE_KEY=""
TEMPLATES_GIT_GPG_PASSPHRASE=""
TEMPLATES_GIT_GPG_PRIVATE_KEY_BASE64=
TEMPLATES_GIT_GPG_PUBLIC_KEY_BASE64=
TEMPLATES_GIT_COMMITTER_EMAIL="[email protected]"
TEMPLATES_GIT_COMMITTER_NAME="Bot"
TEMPLATES_GIT_MAIN_BRANCH="main"
Expand All @@ -44,6 +44,7 @@ MAILER_FROM_EMAIL="Pages Légales Faciles <[email protected]>"

## Security
SECURITY_JWT_SECRET="sikretfordevonly"
SECURITY_WEBHOOK_SECRET=="sikretfordevonly"

## Redis
REDIS_BASE="pages-legales-faciles"
Expand Down
4 changes: 3 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ ESPACE_MEMBRE_API_KEY=
# TEMPLATES_TMPDIR="./templates_tmp"
# TEMPLATES_ADMINS="lilian.sagetlethias,julien.bouquillon"
TEMPLATES_GIT_URL=
# TEMPLATES_GIT_GPG_PRIVATE_KEY=""
# TEMPLATES_GIT_GPG_PRIVATE_KEY_BASE64=""
# TEMPLATES_GIT_GPG_PUBLIC_KEY_BASE64=""
# TEMPLATES_GIT_GPG_PASSPHRASE=""
TEMPLATES_GIT_COMMITTER_EMAIL="[email protected]"
TEMPLATES_GIT_COMMITTER_NAME="Bot"
Expand All @@ -49,6 +50,7 @@ MAILER_SMTP_SSL=false

## Security
SECURITY_JWT_SECRET=
SECURITY_WEBHOOK_SECRET=

## Redis (url or host/port/password)
# REDIS_BASE="pages-legales-faciles"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Build

on:
push:
branches: [main]
branches: [main, dev]
pull_request:
branches: [main]
branches: [dev]

concurrency:
cancel-in-progress: true
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ name: "CodeQL"

on:
push:
branches: ["main"]
branches: [main, dev]
pull_request:
# The branches below must be a subset of the branches above
branches: ["main"]
branches: [dev]
schedule:
- cron: "16 1 * * 5"

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Lint

on:
push:
branches: [main]
branches: [main, dev]
pull_request:
branches: [main]
branches: [dev]

concurrency:
cancel-in-progress: true
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/teardown-review-db.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: Teardown review db on PR close

on:
pull_request:
branches: [dev]
types:
- closed

Expand Down
2 changes: 1 addition & 1 deletion Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: yarn start
web: ./scripts/import_gpg.sh && yarn start
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
- [ ] possibilité de recover un fichier supprimé (si fonction de suppression)
- [ ] possibilité de rollback à une version précédente (ajout d'une version rollback comme nouvelle version)
- [x] anticiper le fait d'avoir plusieurs mentions legales si plusieurs produit (d'ou le "[variableId]"), sinon "default" par défaut
- [ ] GPG pour les commits
- [x] GPG pour les commits
- [x] teardown "db" review app/pr avec github actions

## Navigation
Expand Down
7 changes: 7 additions & 0 deletions cron.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"jobs": [
{
"command": "0 0 * * * ./scripts/call_gpg_refresh_webhook.sh"
}
]
}
29 changes: 15 additions & 14 deletions db/seed/templates/default/mentions-legales.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,37 @@ variables:
nom_hebergeur: Nom de l'hébergeur
adresse_herbergeur: Adresse de l'hébergeur
---
# Mentions légales de {{nom_produit}}
# Mentions légales de {{ nom_produit }}

## Editeur de la Plateforme
La Plateforme **{{nom_produit}}** est éditée par {{nom_editeur}} situé :
<address>
{{ adresse_editeur }}
La Plateforme **{{ nom_produit }}** est éditée par {{ nom_editeur }} situé :
<address class="fr-mb-2w">
<span>{{ adresse_editeur }}</span>
<br/>
<a href="tel:{{ telephone_editeur }}">{{ telephone_editeur }}</a>
<a class="fr-mt-0" href="tel:{{ telephone_editeur }}">{{ telephone_editeur }}</a>
<br/>
<a href="mailto:{{ email_editeur }}">{{ email_editeur }}</a>
</address>

## Directeur de la publication
{{directeur_publication}}
{{ directeur_publication }}

## Hébergement de la Plateforme
Ce site est hébergé en propre par {{ nom_hebergeur}} :
<br />
<address>{{ adresse_herbergeur }}</address>
Ce site est hébergé en propre par {{ nom_hebergeur }} :

<address class="fr-mb-2w">{{ adresse_herbergeur }}</address>

## Accessibilité
La conformité aux normes daccessibilité numérique est un objectif ultérieur mais nous tâchons de rendre ce site accessible à toutes et à tous.
La conformité aux normes d'accessibilité numérique est un objectif ultérieur mais nous tâchons de rendre ce site accessible à toutes et à tous.

### Signaler un dysfonctionnement
Si vous rencontrez un défaut daccessibilité vous empêchant daccéder à un contenu ou une fonctionnalité du site, merci de nous en faire part.
Si vous nobtenez pas de réponse rapide de notre part, vous êtes en droit de faire parvenir vos doléances ou une demande de saisine au Défenseur des droits.
Si vous rencontrez un défaut d'accessibilité vous empêchant d'accéder à un contenu ou une fonctionnalité du site, merci de nous en faire part.
Si vous n'obtenez pas de réponse rapide de notre part, vous êtes en droit de faire parvenir vos doléances ou une demande de saisine au Défenseur des droits.

### En savoir plus
Pour en savoir plus sur la politique daccessibilité numérique de lÉtat : http://references.modernisation.gouv.fr/accessibilite-numerique
Pour en savoir plus sur la politique d'accessibilité numérique de l'État : [http://references.modernisation.gouv.fr/accessibilite-numerique](http://references.modernisation.gouv.fr/accessibilite-numerique)

## Sécurité
Le site est protégé par un certificat électronique, matérialisé pour la grande majorité des navigateurs par un cadenas. Cette protection participe à la confidentialité des échanges.
En aucun cas les services associés à la plateforme ne seront à l’origine d’envoi de courriels pour demander la saisie d’informations personnelles.
En aucun cas les services associés à la plateforme ne seront à l'origine d'envoi de courriels pour demander la saisie d'informations personnelles.

14 changes: 10 additions & 4 deletions env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ Française`
* No dist value.
* {@link [Local Env Dist](.env.development)}
*/
TEMPLATES_GIT_GPG_PRIVATE_KEY?: string;
TEMPLATES_GIT_GPG_PRIVATE_KEY_BASE64?: string;
/**
* No dist value.
* {@link [Local Env Dist](.env.development)}
*/
TEMPLATES_GIT_GPG_PASSPHRASE?: string;
TEMPLATES_GIT_GPG_PUBLIC_KEY_BASE64?: string;
/**
* Dist: `[email protected]`
* {@link [Local Env Dist](.env.development)}
Expand Down Expand Up @@ -178,6 +178,11 @@ Française`
* {@link [Local Env Dist](.env.development)}
*/
SECURITY_JWT_SECRET?: string;
/**
* Dist: `="sikretfordevonly"`
* {@link [Local Env Dist](.env.development)}
*/
SECURITY_WEBHOOK_SECRET?: string;
/**
* Dist: `pages-legales-faciles`
* {@link [Local Env Dist](.env.development)}
Expand Down Expand Up @@ -291,8 +296,8 @@ declare type ProcessEnvCustomKeys =
| 'TEMPLATES_TMPDIR'
| 'TEMPLATES_ADMINS'
| 'TEMPLATES_GIT_URL'
| 'TEMPLATES_GIT_GPG_PRIVATE_KEY'
| 'TEMPLATES_GIT_GPG_PASSPHRASE'
| 'TEMPLATES_GIT_GPG_PRIVATE_KEY_BASE64'
| 'TEMPLATES_GIT_GPG_PUBLIC_KEY_BASE64'
| 'TEMPLATES_GIT_COMMITTER_EMAIL'
| 'TEMPLATES_GIT_COMMITTER_NAME'
| 'TEMPLATES_GIT_MAIN_BRANCH'
Expand All @@ -306,6 +311,7 @@ declare type ProcessEnvCustomKeys =
| 'MAILER_SMTP_SSL'
| 'MAILER_FROM_EMAIL'
| 'SECURITY_JWT_SECRET'
| 'SECURITY_WEBHOOK_SECRET'
| 'REDIS_BASE'
| 'REDIS_HOST'
| 'REDIS_PORT'
Expand Down
2 changes: 1 addition & 1 deletion next-sitemap.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const priorities = {
/** @type {import('next-sitemap').IConfig} */
const config = {
generateRobotsTxt: false,
siteUrl: isDeployment ? `https://${process.env.NEXT_PUBLIC_SITE_URL}` : "http://localhost:3000",
siteUrl: isDeployment ? `${process.env.NEXT_PUBLIC_SITE_URL}` : "http://localhost:3000",
changefreq: "weekly",
transform: async (config, path) => {
return {
Expand Down
3 changes: 2 additions & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const csp = {
"'self'",
"'unsafe-inline'",
process.env.NEXT_PUBLIC_MATOMO_URL,
process.env.NODE_ENV === "development" && "'unsafe-eval' http://localhost",
"'unsafe-eval'",
process.env.NODE_ENV === "development" && "http://localhost",
],
"style-src": ["'self'", "'unsafe-inline'"],
"object-src": ["'self'", "data:"],
Expand Down
15 changes: 4 additions & 11 deletions scalingo.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,36 @@
}
],
"scripts": {
"first-deploy": "NODE_ENV=development yarn install --frozen-lockfile && NODE_ENV=production yarn seed && rm -rf node_modules"
"first-deploy": "./scripts/import_gpg.sh && NODE_ENV=development yarn install --frozen-lockfile && NODE_ENV=production yarn seed && rm -rf node_modules"
},
"env": {
"APP_ENV": {
"description": "État applicatif custom. Valeurs possibles : 'review', 'staging', 'dev', ou 'prod'",
"value": "review"
},
"MAINTENANCE_MODE": {
"description": "Affiche ou non une page de maintenance au lieu d'une navigation normale.",
"value": "false"
},
"NODE_ENV": {
"description": "Node environment",
"value": "production"
},
"NEXT_PUBLIC_BRAND_NAME": {
"description": "Nom de la marque",
"generator": "template",
"template": "%APP%"
},
"TEMPLATES_GIT_MAIN_BRANCH": {
"description": "Nom de la branche principale du dépôt git contenant les templates",
"generator": "template",
"template": "%APP%"
},
"TEMPLATES_GIT_URL": {
"description": "URL du dépôt git contenant les templates",
"value": "https://github.com/incubateur-ademe/pages-legales-faciles-db-staging"
},
"SECURITY_JWT_SECRET": {
"description": "Secret pour la génération des JWT",
"generator": "secret"
},
"SECURITY_WEBHOOK_SECRET": {
"generator": "secret"
},
"REDIS_URL": {
"description": "URL du serveur Redis",
"value": "$SCALINGO_REDIS_URL"
},
"AUTH_URL": {
Expand All @@ -61,11 +56,9 @@
"value": "1"
},
"NEXT_PUBLIC_REPOSITORY_URL": {
"description": "URL du dépôt git du projet",
"value": "https://github.com/incubateur-ademe/pages-legales-faciles"
},
"NEXT_PUBLIC_SITE_URL": {
"description": "URL du site",
"generator": "url"
}
}
Expand Down
20 changes: 20 additions & 0 deletions scripts/call_gpg_refresh_webhook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

if [ -n "$TEMPLATES_GIT_GPG_PASSPHRASE" ]; then
# URL de l'API et clé API
API_URL="$NEXT_PUBLIC_SITE_URL/api/webhook/gpg/refresh"
API_KEY="$SECURITY_WEBHOOK_SECRET"

# Exécuter la requête avec curl
response=$(curl -s -X GET "$API_URL" -H "x-api-key: $API_KEY")

# Vérifier si la requête a réussi
if echo "$response" | grep -q '"ok":true'; then
echo "Succès : $(echo "$response" | jq -r '.message')"
else
echo "Erreur : $(echo "$response" | jq -r '.error')"
fi
else
echo "$(date): No TEMPLATES_GIT_GPG_PASSPHRASE provided. Skipping refresh." >&2
exit 1
fi
52 changes: 52 additions & 0 deletions scripts/import_gpg.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash

# Vérifier si les clés publiques et privées sont définies
if [ -z "$TEMPLATES_GIT_GPG_PRIVATE_KEY_BASE64" ] || [ -z "$TEMPLATES_GIT_GPG_PUBLIC_KEY_BASE64" ]; then
echo "Clés GPG non définies. Signature des commits désactivée."
exit 0
fi

echo "Les clés GPG sont présentes dans les variables d'environnement. Importation en cours..."

# Importer la clé privée
echo -n "$TEMPLATES_GIT_GPG_PRIVATE_KEY_BASE64" | base64 --decode | gpg --batch --import
if [ $? -ne 0 ]; then
echo "Erreur : Échec de l'importation de la clé privée."
exit 1
fi

# Importer la clé publique
echo -n "$TEMPLATES_GIT_GPG_PUBLIC_KEY_BASE64" | base64 --decode | gpg --batch --import
if [ $? -ne 0 ]; then
echo "Erreur : Échec de l'importation de la clé publique."
exit 1
fi

echo "Clés GPG importées avec succès."

TEMPLATE_GIT_GPG_SIGNINKEY="$(gpg --list-secret-keys --keyid-format LONG | grep sec | awk '{print $2}' | cut -d'/' -f2)"

# Configurer gpg-agent pour le mode non interactif
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
echo "default-cache-ttl 115200 " >> ~/.gnupg/gpg-agent.conf # 32 heures (en secondes)
echo "max-cache-ttl 115200" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent

# Injecter la passphrase dans le cache si nécessaire
if [ -n "$TEMPLATES_GIT_GPG_PASSPHRASE" ]; then
gpg --batch --yes --pinentry-mode loopback --default-key "$TEMPLATE_GIT_GPG_SIGNINKEY" --passphrase "$TEMPLATES_GIT_GPG_PASSPHRASE" --sign <<< "refresh-cache"
if [ $? -eq 0 ]; then
echo "Passphrase injectée avec succès dans le cache."
else
echo "Erreur : Échec de l'injection de la passphrase dans le cache."
exit 1
fi
fi

# Configurer Git pour utiliser la clé GPG
git config --global user.signingkey "$TEMPLATE_GIT_GPG_SIGNINKEY"
git config --global commit.gpgSign true
git config --global gpg.program gpg

echo "Configuration GPG terminée."
16 changes: 16 additions & 0 deletions scripts/refresh_gpg_passphrase.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

TEMPLATE_GIT_GPG_SIGNINKEY="$(gpg --list-secret-keys --keyid-format LONG | grep sec | awk '{print $2}' | cut -d'/' -f2)"
# Vérifie et rafraîchit le cache GPG
if [ -n "$TEMPLATES_GIT_GPG_PASSPHRASE" ]; then
gpg --batch --yes --pinentry-mode loopback --default-key "$TEMPLATE_GIT_GPG_SIGNINKEY" --passphrase "$TEMPLATES_GIT_GPG_PASSPHRASE" --sign <<< "refresh-cache" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "$(date): GPG cache refreshed successfully for 32 hours."
else
echo "$(date): Failed to refresh GPG cache." >&2
exit 1
fi
else
echo "$(date): No TEMPLATES_GIT_GPG_PASSPHRASE provided. Skipping refresh." >&2
exit 1
fi
Loading

0 comments on commit 9ce3b2c

Please sign in to comment.