diff --git a/nixos/modules/services/admin/pgadmin.nix b/nixos/modules/services/admin/pgadmin.nix index 439f8f0d0fd..390c80d1a2d 100644 --- a/nixos/modules/services/admin/pgadmin.nix +++ b/nixos/modules/services/admin/pgadmin.nix @@ -37,27 +37,76 @@ in }; initialEmail = mkOption { - description = lib.mdDoc "Initial email for the pgAdmin account."; + description = lib.mdDoc "Initial email for the pgAdmin account"; type = types.str; }; initialPasswordFile = mkOption { description = lib.mdDoc '' Initial password file for the pgAdmin account. - NOTE: Should be string not a store path, to prevent the password from being world readable. + NOTE: Should be string not a store path, to prevent the password from being world readable ''; type = types.path; }; + emailServer = { + enable = mkOption { + description = lib.mdDoc '' + Enable SMTP email server. This is necessary, if you want to use password recovery or change your own password + ''; + type = types.bool; + default = false; + }; + address = mkOption { + description = lib.mdDoc "SMTP server for email delivery"; + type = types.str; + default = "localhost"; + }; + port = mkOption { + description = lib.mdDoc "SMTP server port for email delivery"; + type = types.port; + default = 25; + }; + useSSL = mkOption { + description = lib.mdDoc "SMTP server should use SSL"; + type = types.bool; + default = false; + }; + useTLS = mkOption { + description = lib.mdDoc "SMTP server should use TLS"; + type = types.bool; + default = false; + }; + username = mkOption { + description = lib.mdDoc "SMTP server username for email delivery"; + type = types.nullOr types.str; + default = null; + }; + sender = mkOption { + description = lib.mdDoc '' + SMTP server sender email for email delivery. Some servers require this to be a valid email address from that server + ''; + type = types.str; + example = "noreply@example.com"; + }; + passwordFile = mkOption { + description = lib.mdDoc '' + Password for SMTP email account. + NOTE: Should be string not a store path, to prevent the password from being world readable + ''; + type = types.path; + }; + }; + openFirewall = mkEnableOption (lib.mdDoc "firewall passthrough for pgadmin4"); settings = mkOption { description = lib.mdDoc '' Settings for pgadmin4. - [Documentation](https://www.pgadmin.org/docs/pgadmin4/development/config_py.html). + [Documentation](https://www.pgadmin.org/docs/pgadmin4/development/config_py.html) ''; type = pyType; - default= {}; + default = { }; }; }; @@ -69,6 +118,13 @@ in SERVER_MODE = true; } // (optionalAttrs cfg.openFirewall { DEFAULT_SERVER = mkDefault "::"; + }) // (optionalAttrs cfg.emailServer.enable { + MAIL_SERVER = cfg.emailServer.address; + MAIL_PORT = cfg.emailServer.port; + MAIL_USE_SSL = cfg.emailServer.useSSL; + MAIL_USE_TLS = cfg.emailServer.useTLS; + MAIL_USERNAME = cfg.emailServer.username; + SECURITY_EMAIL_SENDER = cfg.emailServer.sender; }); systemd.services.pgadmin = { @@ -115,10 +171,14 @@ in group = "pgadmin"; }; - users.groups.pgadmin = {}; + users.groups.pgadmin = { }; environment.etc."pgadmin/config_system.py" = { - text = formatPy cfg.settings; + text = lib.optionalString cfg.emailServer.enable '' + with open("${cfg.emailServer.passwordFile}") as f: + pw = f.read() + MAIL_PASSWORD = pw + '' + formatPy cfg.settings; mode = "0600"; user = "pgadmin"; group = "pgadmin"; diff --git a/nixos/tests/pgadmin4.nix b/nixos/tests/pgadmin4.nix index 9f5ac3d8d92..f2809965977 100644 --- a/nixos/tests/pgadmin4.nix +++ b/nixos/tests/pgadmin4.nix @@ -106,15 +106,15 @@ import ./make-test-python.nix ({ pkgs, lib, buildDeps ? [ ], pythonEnv ? [ ], .. && sed -i 's|driver_local.maximize_window()||' web/regression/runtests.py" ) - # don't bother to test LDAP authentification - # exclude resql test due to recent postgres 14.4 update - # see bugreport here https://redmine.postgresql.org/issues/7527 + # Don't bother to test LDAP or kerberos authentification + # For now deactivate change_password API test. Current bug report at https://redmine.postgresql.org/issues/7648 + # Password change works from the UI, if email SMTP is configured. with subtest("run browser test"): machine.succeed( 'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \ && python regression/runtests.py \ --pkg browser \ - --exclude browser.tests.test_ldap_login.LDAPLoginTestCase,browser.tests.test_ldap_login,resql' + --exclude browser.tests.test_ldap_login.LDAPLoginTestCase,browser.tests.test_ldap_login,browser.tests.test_kerberos_with_mocking,browser.tests.test_change_password' ) # fontconfig is necessary for chromium to run @@ -126,11 +126,10 @@ import ./make-test-python.nix ({ pkgs, lib, buildDeps ? [ ], pythonEnv ? [ ], .. && python regression/runtests.py --pkg feature_tests' ) - # reactivate this test again, when the postgres 14.4 test has been fixed - # with subtest("run resql test"): - # machine.succeed( - # 'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \ - # && python regression/runtests.py --pkg resql' - # ) + with subtest("run resql test"): + machine.succeed( + 'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \ + && python regression/runtests.py --pkg resql' + ) ''; }) diff --git a/pkgs/tools/admin/pgadmin/default.nix b/pkgs/tools/admin/pgadmin/default.nix index dadd7982492..8dfcf078dbc 100644 --- a/pkgs/tools/admin/pgadmin/default.nix +++ b/pkgs/tools/admin/pgadmin/default.nix @@ -10,11 +10,11 @@ let pname = "pgadmin"; - version = "6.12"; + version = "6.13"; src = fetchurl { url = "https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v${version}/source/pgadmin4-${version}.tar.gz"; - sha256 = "sha256-cO7GdZDfJ0pq1jpMyrVy0UM49WhrKOIJOmMJauSkbyo="; + sha256 = "sha256-vLItmE76R1IzgMYEGEvIeOmbfQQac5WK12AkkZknTFU="; }; yarnDeps = mkYarnModules { @@ -72,13 +72,16 @@ let azure-identity ]; - # override necessary on pgadmin4 6.12 + # keep the scope, as it is used throughout the derivation and tests + # this also makes potential future overrides easier pythonPackages = python3.pkgs.overrideScope (final: prev: rec { - werkzeug = prev.werkzeug.overridePythonAttrs (oldAttrs: rec { - version = "2.0.3"; + # flask 2.2 is incompatible with pgadmin 6.13 + # https://redmine.postgresql.org/issues/7651 + flask = prev.flask.overridePythonAttrs (oldAttrs: rec { + version = "2.1.3"; src = oldAttrs.src.override { inherit version; - sha256 = "sha256-uGP4/wV8UiFktgZ8niiwQRYbS+W6TQ2s7qpQoWOCLTw="; + sha256 = "sha256-FZcuUBffBXXD1sCQuhaLbbkCWeYgrI1+qBOjlrrVtss="; }; }); }); @@ -124,7 +127,7 @@ pythonPackages.buildPythonApplication rec { # build the documentation cd docs/en_US - ${sphinx}/bin/sphinx-build -W -b html -d _build/doctrees . _build/html + sphinx-build -W -b html -d _build/doctrees . _build/html # Build the clean tree cd ../../web @@ -156,7 +159,7 @@ pythonPackages.buildPythonApplication rec { cp -v ../pkg/pip/setup_pip.py setup.py ''; - nativeBuildInputs = with pythonPackages; [ cython pip ]; + nativeBuildInputs = with pythonPackages; [ cython pip sphinx ]; buildInputs = [ zlib pythonPackages.wheel diff --git a/pkgs/tools/admin/pgadmin/update.sh b/pkgs/tools/admin/pgadmin/update.sh new file mode 100755 index 00000000000..d7ca19bbddd --- /dev/null +++ b/pkgs/tools/admin/pgadmin/update.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p curl wget jq yarn2nix yarn common-updater-scripts + +set -eu -o pipefail + +scriptDir=$(cd "${BASH_SOURCE[0]%/*}" && pwd) +nixpkgs=$(realpath "$scriptDir"/../../../..) + +newest_version="$(curl -s https://www.pgadmin.org/versions.json | jq -r .pgadmin4.version)" +old_version=$(nix-instantiate --eval -E "(import \"$nixpkgs\" { config = {}; overlays = []; }).pgadmin4.version" | tr -d '"') +url="https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v${newest_version}/source/pgadmin4-${newest_version}.tar.gz" + +if [[ $newest_version == $old_version ]]; then + echo "Already at latest version $newest_version" + exit 0 +fi +echo "New version: $newest_version" + +pushd $(mktemp -d --suffix=-pgadmin4-updater) +wget $url +tar -xzf "pgadmin4-$newest_version.tar.gz" +cd "pgadmin4-$newest_version/web" +yarn2nix > yarn.nix +cp yarn.nix yarn.lock package.json "$nixpkgs/pkgs/tools/admin/pgadmin/" +popd + +update-source-version pgadmin4 "$newest_version" --print-changes