diff --git a/.gitignore b/.gitignore index b2be92b..87a3018 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ result +*.qcow2 diff --git a/flake.nix b/flake.nix index 757108a..943b84d 100644 --- a/flake.nix +++ b/flake.nix @@ -59,6 +59,11 @@ specialArgs = inputs; modules = [ ./hosts/vm/livre ] ++ baseModules; }; + + mediakiwi = nixosSystem { + specialArgs = inputs; + modules = [ ./hosts/vm/mediakiwi ] ++ baseModules; + }; neo = nixosSystem { specialArgs = inputs; diff --git a/hosts/vm/mediakiwi/WSOAuth.patch b/hosts/vm/mediakiwi/WSOAuth.patch new file mode 100644 index 0000000..5da4498 --- /dev/null +++ b/hosts/vm/mediakiwi/WSOAuth.patch @@ -0,0 +1,38 @@ +diff --git a/src/WSOAuth.php b/src/WSOAuth.php +index 3a94c87..e077b9e 100644 +--- a/src/WSOAuth.php ++++ b/src/WSOAuth.php +@@ -308,11 +308,12 @@ class WSOAuth extends PluggableAuth { + // Set $realname and $email to the values returned from the authentication provider, if they are available + $realname = $remoteUserInfo['realname'] ?? null; + $email = $remoteUserInfo['email'] ?? null; ++ $username = ucfirst( $remoteUserInfo['name'] ); + +- $remoteUsername = ucfirst( $remoteUserInfo['name'] ); +- $localUserId = $this->getLocalAccountID( $remoteUsername ); ++ $remoteUserId = $remoteUserInfo['remoteUserId'] ?? $username; ++ $localUserId = $this->getLocalAccountID( $remoteUserId ); + +- $this->session->set( self::WSOAUTH_REMOTE_USERNAME_SESSION_KEY, $remoteUsername ); ++ $this->session->set( self::WSOAUTH_REMOTE_USERNAME_SESSION_KEY, $remoteUserId ); + $this->session->save(); + + if ( $localUserId !== 0 ) { +@@ -326,7 +327,7 @@ class WSOAuth extends PluggableAuth { + $currentUser = RequestContext::getMain()->getUser(); + $currentUserId = $currentUser->getId(); + +- $this->createMapping( $currentUserId, $remoteUsername ); ++ $this->createMapping( $currentUserId, $remoteUserId ); + + // Log the account in like normal + $username = $currentUser->getName(); +@@ -339,7 +340,7 @@ class WSOAuth extends PluggableAuth { + throw new ContinuationException( wfMessage( "wsoauth-remote-only-accounts-disabled" )->parse() ); + } + +- $desiredLocalUsername = $this->useRealNameAsUsername && $realname !== null ? $realname : $remoteUsername; ++ $desiredLocalUsername = $this->useRealNameAsUsername && $realname !== null ? $realname : $username; + $userId = User::newFromName( $desiredLocalUsername )->idForName(); + + if ( $userId > 0 && $this->migrateUsersByUsername ) { diff --git a/hosts/vm/mediakiwi/WSONoteKfetAuth/README b/hosts/vm/mediakiwi/WSONoteKfetAuth/README new file mode 100644 index 0000000..b13c920 --- /dev/null +++ b/hosts/vm/mediakiwi/WSONoteKfetAuth/README @@ -0,0 +1,14 @@ +# NoteKfetAuth + +Extension pour médiawiki pour ajouter le support de l'autentification par Note +via l'extension WSOAuth. + +## Installation + +Il faut enregistrer l'extension comme provider + +``` +$wgOAuthCustomAuthProviders = [ + 'note' => WSOAuth\AuthenticationProvider\NoteKfetAuth::class +]; +``` diff --git a/hosts/vm/mediakiwi/WSONoteKfetAuth/extension.json b/hosts/vm/mediakiwi/WSONoteKfetAuth/extension.json new file mode 100644 index 0000000..d4c303d --- /dev/null +++ b/hosts/vm/mediakiwi/WSONoteKfetAuth/extension.json @@ -0,0 +1,25 @@ +{ + "name": "WSONoteKfetAuth", + "author": [ + "Pyjacpp" + ], + "url": "https://gitlab.crans.org/nounous/nixos/-/tree/main/hosts/vm/mediakiwi/WSONoteKfetAuth", + "description": "Implementation of the NoteKfet OAuth2 for the WSOAuth extension", + "type": "other", + "requires": { + "MediaWiki": ">= 1.35.0", + "extensions": { + "WSOAuth": ">= 9.0" + } + }, + "AutoloadNamespaces": { + "WSOAuth\\AuthenticationProvider\\": "src/" + }, + "config": { + "NoteKfetUrl": { + "description": "The url of the NoteKfet.", + "value": "https://note.crans.org/" + } + }, + "manifest_version": 2 +} diff --git a/hosts/vm/mediakiwi/WSONoteKfetAuth/src/NoteKfetAuth.php b/hosts/vm/mediakiwi/WSONoteKfetAuth/src/NoteKfetAuth.php new file mode 100644 index 0000000..4a04205 --- /dev/null +++ b/hosts/vm/mediakiwi/WSONoteKfetAuth/src/NoteKfetAuth.php @@ -0,0 +1,149 @@ +clientId = $clientId; + $this->clientSecret = $clientSecret; + } + + /** + * @inheritDoc + */ + public function login( ?string &$key, ?string &$secret, ?string &$authUrl ): bool { + + // This state is used to prevent CSRF, i.e., ensuring that authentification request + // were initiated on our website. + $state = random_int(PHP_INT_MIN, PHP_INT_MAX); + $secret = "$state"; + $authUrl = $GLOBALS['wgNoteKfetUrl'] . "o/authorize/?" . http_build_query([ + 'client_id' => $this->clientId, + 'response_type' => 'code', + 'scope' => '1_1', + 'state' => $secret, + ]); + + return true; + } + + /** + * @inheritDoc + */ + public function logout( UserIdentity &$user ): void { + } + + /** + * @inheritDoc + */ + public function getUser( string $key, string $secret, &$errorMessage ) { + if ( !isset( $_GET['code'] ) ) { + return false; + } + + if ( !isset( $_GET['state'] ) || empty( $_GET['state'] ) || ( $_GET['state'] !== $secret ) ) { + return false; + } + + try { + $token = $this->getAccessTokens( $_GET['code'] ); + $userInfos = $this->getUserInfos( $token ); + + return [ + 'name' => $this->sanitizeName( "$userInfos->normalized_name (note)" ), + 'realname' => $userInfos->username, + 'email' => $userInfos->email, + 'remoteUserId' => $userInfos->id, + ]; + } catch ( \Exception $e ) { + return false; + } + } + + private function sanitizeName( string $name ) { + // We replace forbidden chars. + $res = preg_replace('/[#\/:<>=@\|]/', '-', $name); + $res = preg_replace(['/[\[{]/', '/[\]}]/'], ['(', ')'], $res); + $res = str_replace('_', ' ', $res); + // We remove the last controls chars possibly remaining. + return preg_replace('/[^a-zA-Z0-9 !\"$%&\'()*+,\-.;?\\\^`~]/', '', $res); + } + + private function getAccessTokens( string $code ) { + $data = [ + 'grant_type' => 'authorization_code', + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + 'code' => $code, + ]; + + $options = [ + 'http' => [ + 'method' => 'POST', + 'header' => 'Content-type: application/x-www-form-urlencoded', + 'content' => http_build_query($data), + ], + ]; + + $context = stream_context_create($options); + $response = file_get_contents($GLOBALS['wgNoteKfetUrl'] . 'o/token/', false, $context); + $tokens = json_decode($response); + return $tokens->access_token; + } + + private function getUserInfos( string $token ) { + $options = [ + 'http' => [ + 'method' => 'GET', + 'header' => "Authorization: Bearer $token", + ], + ]; + + $context = stream_context_create($options); + $response = file_get_contents($GLOBALS['wgNoteKfetUrl'] . 'api/me/', false, $context); + return json_decode($response); + } + + /** + * @inheritDoc + */ + public function saveExtraAttributes( int $id ): void { + } +} diff --git a/hosts/vm/mediakiwi/category-lockdown.patch b/hosts/vm/mediakiwi/category-lockdown.patch new file mode 100644 index 0000000..185ab41 --- /dev/null +++ b/hosts/vm/mediakiwi/category-lockdown.patch @@ -0,0 +1,98 @@ +diff --git a/CategoryLockdown.php b/CategoryLockdown.php +index 3309c52..f2cef51 100644 +--- a/CategoryLockdown.php ++++ b/CategoryLockdown.php +@@ -1,6 +1,7 @@ + getUserGroupManager()->getUserGroups( $user ); + $implicitGroups = MediaWikiServices::getInstance()->getUserGroupManager()->getUserImplicitGroups( $user ); +@@ -25,6 +28,11 @@ class CategoryLockdown { + return; + } + ++ // Rules doesn’t apply to the whitelist ++ if ( in_array( $title, $wgCategoryLockdownWhitelist ) ) { ++ return; ++ } ++ + $categories = array_keys( $title->getParentCategories() ); + + // Apply rules to the category page itself +@@ -32,16 +40,11 @@ class CategoryLockdown { + $categories[] = $title->getFullText(); + } + ++ // Support "Category:Top_secret", "Category:Top secret", "Top_secret" and "Top secret" ++ $categories = array_map( fn($c) => str_replace( '_', ' ', substr( $c, strpos( $c, ':' ) + 1 ) ), $categories ); + $combinedGroups = []; + foreach ( $categories as $category ) { +- // Support "Category:Top_secret", "Category:Top secret", "Top_secret" and "Top secret" +- $category = substr( $category, strpos( $category, ':' ) + 1 ); +- $category = str_replace( '_', ' ', $category ); + $permissions = $wgCategoryLockdown[ $category ] ?? null; +- if ( !$permissions ) { +- $category = str_replace( ' ', '_', $category ); +- $permissions = $wgCategoryLockdown[ $category ] ?? null; +- } + if ( !$permissions ) { + continue; + } +@@ -56,15 +59,40 @@ class CategoryLockdown { + $combinedGroups[] = $allowedGroup; + } + } +- if ( $combinedGroups ) { +- foreach ( $userGroups as $userGroup ) { +- if ( in_array( $userGroup, $combinedGroups ) ) { +- return; +- } ++ ++ $allow = false; ++ foreach ( $userGroups as $userGroup ) { ++ if ( in_array( $userGroup, $combinedGroups ) ) { ++ $allow = true; ++ break; + } ++ } ++ if ( $combinedGroups && !$allow ) { + $result = [ 'categorylockdown-error', implode( ', ', $combinedGroups ) ]; + return false; + } ++ ++ $allow = true; ++ foreach ( $wgCategoryGroupLockdown as $group => $groupCategories ) { ++ if ( str_starts_with( $group, "!") ? ++ in_array( substr($group, 1), $userGroups ) : ++ !in_array( $group, $userGroups ) ) { ++ continue; # Skip if this group rule doesn’t match the user ++ } ++ ++ $requiredCat = $groupCategories[$action] ?? []; ++ $groupLocked = true; ++ foreach ( $requiredCat as $c ) { ++ if ( in_array( $c, $categories ) ) { ++ $groupLocked = false; ++ break; # One of the category is present, we can grant this action. ++ } ++ } ++ if ( $groupLocked ) { ++ $result = [ 'categorylockdown-error', implode( ', ', $requiredCat ) ]; ++ return false; # This group of users need a category from groupCategories on this page to perform $action ++ } ++ } + } + + /** diff --git a/hosts/vm/mediakiwi/default.nix b/hosts/vm/mediakiwi/default.nix new file mode 100644 index 0000000..bba9007 --- /dev/null +++ b/hosts/vm/mediakiwi/default.nix @@ -0,0 +1,28 @@ +{ ... }: + +{ + imports = [ + ./hardware-configuration.nix + ./mediawiki.nix + + ../../../modules + ../../../modules/crans/nullmailer.nix + ]; + + networking.hostName = "mediakiwi"; + boot.loader.grub.devices = [ "/dev/sda" ]; + + crans = { + enable = true; + + networking = { + id = 144; + srvNat.enable = true; + }; + + # Enable when deploying the real mediakiwi + resticClient.enable = false; + }; + + system.stateVersion = "25.05"; +} diff --git a/hosts/vm/mediakiwi/hardware-configuration.nix b/hosts/vm/mediakiwi/hardware-configuration.nix new file mode 100644 index 0000000..de32983 --- /dev/null +++ b/hosts/vm/mediakiwi/hardware-configuration.nix @@ -0,0 +1,31 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/74148438-bd6e-4c19-a41c-d20c907f1fc1"; + fsType = "ext4"; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.ens18.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/hosts/vm/mediakiwi/mediawiki.nix b/hosts/vm/mediakiwi/mediawiki.nix new file mode 100644 index 0000000..446e13e --- /dev/null +++ b/hosts/vm/mediakiwi/mediawiki.nix @@ -0,0 +1,292 @@ +{ + lib, + pkgs, + config, + ... +}: + +let + version = pkgs.mediawiki.version; + major = lib.versions.major version; + minor = lib.versions.minor version; + phpExtensions = config.services.mediawiki.phpPackage.extensions; +in +{ + age.secrets.mediawiki-admin-passwd = { + file = ../../../secrets/mediakiwi/mediawiki-admin-passwd.age; + owner = "mediawiki"; + }; + + age.secrets.mediawiki-ldap = { + file = ../../../secrets/mediakiwi/mediawiki-ldap.age; + owner = "mediawiki"; + }; + + age.secrets.mediawiki-oauth = { + file = ../../../secrets/mediakiwi/mediawiki-oauth.age; + owner = "mediawiki"; + }; + + environment.systemPackages = with pkgs; [ + imagemagick + + # For the PdfHandler extension + ghostscript + poppler-utils + ]; + + services.phpfpm.pools.mediawiki.phpOptions = '' + upload_max_filesize = 512M + post_max_size = 512M + max_execution_time = 1000 + max_input_time = 2000 + default_socket_timeout = 2000 + extension = ${phpExtensions.mbstring}/lib/php/extensions/mbstring.so + extension = ${phpExtensions.luasandbox}/lib/php/extensions/luasandbox.so + ''; + + services.nginx.clientMaxBodySize = "512M"; + + services.syslogd.enable = true; + + services.mediawiki = { + enable = true; + + name = "Wiki Crans"; + + nginx.hostName = "mediawiki.crans.org"; + + webserver = "nginx"; + + passwordFile = config.age.secrets.mediawiki-admin-passwd.path; + + extraConfig = '' + # TODO remove log error in test + error_reporting( -1 ); + ini_set('display_errors', 1); + ini_set('display_startup_errors', 1); + + # Server settings + $wgFavicon = 'https://www.crans.org/images/favicon.ico'; + $wgLogo = 'https://www.crans.org/images/crans.svg'; + + # Files and Uploads + $wgMaxUploadSize = 512 * 1024 * 1024; + $wgUseImageMagick = true; + $wgImageMagickConvertCommand = '${pkgs.imagemagick}/bin/convert'; + $wgStrictFileExtensions = false; + $wgFileExtensions[] = 'pdf'; + $wgFileExtensions[] = 'svg'; + + # Limite mémoire, quand on fait de gros importi (9M de xml), le parser + # prends plus que 50M + $wgMemoryLimit = 512 * 1024 * 1024; + + # E-mail settings + $wgEnableEmail = true; + # $wgSMTP = [ + # 'host' => 'smtp.adm.crans.org', + # 'IDHost' => 'crans.org', + # 'localhost' => 'crans.org', + # 'port' => , + # 'auth' => false, + # # 'username' => , + # # 'password' => , + # ]; + $wgPasswordSender = 'root@crans.org'; + $wgEmergencyContact = 'contact@crans.org'; + $wgNoReplyAddress = 'root@crans.org'; + $wgEnableUserEmail = false; + # $wgEnableSpecialMute = true; + $wgAllowHTMLEmail = true; + + $wgEnotifUseRealName = false; + $wgEnotifFromEditor = false; + $wgEnotifRevealEditorAddress = false; + $wgEnotifUserTalk = true; + $wgEnotifMinorEdits = true; + $wgEnotifWatchlist = true; + # Peut-être utilisé pour les Wikistes + $wgUsersNotifiedOnAllChanges = []; + + # Auth + $wgPluggableAuth_EnableLocalLogin = true; + $LDAPAuthentication2AllowLocalLogin = true; + $LDAPProviderDomainConfigs = "${config.age.secrets.mediawiki-ldap.path}"; + $wgOAuthCustomAuthProviders = [ + 'note' => WSOAuth\AuthenticationProvider\NoteKfetAuth::class + ]; + $wgPluggableAuth_Config = [ + "Compte Crans" => [ + 'plugin' => 'LDAPAuthentication2', + 'data' => [ + 'domain' => 'crans' + ] + ], + "Note BDE" => [ + 'plugin' => 'WSOAuth', + 'data' => require('${config.age.secrets.mediawiki-oauth.path}'), + ] + ]; + + # Theme + $wgDefaultSkin = 'citizen'; + $wgCitizenThemeColor = '#AD1F1F'; + $wgCitizenEnableARFonts = true; + $wgCitizenEnableCJKFonts = true; + + $wgLanguageCode = 'fr'; + $wgLocaltimezone = 'Europe/Paris'; + $wgDefaultUserOptions['timecorrection'] = 'ZoneInfo|0|' . $wgLocaltimezone; + + # Access Control + $wgGroupPermissions['*']['edit'] = false; # Restrict edition for anonymous user + $wgGroupPermissions['*']['createaccount'] = false; # Restrict the creation of account to sysop only + + $wgCategoryLockdownWhitelist = [ + "Spécial:Connexion", + "Spécial:Connexion/return", + "Spécial:PluggableAuthLogin", + "Spécial:Recherche", + "MediaWiki:Common.css", + "MediaWiki:Common.js" + ]; + + $wgCategoryGroupLockdown["!user"]["read"] = [ "Page Publique" ]; # Restrict read for non-user (i.e. anonymous) on execpt for Page Publique # Extensions + $wgWikiEditorRealtimePreview = true; + $wgCiteBookReferencing = true; + $wgPdfProcessor = '${pkgs.ghostscript}/bin/gs'; + $wgPdfPostProcessor = $wgImageMagickConvertCommand; + $wgPdfInfo = '${pkgs.poppler-utils}/bin/pdfinfo'; + $wgPdftoText = '${pkgs.poppler-utils}/bin/pdftotext'; + $wgScribuntoDefaultEngine = 'luasandbox'; + + # Custom Namespaces + define("NS_ARCHIVE", 3000); + define("NS_ARCHIVE_TALK", 3001); + $wgExtraNamespaces = [ + NS_ARCHIVE => "Archive", + NS_ARCHIVE_TALK => "Discussion_archive", + ]; + + # Debug + $wgShowExceptionDetails = true; + $wgDebugToolbar = true; + $wgDebugLogFile = "/var/log/mediawiki/debug.log"; + # $wgShowDebug = true; + # $wgDevelopmentWarnings = true; + ''; + + skins = { + Citizen = pkgs.fetchFromGitHub { + name = "Citizen"; + owner = "StarCitizenTools"; + repo = "mediawiki-skins-Citizen"; + tag = "v3.17.0"; + sha256 = "sha256-IPwfI2ldzis3Zni5QSsrSfi0Qt6+xjOupPJk+j7P6aM="; + }; + }; + + extensions = { + # Enables embedded extensions + AbuseFilter = null; # pour faire de la modération + CategoryTree = null; # pour faire des arbres de catégories + Cite = null; # pour faire des références/footnotes + CiteThisPage = null; # pour avoir la citation (à la bibtex) d'une page + CodeEditor = null; # pour éditer des macros/scripts wiki + DiscussionTools = null; # pour des pages de discussion intéractives + Echo = null; # pour le système de notification du wiki + Gadgets = null; # pour avoir un système d'outils activable par les users + ImageMap = null; # pour mettre des widgets sur des images + Linter = null; # requis pour DiscussionTools + Math = null; # pour avoir des maths LaTeX + MultimediaViewer = null; # pour avoir un affichage sympa des images + Nuke = null; # pour purger des pages + PageImages = null; # pour set la bonne image représentant un article + ParserFunctions = null; # pour la logique et les fonctions de base du templating + PdfHandler = null; # pour afficher les pdfs + Poem = null; # pour afficher des blocks de texte respectant l'espacement (poèmes, écrits) + ReplaceText = null; # pour du méga-renommage à travers le wiki + Scribunto = null; # pour faire du scripting et des templates pour le wiki + SyntaxHighlight_GeSHi = null; # pour avoir de la coloration syntaxique + TemplateData = null; # pour faire de la doc sur les templates + TemplateStyles = null; # pour styliser les templates (bundlé pour la prochaine version de mediawiki) + TextExtracts = null; # pour set le bon text représentant un article + Thanks = null; # pour remercier des gens en notif + TitleBlacklist = null; # pour faire de la modération + VisualEditor = null; # pour éditer visuellement les pages + WikiEditor = null; # pour éditer le code wiki des pages + + CategoryLockdown = pkgs.applyPatches { + src = pkgs.fetchFromGitHub { + name = "CategoryLockdown"; + owner = "wikimedia"; + repo = "mediawiki-extensions-CategoryLockdown"; + rev = "REL" + major + "_" + minor; + # Le SHA doit être changé à chaque nouveau commit de traduction. + # Pas de meilleure solution à ma connaissance pour suivre les releases. + sha256 = "sha256-lrBhevfXs1Eyi69uvF/+qs/+wzOsKm0SLbnY8lD6pp4="; + }; + patches = [ + # Cette extension s’occupe des du contrôle d’accès du Wiki + # et a été beaucoup patché. Pensez à vérifier les changements + # et révisez le patch le cas échéant. + "${./category-lockdown.patch}" + ]; + }; + + # Popups + Popups = pkgs.fetchFromGitHub { + name = "Popups"; + owner = "wikimedia"; + repo = "mediawiki-extensions-Popups"; + rev = "REL" + major + "_" + minor; + # Le SHA doit être changé à chaque nouveau commit de traduction. + # Pas de meilleure solution à ma connaissance pour suivre les releases. + sha256 = "sha256-wNI6LnpGrpUA96Nr+4+KbuislKXTGyyua2F3N+t2O1s="; + }; + + # Auth + PluggableAuth = pkgs.fetchFromGitHub { + name = "PluggableAuth"; + owner = "wikimedia"; + repo = "mediawiki-extensions-PluggableAuth"; + rev = "REL" + major + "_" + minor; + # Le SHA doit être changé à chaque nouveau commit de traduction. + # Pas de meilleure solution à ma connaissance pour suivre les releases. + sha256 = "sha256-ZGw0Wgz0Sg04YDcOzkOGywmfQ6s6Ex17QbjmUDO1D8c="; + }; + LDAPProvider = pkgs.fetchFromGitHub { + name = "LDAPProvider"; + owner = "wikimedia"; + repo = "mediawiki-extensions-LDAPProvider"; + tag = "3.1.0"; + # Le SHA doit être changé à chaque nouveau commit de traduction. + # Pas de meilleure solution à ma connaissance pour suivre les releases. + sha256 = "sha256-9/5Uph5C6VPWT7NzrPsYpM9pxZPIQneKZDPFCaYm1e8="; + }; + LDAPAuthentication2 = pkgs.fetchFromGitHub { + name = "LDAPAuthentication2"; + owner = "wikimedia"; + repo = "mediawiki-extensions-LDAPAuthentication2"; + tag = "3.1.0"; + # Le SHA doit être changé à chaque nouveau commit de traduction. + # Pas de meilleure solution à ma connaissance pour suivre les releases. + sha256 = "sha256-/9VISvpvhaVq/sAHE10INlTju7+PTirFO/6U68WBOgM="; + }; + WSOAuth = pkgs.applyPatches { + src = pkgs.fetchFromGitHub { + name = "WSOAuth"; + owner = "wikimedia"; + repo = "mediawiki-extensions-WSOAuth"; + rev = "REL" + major + "_" + minor; + # Le SHA doit être changé à chaque nouveau commit de traduction. + # Pas de meilleure solution à ma connaissance pour suivre les releases. + sha256 = "sha256-04VCOKfrgrijrv9CdjXeaExmAsxIEWcWMz8W2KVutGI="; + }; + patches = [ "${./WSOAuth.patch}" ]; + }; + WSONoteKfetAuth = "${./WSONoteKfetAuth}"; + }; + }; +} diff --git a/secrets.nix b/secrets.nix index b052873..e7a004e 100644 --- a/secrets.nix +++ b/secrets.nix @@ -40,6 +40,7 @@ let collabora = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFa2D9fREtO2r2oIx6q9JAKFUHtxGbgEPMjkx09DQSU8 root@collabora"; jitsi = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB6jVMIZ5y2oXX9HOkw7r5UUjw95MlFaFuu7FnEC0Q8z root@jitsi"; livre = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEVfKNokHG6ig32hhQxTep+fKFmKahlDClPrX/dP4/gb root@livre"; + mediakiwi = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAiCZU+gdUt2jOxR0niVFsNzw0LIleYvwNhMFIANR5YE root@mediakiwi"; neo = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMGfSvxqC2PJYRrxJaivVDujwlwCZ6AwH8hOSA9ktZ1V root@neo"; nextcloud = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMgSP9UmuJw8Bi2ML07WHsWvxN8akkc9XZxXyOgdjXkq root@nextcloud"; periodique = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHTdfSIL3AWIv0mjRDam6E/qsjoqwJ8QSm1Cb0xqs1s1 root@periodique"; diff --git a/secrets/common/root.age b/secrets/common/root.age index e1b76db..2df9ddc 100644 Binary files a/secrets/common/root.age and b/secrets/common/root.age differ diff --git a/secrets/mediakiwi/mediawiki-admin-passwd.age b/secrets/mediakiwi/mediawiki-admin-passwd.age new file mode 100644 index 0000000..644c203 --- /dev/null +++ b/secrets/mediakiwi/mediawiki-admin-passwd.age @@ -0,0 +1,33 @@ +age-encryption.org/v1 +-> ssh-ed25519 vZ8Vgw cJhdOIkMufEIHU+LqOAs4/KTxOiiBL1Knl8ChkApajM +lSJiqVLy8KS0+pD0MSDgtD2IdMD7toVof4u8zFbc534 +-> piv-p256 ewCc3w A4oqsiewlX50Psnk7HT3nRGHd3+pdgb21kN8Zk1hPwKa +GAsqMgKtKRCSroHria5qAWSY8XqOUmHDMRCXdLOIJdQ +-> piv-p256 6CL/Pw A67ODihOF1IhvLWhUsIWAQVmhO/XTJ6GRznS4GkJwxOO +3zriXUAIS3RLhVDmeCzFka4LerN3/fgIJRyKmJatIFg +-> ssh-ed25519 eOAUSg px/iV0OQ9ZtNyNJsPIWdEbmemBKaXqfcD4Ew85HcVAo +7LMHrNse0MjlLNlAwbMexIcSRjK1vDkLSoEfJAtRmLU +-> ssh-rsa REaZBA +ewC5fAfzqr04uPsw9l3E8PZKoKIDACP1U5lEnL2++04zv7w9GL0eEHa693leB9z0 +OJNhq2FHU+NH2IofoLm/k46ma3XVWaCNExYiSaRQWo7Cm6fON2F+K32tJaxeFc9n +xCE7E5YM75e1U9LOqSPdfoeuWUg5iLDhg4uauMPagCgKA5Dd0ndClZyNWYK2C7NQ +V6MhczLs6cxrFEOQoaudlXnj7TDAiCdVLFmvlas56+QqVA2SXfM+xha3flfkZvR4 +rdcUY/y0ZBoLaZF+K0f2gcqDlL8VgvYFizIPTRAZYEKdMytSJbxv4LFb64E85Lwe +JFWPCp1lBTVhDFeulN7XBYYOCacw1Pyj+n3at2GIPEZwhnl6++NtBuiWj+g3Cnfr +BomwuFlcZmykI3p4qzPlwcHaAeY4UhzciNo+frDMKCUhUmczBoRMK45oa8nv5AC3 +z2h8OZGtKNpg55/FZJ9NONr/GA3xR74iB6chpANx8h6e8QDnUo9FZyl+qZcQ/Ghr + +-> ssh-ed25519 J/iReg IFdFOpdEUjMHdunUN7vfJ09lkDLA/SPOQY4b8UjT0S8 +qQEZnxKcLpbhc3u1zE3QCI8X/XTCRuWOwPsOL2SzdzI +-> ssh-ed25519 GNhSGw 6aFCUFK8BqLZrP5m1qGYxdRihpaoJyueHJa/00T/ZHM +Jfa1/KfD1JCYdIsdF6h+FjV3yozWfiscNWv2Krkdjz8 +-> ssh-ed25519 eXMAtA sFwZS3oq80e8CfDruygKRW1oP5aGfpHqeOrqEcoRL0o +lYaTFhvGXqVnd7WHFZXe8FZ9pWtk6dL9M6h3DC3Eov4 +-> ssh-ed25519 5hXocQ 4eznATzeJliAZkVeR69DD2Gr8YKWcarlSSOEPjk9Cxg +Rd6iAIj7jCs7/sDisd9ErKG63bA6jW07XqY4MdKBGjA +-> ssh-ed25519 bRHVVA YSXkgUVhRpXYbbeVpsdLZzncNIysYNrLvc5q3JTaLWI +g9xoh/G4NnKmjXPuLy5flQCjVYGbkAR5RHOqnhi95/U +-> ssh-ed25519 HgW9eA 4uEzjQxKg8KIXPGyMRdXdJb4BPC5ZTRok9tAXa6AwwQ +BXnFdGZlCjYakDN81w1fxF2P94b2ZAZAhlBsbM3I3PA +--- ragIvYUEISd+PwMW5KyGj0r7HOZQiHIDbY6vHewuZ1I +KJ׀ % Xplvt!q^aܠt|"&7 \ No newline at end of file diff --git a/secrets/mediakiwi/mediawiki-ldap.age b/secrets/mediakiwi/mediawiki-ldap.age new file mode 100644 index 0000000..b28cc2b Binary files /dev/null and b/secrets/mediakiwi/mediawiki-ldap.age differ diff --git a/secrets/mediakiwi/mediawiki-oauth.age b/secrets/mediakiwi/mediawiki-oauth.age new file mode 100644 index 0000000..e442571 Binary files /dev/null and b/secrets/mediakiwi/mediawiki-oauth.age differ diff --git a/secrets/restic/mediakiwi/base-password.age b/secrets/restic/mediakiwi/base-password.age new file mode 100644 index 0000000..f7742d3 --- /dev/null +++ b/secrets/restic/mediakiwi/base-password.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 vZ8Vgw +B57yVih+Nm3HaJfX53NcVTIUChaN4QRHpIhNRh0wig +2Icnq7jf1+suEjUYnQ1ABx3gdTefT6eZJ6KVEupA3Xg +-> piv-p256 ewCc3w A2uBciAE9cSCBJWLowDc4d5D4GQsroJ1EX3BJsr0w8+T +FUJZET8ck71xPBh2eWF8930JacE89+R2n2i32hFhAlg +-> piv-p256 6CL/Pw AgCcZy/RvYFO4WZz5/Os29sXgkDGdDLSPl4ZBdJjONPk +J7eaYHcgnrLEm4PMVh8qXHB8g/qpx7huoRgHNgO2aXw +-> ssh-ed25519 I2EdxQ +7WH3VaqC48ABO8Wpcb7hlY04lhKetfyYm3+62JESFo +iZXrtZ0+UFdvcn75ceJ6gxdXc410BZdgnPSaJsG3muA +-> ssh-ed25519 J/iReg rUhw71duo5PP4M3ySN7xHW1ebsXJ6iYFdj3eZUriGgA +pSAHL6A9lCJ5qFqK26PJLG84d6nIs4psL3ea5Pd8Tac +-> ssh-ed25519 GNhSGw zRjF+gRLm7IibS6joIBlOInFygsHVo7vf10IsYWx20o +93aGm4IS9bc/noU/2l3sMAKJbf5EkDU5gDDxDDdomak +-> ssh-ed25519 eXMAtA 2QLLIa6MylYi7h0KOyeZCxQQuyMPtcRTWu5Mg8oRpSI +VwWCwogmcmAQs86ABxxbuWdK7XWh071HPdQdPeeS7I8 +-> ssh-ed25519 5hXocQ AIMNW8H9VIA/wabPNGB54KGv2OT4iUtX4b6emWTpYk0 +vIj14LjtUcJ2GVDrStg40xHjpkEAkv53qnXdtaweuAk +--- iqSZN2bLs1BukHdpv8L48ir+5W4DeJ4ZviSn2hj9Eqc +w? +pjsN m)}Z,!|3#K֖^&o,0/K1J ;'-QۜG +@ 1޹?pز .][5D$+ #9ۛ$Pj_˓Tqx9sH8=;1WSj+"Hݐ\_1ygGP \ No newline at end of file diff --git a/secrets/restic/mediakiwi/base-repo.age b/secrets/restic/mediakiwi/base-repo.age new file mode 100644 index 0000000..65e03c8 Binary files /dev/null and b/secrets/restic/mediakiwi/base-repo.age differ