Sur Forgejo 15, la sous-commande forgejo admin user couvre le quotidien du
support (créer un compte, changer un mot de passe, générer un jeton, supprimer,
retirer un second facteur), mais elle ne sait ni verrouiller un compte, ni
promouvoir un compte existant en administrateur, ni révoquer un jeton : ces trois gestes passent
par l'API. Cette leçon s'adresse à l'administrateur qui reçoit les demandes
« j'ai perdu mon mot de passe », « mon jeton a fuité » ou « je change
de téléphone » et veut y répondre depuis un terminal, sans interface web.
Vous repartez avec quatre preuves : un compte au changement de mot de
passe forcé puis libéré, un compte verrouillé puis rétabli, un jeton
révoqué (avec le refus que l'on obtient d'abord), et un dépôt protégé par
le refus de supprimer son propriétaire sans --purge. Les commandes ont été
exécutées sur Forgejo 15.0.10, AlmaLinux 10, avec la pile de la leçon
Installer Forgejo LTS.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Lister les sous-commandes de
forgejo admin useret savoir ce qu'elles ne font pas. - Créer un compte et réinitialiser un mot de passe, avec ou sans changement forcé.
- Générer un jeton d'accès pour un utilisateur, puis le révoquer.
- Verrouiller et rétablir un compte, promouvoir un administrateur, par l'API.
- Supprimer un compte en protégeant ses dépôts, et retirer son second facteur.
- Contrôler la forge avec
forgejo doctor check.
Quels sont les prérequis ?
Section intitulée « Quels sont les prérequis ? »Il vous faut la forge des leçons précédentes : Forgejo 15 LTS derrière
Caddy dans /opt/forgejo-lab, le nom forge.lab.test et le compte
fjadmin
(installation), puis les
notions d'organisation et de jeton d'accès vues dans
Organisations, équipes et droits.
Les comptes venus d'un fournisseur d'identité, qui ne se gèrent pas tout à fait
comme des comptes locaux, sont ceux de la leçon
Brancher Forgejo sur OIDC.
Vous devez savoir lancer curl, lire un code HTTP, et ouvrir un navigateur pour constater une connexion : plusieurs preuves sont des pages
que seul le navigateur affiche. Pour rejouer l'enrôlement du second facteur,
prévoyez une application TOTP sur un téléphone (elle affiche un code à six
chiffres renouvelé toutes les 30 secondes). Les comptes de test (gina,
hank, dave) sont créés dans la leçon ; chaque mot de passe est généré dans
une variable du shell et jamais écrit en clair.
Quelles commandes Forgejo 15 propose-t-il pour les comptes ?
Section intitulée « Quelles commandes Forgejo 15 propose-t-il pour les comptes ? »La commande forgejo admin user en propose sept en 15.0.10 : create,
list, change-password, delete, generate-access-token,
must-change-password et reset-mfa. Tout ce qui n'y figure pas se
règle autrement. Le tableau dit où chercher selon la demande, et c'est la table
de décision de toute la leçon.
| Demande de l'utilisateur | Outil | Section |
|---|---|---|
| Voir les comptes | admin user list | lister |
| Nouvel arrivant | admin user create | créer |
| Mot de passe perdu | admin user change-password | réinitialiser |
| Jeton à fournir | admin user generate-access-token | jeton |
| Jeton compromis | DELETE /api/v1/users/{nom}/tokens/{jeton} | jeton |
| Suspendre un compte | API PATCH /api/v1/admin/users/{nom} (prohibit_login) | verrouiller |
| Donner ou retirer le rôle admin | API PATCH … (admin) | promouvoir |
| Départ | admin user delete | supprimer |
| Téléphone perdu | admin user reset-mfa | second facteur |
La sous-commande create accepte aussi --admin pour créer un administrateur, mais il n'existe pas de sous-commande qui promeuve un compte existant : la section sur les administrateurs montre l'API.
Préparez maintenant le shell : une fonction pour appeler Forgejo dans son conteneur, une autre pour l'API.
D=forge.lab.testfj() { sudo docker exec -u git forgejo forgejo "$@"; }ATK=$(fj admin user generate-access-token --username fjadmin --token-name "asst-$$" --scopes all --raw)api() { curl -sk -H "Authorization: token $ATK" -H 'Content-Type: application/json' "$@"; }code() { curl -sk -o /dev/null -w '%{http_code}' "$@"; }fj exécute forgejo en tant qu'utilisateur git dans le conteneur,
api appelle l'API avec le jeton d'administrateur et code n'affiche
que le code HTTP. L'option -k de curl ignore le certificat ; elle n'est
acceptable que parce que l'autorité est celle du lab. Le périmètre all du
jeton ne convient qu'à un lab jetable : sur une vraie forge, restreignez-le
comme l'indique la leçon sur les organisations.
Comment lister les comptes ?
Section intitulée « Comment lister les comptes ? »forgejo admin user list affiche l'identifiant, le nom, l'adresse e-mail,
l'état d'activation, le rôle d'administrateur et la présence d'un second
facteur de chaque compte. Avec --admin, elle ne garde que les
administrateurs. C'est le premier geste de tout dépannage : vérifier que le
compte existe, qu'il est actif et ce qu'il est.
fj admin user listfj admin user list --adminLa première commande affiche l'en-tête ID Username Email IsActive IsAdmin 2FA
puis une ligne par compte, par exemple fjadmin … true true false. La seconde
ne garde que les comptes administrateurs et n'affiche que les colonnes ID,
Username, Email et IsActive. La colonne 2FA vaut false tant
qu'aucun second facteur n'est enrôlé (le second facteur est la preuve
d'identité demandée en plus du mot de passe, par exemple un code TOTP). Le piège : cette liste ne dit pas
qu'un compte est verrouillé ; l'état de verrouillage se règle par l'API, ce
que montre la section dédiée.
Comment créer un compte pour un nouvel arrivant ?
Section intitulée « Comment créer un compte pour un nouvel arrivant ? »forgejo admin user create prend un nom, une adresse e-mail et un mot de
passe, et force par défaut le changement de ce mot de passe à la première
connexion. C'est le bon réglage : l'administrateur connaît le mot de passe
initial, l'utilisateur doit donc en choisir un autre. Créez gina.
P1=$(openssl rand -hex 10)fj admin user create --username gina --email gina@example.test --password "$P1"fj admin user list | grep -E 'ID|gina'La sortie est New user 'gina' has been successfully created!, puis la liste montre la ligne de gina, avec IsActive à true. Si la leçon de configuration a branché le courrier, une
ligne d'avertissement [W] sur le SMTP non chiffré peut précéder ce message,
sans conséquence. Ouvrez
https://forge.lab.test/user/login dans un navigateur, connectez-vous avec
gina et le mot de passe de $P1 (affichez-le avec echo "$P1" dans ce lab
seulement) : vous arrivez sur la page /user/settings/change_password, et
non sur le tableau de bord.
L'aide de la commande liste d'autres options : --admin, --restricted (compte restreint), --fullname, --random-password avec
--random-password-length, et --access-token avec --access-token-name et
--access-token-scopes. Nous ne les avons pas toutes jouées ; testez-les sur
une instance jetable. Le piège majeur est le mot de passe passé avec
--password : il figure dans la ligne de commande du processus, visible
avec ps par tous les utilisateurs de la machine pendant l'exécution. Sur un
serveur partagé, c'est une fuite ; limitez l'accès à la machine et préférez
l'option --random-password, que nous n'avons pas rejouée.
Comment réinitialiser un mot de passe oublié ?
Section intitulée « Comment réinitialiser un mot de passe oublié ? »forgejo admin user change-password remplace le mot de passe, et le
changement forcé est actif par défaut : l'utilisateur doit en choisir un autre
dès sa connexion. Passer --must-change-password le rend explicite ; pour
l'éviter, il faut écrire --must-change-password=false. Le mot de passe
connu de l'administrateur ne reste donc pas en vigueur. La commande ne demande
pas l'ancien mot de passe : le droit d'administration suffit.
P2=$(openssl rand -hex 10)fj admin user change-password --username gina --password "$P2" --must-change-passwordLa sortie est gina's password has been successfully updated!. Vérifiez
dans le navigateur : l'ancien mot de passe est refusé avec
Username or password is incorrect., le nouveau est accepté mais mène
de nouveau à /user/settings/change_password. Si l'utilisateur ne doit pas
changer son mot de passe (compte de service, par exemple), levez l'obligation.
fj admin user must-change-password --unset ginaLa sortie est Updated 1 users setting MustChangePassword to false, et
la connexion suivante arrive sur le tableau de bord. L'aide indique que la
commande vise « the provided users or all users » ; nous n'avons pas rejoué
l'option qui vise tous les comptes, relisez son aide avant de l'utiliser.
Le piège : pour un compte de service, oublier --must-change-password=false
redirige son premier usage vers /user/settings/change_password ; nous l'avons
observé avec change-password sans aucune option.
Comment générer puis révoquer un jeton d'accès ?
Section intitulée « Comment générer puis révoquer un jeton d'accès ? »generate-access-token crée un jeton pour un utilisateur donné, mais la
révocation n'a pas de commande : elle passe par l'API, où un administrateur
s'authentifie en Basic, avec son nom et son mot de passe, et non avec un jeton. Un jeton d'accès est
une clé personnelle qui remplace le mot de passe pour l'API ; sa fuite donne
les droits de son propriétaire jusqu'à sa révocation. Générez-en un pour gina
et vérifiez qu'il fonctionne.
TK=$(fj admin user generate-access-token --username gina --token-name t1 --scopes all --raw)echo "longueur ${#TK}, GET /user -> $(code -H "Authorization: token $TK" https://$D/api/v1/user)"fj admin user generate-access-token --username gina --token-name t1 --scopes all --raw 2>&1 | tail -1L'option --raw n'affiche que le jeton. La première ligne indique une
longueur de 40 caractères et un code 200. Le second appel, avec le
même nom, est refusé : Command error: access token name has been used already.
Le nom d'un jeton est donc unique par utilisateur. Essayez maintenant de le
révoquer avec le jeton de l'administrateur.
AP=$(sudo sed -n 's/^ADMIN_PASSWORD=//p' /opt/forgejo-lab/.env)echo "jeton admin -> $(code -X DELETE -H "Authorization: token $ATK" https://$D/api/v1/users/gina/tokens/t1)"echo "fjadmin (Basic) -> $(code -X DELETE -u "fjadmin:$AP" https://$D/api/v1/users/gina/tokens/t1)"echo "ancien jeton -> $(code -H "Authorization: token $TK" https://$D/api/v1/user)"La première ligne lit le mot de passe de fjadmin dans le .env posé à
l'installation, sans l'afficher. Les trois suivantes affichent 401,
204 puis 401. Le jeton d'administrateur est refusé : les routes
de jetons de l'API exigent une authentification Basic, ce que la
documentation de l'API Forgejo indique pour /users/{nom}/tokens. En Basic,
l'administrateur révoque le jeton de gina sans toucher à son mot de
passe : le 204 signale la suppression, et l'ancien jeton ne marche plus.
Ce geste ne vise que le jeton nommé : un autre jeton de gina reste valide,
et un utilisateur non administrateur qui tente la même requête en Basic
reçoit un 403 (rejoué sur un Forgejo 15.0.10 jetable). Pour un jeton
compromis, révoquez donc d'abord le jeton, puis demandez à l'utilisateur
quels autres jetons il a créés : la fuite d'un jeton dit rarement qu'il était
le seul exposé. Le piège classique est de réinitialiser le mot de passe
pour révoquer un jeton : l'utilisateur se retrouve dehors, alors que le jeton
se révoquait sans lui.
Comment verrouiller puis rétablir un compte ?
Section intitulée « Comment verrouiller puis rétablir un compte ? »Il n'existe pas de commande de verrouillage : on appelle l'API
PATCH /api/v1/admin/users/{nom} avec prohibit_login à true, en répétant
login_name et source_id. Ces deux champs sont obligatoires même si on
ne les modifie pas ; pour un compte local de ce lab, login_name est le nom du
compte et source_id vaut 0. Pour un compte venu d'un fournisseur d'identité,
relevez les deux valeurs dans la réponse de GET /api/v1/admin/users.
Créez d'abord un second jeton pour gina, qui servira de témoin, puis
verrouillez le compte.
TK2=$(fj admin user generate-access-token --username gina --token-name t2 --scopes all --raw)api -X PATCH https://$D/api/v1/admin/users/gina -d '{"login_name":"gina","source_id":0,"prohibit_login":true}' | python3 -c 'import sys,json;print("prohibit_login =",json.load(sys.stdin)["prohibit_login"])'echo "API Basic: $(code -u "gina:$P2" https://$D/api/v1/user) | jeton t2: $(code -H "Authorization: token $TK2" https://$D/api/v1/user)"La première ligne répond prohibit_login = True. L'API en Basic répond
401 et le jeton t2, qui existait avant le verrouillage, 403 : le
compte verrouillé ne sert plus à rien, même avec un jeton valide. Dans le
navigateur, une tentative de connexion de gina affiche une page
Account is suspended.
Rétablissez le compte avec la même requête et false.
api -X PATCH https://$D/api/v1/admin/users/gina -d '{"login_name":"gina","source_id":0,"prohibit_login":false}' >/dev/nullLa connexion web de gina arrive de nouveau sur le tableau de bord. Le
verrouillage est donc réversible : il ne supprime pas le compte, il en
bloque l'usage. Le piège : pour un départ définitif, un compte verrouillé
reste dans la base avec ses dépôts et ses droits ; la suppression, détaillée
plus bas, est le bon geste.
Comment promouvoir ou rétrograder un administrateur ?
Section intitulée « Comment promouvoir ou rétrograder un administrateur ? »La même route PATCH porte le champ admin : à true, le compte devient
administrateur, à false, il cesse de l'être. Comme le verrouillage, ce
geste n'a pas de commande, hors create --admin à la création. Faites-le
brièvement sur gina pour voir le résultat dans la liste.
api -X PATCH https://$D/api/v1/admin/users/gina -d '{"login_name":"gina","source_id":0,"admin":true}' >/dev/nullfj admin user list --adminapi -X PATCH https://$D/api/v1/admin/users/gina -d '{"login_name":"gina","source_id":0,"admin":false}' >/dev/nullLa liste des administrateurs contient maintenant fjadmin et gina.
Relancez-la après la rétrogradation pour constater que gina en a disparu.
Le rôle d'administrateur donne accès à toute la forge : donnez-le pour une
tâche précise, retirez-le ensuite, et tenez à jour la liste de ceux qui le
portent. Le principe général est celui du
moindre privilège.
Comment supprimer un compte sans perdre ses dépôts ?
Section intitulée « Comment supprimer un compte sans perdre ses dépôts ? »forgejo admin user delete refuse de supprimer un utilisateur qui possède
encore des dépôts, sauf avec --purge, qui supprime le compte et tout ce qu'il
possède. Ce refus est un garde-fou : la suppression sans --purge ne détruit
donc pas un dépôt par surprise. Créez hank et un dépôt à son nom.
fj admin user create --username hank --email hank@example.test --password "$(openssl rand -hex 10)" --must-change-password=false >/dev/nullTK3=$(fj admin user generate-access-token --username hank --token-name t --scopes all --raw)curl -sk -H "Authorization: token $TK3" -H 'Content-Type: application/json' -X POST https://$D/api/v1/user/repos -d '{"name":"hank-repo","auto_init":true}' >/dev/nullecho "dépôt : $(code -H "Authorization: token $ATK" https://$D/api/v1/repos/hank/hank-repo)"fj admin user delete --username hank 2>&1 | tail -1echo "après le refus : $(fj admin user list | grep -c hank) compte, dépôt $(code -H "Authorization: token $ATK" https://$D/api/v1/repos/hank/hank-repo)"Le dépôt répond 200. La suppression est refusée avec Command error: user still has ownership of repositories [uid: 9]
(l'identifiant varie), et la dernière ligne montre 1 compte et un dépôt
toujours à 200. Rien n'a été supprimé. Le piège : ce refus ne vaut
que s'il reste des dépôts : un compte sans dépôt, ivan dans notre essai, se
supprime sans --purge (code retour 0). Un compte encore membre d'une
organisation est refusé aussi, avec
Command error: user still has membership of organizations.
Pour aller au bout, ajoutez --purge. La documentation de la commande la
décrit ainsi : « Purge user, all their repositories, organizations and
comments ». Elle est irréversible : faites d'abord une sauvegarde, comme
le montre la leçon
Sauvegarder et restaurer Forgejo.
fj admin user delete --username hank --purgeecho "après la purge : $(fj admin user list | grep -c hank) compte, dépôt $(code -H "Authorization: token $ATK" https://$D/api/v1/repos/hank/hank-repo)"La dernière ligne affiche 0 compte et le dépôt à 404. Si le dépôt
doit survivre au départ, copiez-le ou changez-le de propriétaire avant la
purge : cette leçon ne rejoue pas le transfert, ni le sort des dépôts d'une
organisation.
Comment retirer le second facteur d'un utilisateur ?
Section intitulée « Comment retirer le second facteur d'un utilisateur ? »forgejo admin user reset-mfa supprime toutes les configurations de second
facteur d'un compte, et l'utilisateur se connecte de nouveau avec son seul mot
de passe. C'est le geste du téléphone perdu. Il ramène le compte à l'état d'avant
l'enrôlement ; l'utilisateur pourra en configurer un autre. Pour le voir,
enrôlez un compte local, par exemple dave.
fj admin user create --username dave --email dave@example.test --password "$(openssl rand -hex 10)" --must-change-password=false >/dev/null 2>&1fj admin user list | grep daveSi dave existe déjà (leçon précédente), la création échoue sans conséquence.
Connectez-vous comme dave dans le navigateur (le mot de passe est celui de
sa création, ou réinitialisez-le avec change-password), ouvrez /user/settings/security/two_factor/enroll sur la forge, scannez le code avec l'application TOTP, saisissez le premier code et validez. Quand
vous vous reconnectez, Forgejo demande le code sur la page
/user/two_factor : le second facteur est actif.
fj admin user reset-mfa --username daveLa sortie est dave's two-factor authentication settings have been removed!.
La connexion suivante arrive directement sur le tableau de bord. Le
piège est social : quiconque obtient un reset-mfa obtient un compte
protégé par un mot de passe seul. Vérifiez l'identité du demandeur par un
autre canal avant d'exécuter la commande, puis demandez à l'utilisateur de
réenrôler un second facteur. Si la forge impose le second facteur à tous,
comme le montre la leçon
Brancher Forgejo sur OIDC,
il le refera dès sa prochaine connexion.
Comment contrôler la forge avec forgejo doctor ?
Section intitulée « Comment contrôler la forge avec forgejo doctor ? »forgejo doctor check --list énumère les vérifications disponibles, et
forgejo doctor check --all les exécute toutes. Quand un utilisateur signale
un comportement étrange, c'est un contrôle de plus pour écarter une
incohérence de la base ou du stockage. La liste marque d'une étoile les
vérifications exécutées par défaut.
fj doctor check --list 2>&1 | head -14fj doctor check --all 2>&1 | tail -12La liste affiche un tableau Default Name Title, dont les vérifications par défaut paths, check-db-version, check-user-type et authorized-keys.
L'exécution complète se termine par All done (checks: 28), chaque
vérification imprimant OK ou ses constats. Dans nos essais, les six
dernières, dont celle des adresses e-mail et des noms d'utilisateur valides,
étaient toutes OK. Nous n'avons pas rejoué --fix ni --run <nom> : lisez
leur aide avant d'autoriser une réparation automatique.
Que faire quand une commande échoue ?
Section intitulée « Que faire quand une commande échoue ? »Les échecs de cette leçon sont courts et se lisent dans le message de la commande ou dans le code HTTP. Le tableau relie chacun à sa cause.
| Symptôme | Cause | Correction |
|---|---|---|
Command error: user still has ownership of repositories | le compte possède des dépôts | sauvegarder, déplacer ce qui doit survivre, puis --purge |
Command error: user still has membership of organizations | le compte est membre d'une équipe d'organisation | --purge (observé), ou le retirer de ses équipes (non rejoué) |
Command error: access token name has been used already | le nom du jeton existe déjà pour cet utilisateur | choisir un autre nom, ou révoquer l'ancien |
DELETE …/tokens/… répond 401 avec le jeton d'administrateur | la route exige une authentification Basic, pas un jeton | DELETE en Basic avec le mot de passe de fjadmin |
| Après verrouillage, API en Basic 401 et jeton existant 403 | prohibit_login à true : c'est le résultat voulu | rétablir avec prohibit_login à false |
Username or password is incorrect. après une réinitialisation | l'ancien mot de passe est toujours saisi | utiliser le mot de passe posé par change-password |
La connexion mène à /user/settings/change_password | le changement est forcé | choisir un mot de passe, ou lever avec must-change-password --unset |
Comment défaire cette configuration ?
Section intitulée « Comment défaire cette configuration ? »On supprime les comptes de test restants avec --purge. hank l'a déjà
été dans la section sur la suppression ; restent gina et dave.
fj admin user delete --username gina --purgefj admin user delete --username dave --purgefj admin user listLa liste ne contient plus ni gina, ni hank, ni dave. Le
jeton asst-… de fjadmin reste valable après la fermeture du shell :
révoquez-le comme t1, par un DELETE en authentification Basic avec le mot
de passe de fjadmin (variable ADMIN_PASSWORD du .env). Son nom est asst-
suivi du numéro du processus du shell où vous avez posé ATK (echo asst-$$
dans ce même shell), ou lisible dans les réglages de sécurité du compte.
À retenir
Section intitulée « À retenir »forgejo admin usera sept sous-commandes en 15.0.10 :create,list,change-password,delete,generate-access-token,must-change-password,reset-mfa.- Le verrouillage d'un compte, la promotion d'un administrateur et la révocation d'un jeton n'ont pas de commande : ils passent par l'API.
createetchange-passwordforcent par défaut le changement du mot de passe à la connexion suivante ;--must-change-password=falseoumust-change-password --unsetlève l'obligation.- La révocation d'un jeton par l'API refuse le jeton d'administrateur (401) ; un administrateur en authentification Basic révoque le jeton d'un autre compte (204) sans toucher à son mot de passe, et un non-administrateur en Basic reçoit 403 ; le nom d'un jeton est unique par utilisateur.
PATCH /api/v1/admin/users/{nom}avecprohibit_loginexigelogin_nameetsource_id; un compte verrouillé répond 401 en Basic, 403 avec un jeton existant, etAccount is suspendedsur le web.deletesans--purgeest refusé tant que le compte possède un dépôt ;--purgesupprime le compte et ses dépôts, de façon irréversible.reset-mfaretire tous les seconds facteurs d'un compte ; vérifiez l'identité du demandeur avant de l'exécuter.- Un mot de passe passé avec
--passwordest visible avecpspendant la commande, etforgejo doctor check --allcontrôle la forge (28 vérifications en 15.0.10).
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Six questions tirées sur huit : les sous-commandes de forgejo admin user, le changement forcé du mot de passe, la révocation d'un jeton, le verrouillage d'un compte et la suppression avec --purge.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Épreuve niveau 1 : mettre en service et gouverner une forge
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications