From cb62bf497925f7edafe79467c96666c642c8255f Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Mon, 13 Apr 2020 23:40:39 +0200 Subject: [PATCH 1/9] python.pkgs.sqlsoup: init at 0.9.1 --- .../python-modules/sqlsoup/default.nix | 21 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 pkgs/development/python-modules/sqlsoup/default.nix diff --git a/pkgs/development/python-modules/sqlsoup/default.nix b/pkgs/development/python-modules/sqlsoup/default.nix new file mode 100644 index 00000000000..a6ffd3227cd --- /dev/null +++ b/pkgs/development/python-modules/sqlsoup/default.nix @@ -0,0 +1,21 @@ +{ buildPythonPackage, fetchPypi, lib, sqlalchemy, nose }: + +buildPythonPackage rec { + pname = "sqlsoup"; + version = "0.9.1"; + + src = fetchPypi { + inherit pname version; + sha256 = "1mj00fhxj75ac3i8xk9jmm7hvcjz9p4x2r3yndcwsgb659rvgbrg"; + }; + + propagatedBuildInputs = [ sqlalchemy ]; + checkInputs = [ nose ]; + + meta = with lib; { + description = "A one step database access tool, built on the SQLAlchemy ORM"; + homepage = "https://bitbucket.org/zzzeek/sqlsoup"; + license = licenses.mit; + maintainers = [ maintainers.globin ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index cb5cbb5375a..cef7faa534e 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -5786,6 +5786,8 @@ in { sqlalchemy-utils = callPackage ../development/python-modules/sqlalchemy-utils { }; + sqlsoup = callPackage ../development/python-modules/sqlsoup { }; + staticjinja = callPackage ../development/python-modules/staticjinja { }; statsmodels = callPackage ../development/python-modules/statsmodels { }; From 7a68da69ba966093855c9286ad7ee00564ecf3ea Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Mon, 13 Apr 2020 23:59:37 +0200 Subject: [PATCH 2/9] python.pkgs.pyrad: init at 2.3 --- .../python-modules/pyrad/default.nix | 27 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 29 insertions(+) create mode 100644 pkgs/development/python-modules/pyrad/default.nix diff --git a/pkgs/development/python-modules/pyrad/default.nix b/pkgs/development/python-modules/pyrad/default.nix new file mode 100644 index 00000000000..31cbf77d94e --- /dev/null +++ b/pkgs/development/python-modules/pyrad/default.nix @@ -0,0 +1,27 @@ +{ buildPythonPackage, fetchFromGitHub, lib, netaddr, six, nose }: + +buildPythonPackage rec { + pname = "pyrad"; + version = "2.3"; + + src = fetchFromGitHub { + owner = "pyradius"; + repo = pname; + rev = version; + sha256 = "0hy7999av47s8100afbhxfjb8phbmrqcv530xlvskndby4a8w94k"; + }; + + propagatedBuildInputs = [ netaddr six ]; + checkInputs = [ nose ]; + + checkPhase = '' + nosetests -e testBind + ''; + + meta = with lib; { + description = "Python RADIUS Implementation"; + homepage = "https://bitbucket.org/zzzeek/sqlsoup"; + license = licenses.mit; + maintainers = [ maintainers.globin ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index cef7faa534e..ad05977984c 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -5180,6 +5180,8 @@ in { pyrabbit2 = callPackage ../development/python-modules/pyrabbit2 { }; + pyrad = callPackage ../development/python-modules/pyrad { }; + pyrr = callPackage ../development/python-modules/pyrr { }; pysha3 = callPackage ../development/python-modules/pysha3 { }; From 1a2852b447e97bae0967f00a4451ece6936762ac Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Tue, 14 Apr 2020 00:09:48 +0200 Subject: [PATCH 3/9] python.pkgs.flask-versioned: init at 0.9.4-20101221 --- .../flask-versioned/default.nix | 23 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 25 insertions(+) create mode 100644 pkgs/development/python-modules/flask-versioned/default.nix diff --git a/pkgs/development/python-modules/flask-versioned/default.nix b/pkgs/development/python-modules/flask-versioned/default.nix new file mode 100644 index 00000000000..c4e9f16bceb --- /dev/null +++ b/pkgs/development/python-modules/flask-versioned/default.nix @@ -0,0 +1,23 @@ +{ stdenv, buildPythonPackage, fetchFromGitHub, flask }: + +buildPythonPackage rec { + pname = "Flask-Versioned"; + version = "0.9.4-20101221"; + + src = fetchFromGitHub { + owner = "pilt"; + repo = "flask-versioned"; + rev = "38046fb53a09060de437c90a5f7370a6b94ffc31"; # no tags + sha256 = "1wim9hvx7lxzfg35c0nc7p34j4vw9mzisgijlz4ibgykah4g1y37"; + }; + + propagatedBuildInputs = [ flask ]; + + meta = with stdenv.lib; { + description = "Flask plugin to rewrite file paths to add version info"; + homepage = https://github.com/pilt/flask-versioned; + license = licenses.bsd3; + maintainers = with maintainers; [ globin ]; + }; +} + diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index ad05977984c..55752407edb 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -3711,6 +3711,8 @@ in { flask_testing = callPackage ../development/python-modules/flask-testing { }; + flask-versioned = callPackage ../development/python-modules/flask-versioned { }; + flask_wtf = callPackage ../development/python-modules/flask-wtf { }; wtforms = callPackage ../development/python-modules/wtforms { }; From 38c5add29c0ab1b637ce060ba288f82d29a1501a Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Tue, 21 Apr 2020 13:34:05 +0200 Subject: [PATCH 4/9] python.pkgs.huey: init at 2.2.0 --- .../python-modules/huey/default.nix | 25 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 27 insertions(+) create mode 100644 pkgs/development/python-modules/huey/default.nix diff --git a/pkgs/development/python-modules/huey/default.nix b/pkgs/development/python-modules/huey/default.nix new file mode 100644 index 00000000000..28a801de71a --- /dev/null +++ b/pkgs/development/python-modules/huey/default.nix @@ -0,0 +1,25 @@ +{ lib, buildPythonPackage, fetchFromGitHub, redis }: + +buildPythonPackage rec { + pname = "huey"; + version = "2.2.0"; + + src = fetchFromGitHub { + owner = "coleifer"; + repo = pname; + rev = version; + sha256 = "1hgic7qrmb1kxvfgf2qqiw39nqyknf17pjvli8jfzvd9mv7cb7hh"; + }; + + propagatedBuildInputs = [ redis ]; + + # connects to redis + doCheck = false; + + meta = with lib; { + description = "A little task queue for python"; + homepage = "https://github.com/coleifer/huey"; + license = licenses.mit; + maintainers = [ maintainers.globin ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 55752407edb..cdee7870eb4 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -2895,6 +2895,8 @@ in { hglib = callPackage ../development/python-modules/hglib {}; + huey = callPackage ../development/python-modules/huey { }; + humanize = callPackage ../development/python-modules/humanize { }; humanfriendly = callPackage ../development/python-modules/humanfriendly { }; From fb0c2616a79414d030185ed52e04ad1e567abc12 Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Tue, 21 Apr 2020 13:34:59 +0200 Subject: [PATCH 5/9] python.pkgs.smpplib: init at 2.1.0 --- .../python-modules/smpplib/default.nix | 29 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 31 insertions(+) create mode 100644 pkgs/development/python-modules/smpplib/default.nix diff --git a/pkgs/development/python-modules/smpplib/default.nix b/pkgs/development/python-modules/smpplib/default.nix new file mode 100644 index 00000000000..fe22f121efb --- /dev/null +++ b/pkgs/development/python-modules/smpplib/default.nix @@ -0,0 +1,29 @@ +{ buildPythonPackage, fetchPypi, lib, python, six, tox, mock, pytest }: + +buildPythonPackage rec { + pname = "smpplib"; + version = "2.1.0"; + + src = fetchPypi { + inherit pname version; + sha256 = "0jzxlfwf0861ilh4xyd70hmkdbvdki52aalglm1bnpxkg6i3jhfz"; + }; + + propagatedBuildInputs = [ six ]; + checkInputs = [ tox mock pytest ]; + + checkPhase = '' + pytest + ''; + + postInstall = '' + rm -rf $out/${python.sitePackages}/tests + ''; + + meta = with lib; { + description = "SMPP library for Python"; + homepage = "https://github.com/python-smpplib/python-smpplib"; + license = licenses.lgpl3Plus; + maintainers = [ maintainers.globin ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index cdee7870eb4..a0012372319 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -6204,6 +6204,8 @@ in { smartdc = callPackage ../development/python-modules/smartdc { }; + smpplib = callPackage ../development/python-modules/smpplib { }; + socksipy-branch = callPackage ../development/python-modules/socksipy-branch { }; sockjs-tornado = callPackage ../development/python-modules/sockjs-tornado { }; From 546b31bf4cf96300dd46e2dd9b6db8246f9cfa8e Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Tue, 21 Apr 2020 13:35:41 +0200 Subject: [PATCH 6/9] python.pkgs.privacyidea: init at 3.3 --- pkgs/servers/privacyidea/default.nix | 49 ++++++++++++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 51 insertions(+) create mode 100644 pkgs/servers/privacyidea/default.nix diff --git a/pkgs/servers/privacyidea/default.nix b/pkgs/servers/privacyidea/default.nix new file mode 100644 index 00000000000..af5451a9378 --- /dev/null +++ b/pkgs/servers/privacyidea/default.nix @@ -0,0 +1,49 @@ +{ lib, buildPythonPackage, fetchFromGitHub, cacert, openssl, python + +, cryptography, pyrad, pymysql, python-dateutil, flask-versioned, flask_script +, defusedxml, croniter, flask_migrate, pyjwt, configobj, sqlsoup, pillow +, python-gnupg, passlib, pyopenssl, beautifulsoup4, smpplib, flask-babel +, ldap3, huey, pyyaml, qrcode, oauth2client, requests, lxml, cbor2, psycopg2 + +, mock, pytest, responses, testfixtures +}: + +buildPythonPackage rec { + pname = "privacyIDEA"; + version = "3.3"; + + src = fetchFromGitHub { + owner = pname; + repo = pname; + rev = "v${version}"; + sha256 = "188ki924dig899wlih45xfsm0s7mjkya56vii26bg02h91izrb4b"; + }; + + propagatedBuildInputs = [ + cryptography pyrad pymysql python-dateutil flask-versioned flask_script + defusedxml croniter flask_migrate pyjwt configobj sqlsoup pillow + python-gnupg passlib pyopenssl beautifulsoup4 smpplib flask-babel + ldap3 huey pyyaml qrcode oauth2client requests lxml cbor2 psycopg2 + ]; + + checkInputs = [ openssl mock pytest responses testfixtures ]; + # issues with hardware token tests + doCheck = false; + + postPatch = '' + substituteInPlace privacyidea/lib/resolvers/LDAPIdResolver.py --replace \ + "/etc/privacyidea/ldap-ca.crt" \ + "${cacert}/etc/ssl/certs/ca-bundle.crt" + ''; + + postInstall = '' + rm -rf $out/${python.sitePackages}/tests + ''; + + meta = with lib; { + description = "Multi factor authentication system (2FA, MFA, OTP Server)"; + license = licenses.agpl3Plus; + homepage = "http://www.privacyidea.org"; + maintainers = [ maintainers.globin ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index a0012372319..bbb246a6082 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -3197,6 +3197,8 @@ in { priority = callPackage ../development/python-modules/priority { }; + privacyidea = callPackage ../servers/privacyidea { }; + prov = callPackage ../development/python-modules/prov { }; pudb = callPackage ../development/python-modules/pudb { }; From 6cbdd8640a7cb1c64e1014ac9ad4816aecab6385 Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Tue, 21 Apr 2020 13:36:07 +0200 Subject: [PATCH 7/9] python.pkgs.privacyidea-ldap-proxy: init at 0.6.1 --- pkgs/servers/privacyidea/ldap-proxy.nix | 23 +++++++++++++++++++++++ pkgs/top-level/python-packages.nix | 1 + 2 files changed, 24 insertions(+) create mode 100644 pkgs/servers/privacyidea/ldap-proxy.nix diff --git a/pkgs/servers/privacyidea/ldap-proxy.nix b/pkgs/servers/privacyidea/ldap-proxy.nix new file mode 100644 index 00000000000..bf15acb294e --- /dev/null +++ b/pkgs/servers/privacyidea/ldap-proxy.nix @@ -0,0 +1,23 @@ +{ lib, buildPythonPackage, fetchFromGitHub, twisted, ldaptor, configobj }: + +buildPythonPackage rec { + pname = "privacyidea-ldap-proxy"; + version = "0.6.1"; + + src = fetchFromGitHub { + owner = "privacyidea"; + repo = pname; + rev = "v${version}"; + sha256 = "1kc1n9wr1a66xd5zvl6dq78xnkqkn5574jpzashc99pvm62dr24j"; + }; + + propagatedBuildInputs = [ twisted ldaptor configobj ]; + doCheck = false; + + meta = with lib; { + description = "LDAP Proxy to intercept LDAP binds and authenticate against privacyIDEA"; + homepage = "https://github.com/privacyidea/privacyidea-ldap-proxy"; + license = licenses.agpl3; + maintainers = [ maintainers.globin ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index bbb246a6082..7b246c6ce0a 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -3198,6 +3198,7 @@ in { priority = callPackage ../development/python-modules/priority { }; privacyidea = callPackage ../servers/privacyidea { }; + privacyidea-ldap-proxy = callPackage ../servers/privacyidea/ldap-proxy.nix { }; prov = callPackage ../development/python-modules/prov { }; From 134c66b5842f13f4558151b2d79008597ccbd4dd Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Tue, 21 Apr 2020 13:37:00 +0200 Subject: [PATCH 8/9] privacyidea module: init --- nixos/modules/module-list.nix | 1 + .../modules/services/security/privacyidea.nix | 296 ++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/privacyidea.nix | 36 +++ 4 files changed, 334 insertions(+) create mode 100644 nixos/modules/services/security/privacyidea.nix create mode 100644 nixos/tests/privacyidea.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index df08ac2959e..bc0686f578c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -792,6 +792,7 @@ ./services/security/nginx-sso.nix ./services/security/oauth2_proxy.nix ./services/security/oauth2_proxy_nginx.nix + ./services/security/privacyidea.nix ./services/security/physlock.nix ./services/security/shibboleth-sp.nix ./services/security/sks.nix diff --git a/nixos/modules/services/security/privacyidea.nix b/nixos/modules/services/security/privacyidea.nix new file mode 100644 index 00000000000..49c03afdf8c --- /dev/null +++ b/nixos/modules/services/security/privacyidea.nix @@ -0,0 +1,296 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.privacyidea; + + uwsgi = pkgs.uwsgi.override { plugins = [ "python3" ]; }; + python = uwsgi.python3; + penv = python.withPackages (ps: [ ps.privacyidea ]); + logCfg = pkgs.writeText "privacyidea-log.cfg" '' + [formatters] + keys=detail + + [handlers] + keys=stream + + [formatter_detail] + class=privacyidea.lib.log.SecureFormatter + format=[%(asctime)s][%(process)d][%(thread)d][%(levelname)s][%(name)s:%(lineno)d] %(message)s + + [handler_stream] + class=StreamHandler + level=NOTSET + formatter=detail + args=(sys.stdout,) + + [loggers] + keys=root,privacyidea + + [logger_privacyidea] + handlers=stream + qualname=privacyidea + level=INFO + + [logger_root] + handlers=stream + level=ERROR + ''; + + piCfgFile = pkgs.writeText "privacyidea.cfg" '' + SUPERUSER_REALM = [ '${concatStringsSep "', '" cfg.superuserRealm}' ] + SQLALCHEMY_DATABASE_URI = '${cfg.databaseURI}' + SECRET_KEY = '${cfg.secretKey}' + PI_PEPPER = '${cfg.pepper}' + PI_ENCFILE = '${cfg.encFile}' + PI_AUDIT_KEY_PRIVATE = '${cfg.auditKeyPrivate}' + PI_AUDIT_KEY_PUBLIC = '${cfg.auditKeyPublic}' + PI_LOGCONFIG = '${logCfg}' + ${cfg.extraConfig} + ''; + +in + +{ + options = { + services.privacyidea = { + enable = mkEnableOption "PrivacyIDEA"; + + stateDir = mkOption { + type = types.str; + default = "/var/lib/privacyidea"; + description = '' + Directory where all PrivacyIDEA files will be placed by default. + ''; + }; + + runDir = mkOption { + type = types.str; + default = "/run/privacyidea"; + description = '' + Directory where all PrivacyIDEA files will be placed by default. + ''; + }; + + superuserRealm = mkOption { + type = types.listOf types.str; + default = [ "super" "administrators" ]; + description = '' + The realm where users are allowed to login as administrators. + ''; + }; + + databaseURI = mkOption { + type = types.str; + default = "postgresql:///privacyidea"; + description = '' + Database as SQLAlchemy URI to use for PrivacyIDEA. + ''; + }; + + secretKey = mkOption { + type = types.str; + example = "t0p s3cr3t"; + description = '' + This is used to encrypt the auth_token. + ''; + }; + + pepper = mkOption { + type = types.str; + example = "Never know..."; + description = '' + This is used to encrypt the admin passwords. + ''; + }; + + encFile = mkOption { + type = types.str; + default = "${cfg.stateDir}/enckey"; + description = '' + This is used to encrypt the token data and token passwords + ''; + }; + + auditKeyPrivate = mkOption { + type = types.str; + default = "${cfg.stateDir}/private.pem"; + description = '' + Private Key for signing the audit log. + ''; + }; + + auditKeyPublic = mkOption { + type = types.str; + default = "${cfg.stateDir}/public.pem"; + description = '' + Public key for checking signatures of the audit log. + ''; + }; + + adminPassword = mkOption { + type = types.str; + description = "Password for the admin user"; + }; + + adminEmail = mkOption { + type = types.str; + example = "admin@example.com"; + description = "Mail address for the admin user"; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration options for pi.cfg. + ''; + }; + + user = mkOption { + type = types.str; + default = "privacyidea"; + description = "User account under which PrivacyIDEA runs."; + }; + + group = mkOption { + type = types.str; + default = "privacyidea"; + description = "Group account under which PrivacyIDEA runs."; + }; + + ldap-proxy = { + enable = mkEnableOption "PrivacyIDEA LDAP Proxy"; + + configFile = mkOption { + type = types.path; + default = ""; + description = '' + Path to PrivacyIDEA LDAP Proxy configuration (proxy.ini). + ''; + }; + + user = mkOption { + type = types.str; + default = "pi-ldap-proxy"; + description = "User account under which PrivacyIDEA LDAP proxy runs."; + }; + + group = mkOption { + type = types.str; + default = "pi-ldap-proxy"; + description = "Group account under which PrivacyIDEA LDAP proxy runs."; + }; + }; + }; + }; + + config = mkMerge [ + + (mkIf cfg.enable { + + environment.systemPackages = [ python.pkgs.privacyidea ]; + + services.postgresql.enable = mkDefault true; + + systemd.services.privacyidea = let + piuwsgi = pkgs.writeText "uwsgi.json" (builtins.toJSON { + uwsgi = { + plugins = [ "python3" ]; + pythonpath = "${penv}/${uwsgi.python3.sitePackages}"; + socket = "${cfg.runDir}/socket"; + uid = cfg.user; + gid = cfg.group; + chmod-socket = 770; + chown-socket = "${cfg.user}:nginx"; + chdir = cfg.stateDir; + wsgi-file = "${penv}/etc/privacyidea/privacyideaapp.wsgi"; + processes = 4; + harakiri = 60; + reload-mercy = 8; + stats = "${cfg.runDir}/stats.socket"; + max-requests = 2000; + limit-as = 1024; + reload-on-as = 512; + reload-on-rss = 256; + no-orphans = true; + vacuum = true; + }; + }); + in { + wantedBy = [ "multi-user.target" ]; + after = [ "postgresql.service" ]; + path = with pkgs; [ openssl ]; + environment.PRIVACYIDEA_CONFIGFILE = piCfgFile; + preStart = let + pi-manage = "${pkgs.sudo}/bin/sudo -u privacyidea -H PRIVACYIDEA_CONFIGFILE=${piCfgFile} ${penv}/bin/pi-manage"; + pgsu = config.services.postgresql.superUser; + psql = config.services.postgresql.package; + in '' + mkdir -p ${cfg.stateDir} ${cfg.runDir} + chown ${cfg.user}:${cfg.group} -R ${cfg.stateDir} ${cfg.runDir} + ln -sf ${piCfgFile} ${cfg.stateDir}/privacyidea.cfg + if ! test -e "${cfg.stateDir}/db-created"; then + ${pkgs.sudo}/bin/sudo -u ${pgsu} ${psql}/bin/createuser --no-superuser --no-createdb --no-createrole ${cfg.user} + ${pkgs.sudo}/bin/sudo -u ${pgsu} ${psql}/bin/createdb --owner ${cfg.user} privacyidea + ${pi-manage} create_enckey + ${pi-manage} create_audit_keys + ${pi-manage} createdb + ${pi-manage} admin add admin -e ${cfg.adminEmail} -p ${cfg.adminPassword} + ${pi-manage} db stamp head -d ${penv}/lib/privacyidea/migrations + touch "${cfg.stateDir}/db-created" + chmod g+r "${cfg.stateDir}/enckey" "${cfg.stateDir}/private.pem" + fi + ${pi-manage} db upgrade -d ${penv}/lib/privacyidea/migrations + ''; + serviceConfig = { + Type = "notify"; + ExecStart = "${uwsgi}/bin/uwsgi --json ${piuwsgi}"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID"; + NotifyAccess = "main"; + KillSignal = "SIGQUIT"; + StandardError = "syslog"; + }; + }; + + users.extraUsers.privacyidea = mkIf (cfg.user == "privacyidea") { + group = cfg.group; + }; + + users.extraGroups.privacyidea = mkIf (cfg.group == "privacyidea") {}; + }) + + (mkIf cfg.ldap-proxy.enable { + + systemd.services.privacyidea-ldap-proxy = let + ldap-proxy-env = pkgs.python2.withPackages (ps: [ ps.privacyidea-ldap-proxy ]); + in { + description = "privacyIDEA LDAP proxy"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = cfg.ldap-proxy.user; + Group = cfg.ldap-proxy.group; + ExecStart = '' + ${ldap-proxy-env}/bin/twistd \ + --nodaemon \ + --pidfile= \ + -u ${cfg.ldap-proxy.user} \ + -g ${cfg.ldap-proxy.group} \ + ldap-proxy \ + -c ${cfg.ldap-proxy.configFile} + ''; + Restart = "always"; + }; + }; + + users.extraUsers.pi-ldap-proxy = mkIf (cfg.ldap-proxy.user == "pi-ldap-proxy") { + group = cfg.ldap-proxy.group; + }; + + users.extraGroups.pi-ldap-proxy = mkIf (cfg.ldap-proxy.group == "pi-ldap-proxy") {}; + }) + ]; + +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 30229a3a5b2..245f8497d05 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -255,6 +255,7 @@ in pppd = handleTest ./pppd.nix {}; predictable-interface-names = handleTest ./predictable-interface-names.nix {}; printing = handleTest ./printing.nix {}; + privacyidea = handleTest ./privacyidea.nix {}; prometheus = handleTest ./prometheus.nix {}; prometheus-exporters = handleTest ./prometheus-exporters.nix {}; prosody = handleTest ./xmpp/prosody.nix {}; diff --git a/nixos/tests/privacyidea.nix b/nixos/tests/privacyidea.nix new file mode 100644 index 00000000000..fcca1937385 --- /dev/null +++ b/nixos/tests/privacyidea.nix @@ -0,0 +1,36 @@ +# Miscellaneous small tests that don't warrant their own VM run. + +import ./make-test-python.nix ({ pkgs, ...} : rec { + name = "privacyidea"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ fpletz ]; + }; + + machine = { ... }: { + virtualisation.cores = 2; + virtualisation.memorySize = 512; + + services.privacyidea = { + enable = true; + secretKey = "testing"; + pepper = "testing"; + adminPassword = "testing"; + adminEmail = "root@localhost"; + }; + services.nginx = { + enable = true; + virtualHosts."_".locations."/".extraConfig = '' + uwsgi_pass unix:/run/privacyidea/socket; + ''; + }; + }; + + testScript = '' + machine.start() + machine.wait_for_unit("multi-user.target") + machine.succeed("curl --fail http://localhost | grep privacyIDEA") + machine.succeed( + "curl --fail http://localhost/auth -F username=admin -F password=testing | grep token" + ) + ''; +}) From f1f0e82c509310d169ed6f38889a7b32244154a9 Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Fri, 8 May 2020 14:09:10 +0200 Subject: [PATCH 9/9] privacyidea: address reviews --- .../modules/services/security/privacyidea.nix | 45 ++++++------------- nixos/tests/privacyidea.nix | 2 +- .../flask-versioned/default.nix | 2 +- .../python-modules}/privacyidea/default.nix | 2 + .../privacyidea/ldap-proxy.nix | 4 ++ pkgs/top-level/python-packages.nix | 4 +- 6 files changed, 24 insertions(+), 35 deletions(-) rename pkgs/{servers => development/python-modules}/privacyidea/default.nix (97%) rename pkgs/{servers => development/python-modules}/privacyidea/ldap-proxy.nix (87%) diff --git a/nixos/modules/services/security/privacyidea.nix b/nixos/modules/services/security/privacyidea.nix index 49c03afdf8c..d6abfd0e271 100644 --- a/nixos/modules/services/security/privacyidea.nix +++ b/nixos/modules/services/security/privacyidea.nix @@ -40,7 +40,7 @@ let piCfgFile = pkgs.writeText "privacyidea.cfg" '' SUPERUSER_REALM = [ '${concatStringsSep "', '" cfg.superuserRealm}' ] - SQLALCHEMY_DATABASE_URI = '${cfg.databaseURI}' + SQLALCHEMY_DATABASE_URI = 'postgresql:///privacyidea' SECRET_KEY = '${cfg.secretKey}' PI_PEPPER = '${cfg.pepper}' PI_ENCFILE = '${cfg.encFile}' @@ -65,14 +65,6 @@ in ''; }; - runDir = mkOption { - type = types.str; - default = "/run/privacyidea"; - description = '' - Directory where all PrivacyIDEA files will be placed by default. - ''; - }; - superuserRealm = mkOption { type = types.listOf types.str; default = [ "super" "administrators" ]; @@ -81,14 +73,6 @@ in ''; }; - databaseURI = mkOption { - type = types.str; - default = "postgresql:///privacyidea"; - description = '' - Database as SQLAlchemy URI to use for PrivacyIDEA. - ''; - }; - secretKey = mkOption { type = types.str; example = "t0p s3cr3t"; @@ -129,9 +113,9 @@ in ''; }; - adminPassword = mkOption { - type = types.str; - description = "Password for the admin user"; + adminPasswordFile = mkOption { + type = types.path; + description = "File containing password for the admin user"; }; adminEmail = mkOption { @@ -199,7 +183,7 @@ in uwsgi = { plugins = [ "python3" ]; pythonpath = "${penv}/${uwsgi.python3.sitePackages}"; - socket = "${cfg.runDir}/socket"; + socket = "/run/privacyidea/socket"; uid = cfg.user; gid = cfg.group; chmod-socket = 770; @@ -209,7 +193,7 @@ in processes = 4; harakiri = 60; reload-mercy = 8; - stats = "${cfg.runDir}/stats.socket"; + stats = "/run/privacyidea/stats.socket"; max-requests = 2000; limit-as = 1024; reload-on-as = 512; @@ -224,20 +208,19 @@ in path = with pkgs; [ openssl ]; environment.PRIVACYIDEA_CONFIGFILE = piCfgFile; preStart = let - pi-manage = "${pkgs.sudo}/bin/sudo -u privacyidea -H PRIVACYIDEA_CONFIGFILE=${piCfgFile} ${penv}/bin/pi-manage"; + pi-manage = "${pkgs.sudo}/bin/sudo -u privacyidea -HE ${penv}/bin/pi-manage"; pgsu = config.services.postgresql.superUser; psql = config.services.postgresql.package; in '' - mkdir -p ${cfg.stateDir} ${cfg.runDir} - chown ${cfg.user}:${cfg.group} -R ${cfg.stateDir} ${cfg.runDir} - ln -sf ${piCfgFile} ${cfg.stateDir}/privacyidea.cfg + mkdir -p ${cfg.stateDir} /run/privacyidea + chown ${cfg.user}:${cfg.group} -R ${cfg.stateDir} /run/privacyidea if ! test -e "${cfg.stateDir}/db-created"; then ${pkgs.sudo}/bin/sudo -u ${pgsu} ${psql}/bin/createuser --no-superuser --no-createdb --no-createrole ${cfg.user} ${pkgs.sudo}/bin/sudo -u ${pgsu} ${psql}/bin/createdb --owner ${cfg.user} privacyidea ${pi-manage} create_enckey ${pi-manage} create_audit_keys ${pi-manage} createdb - ${pi-manage} admin add admin -e ${cfg.adminEmail} -p ${cfg.adminPassword} + ${pi-manage} admin add admin -e ${cfg.adminEmail} -p "$(cat ${cfg.adminPasswordFile})" ${pi-manage} db stamp head -d ${penv}/lib/privacyidea/migrations touch "${cfg.stateDir}/db-created" chmod g+r "${cfg.stateDir}/enckey" "${cfg.stateDir}/private.pem" @@ -255,11 +238,11 @@ in }; }; - users.extraUsers.privacyidea = mkIf (cfg.user == "privacyidea") { + users.users.privacyidea = mkIf (cfg.user == "privacyidea") { group = cfg.group; }; - users.extraGroups.privacyidea = mkIf (cfg.group == "privacyidea") {}; + users.groups.privacyidea = mkIf (cfg.group == "privacyidea") {}; }) (mkIf cfg.ldap-proxy.enable { @@ -285,11 +268,11 @@ in }; }; - users.extraUsers.pi-ldap-proxy = mkIf (cfg.ldap-proxy.user == "pi-ldap-proxy") { + users.users.pi-ldap-proxy = mkIf (cfg.ldap-proxy.user == "pi-ldap-proxy") { group = cfg.ldap-proxy.group; }; - users.extraGroups.pi-ldap-proxy = mkIf (cfg.ldap-proxy.group == "pi-ldap-proxy") {}; + users.groups.pi-ldap-proxy = mkIf (cfg.ldap-proxy.group == "pi-ldap-proxy") {}; }) ]; diff --git a/nixos/tests/privacyidea.nix b/nixos/tests/privacyidea.nix index fcca1937385..45c7cd37c24 100644 --- a/nixos/tests/privacyidea.nix +++ b/nixos/tests/privacyidea.nix @@ -14,7 +14,7 @@ import ./make-test-python.nix ({ pkgs, ...} : rec { enable = true; secretKey = "testing"; pepper = "testing"; - adminPassword = "testing"; + adminPasswordFile = pkgs.writeText "admin-password" "testing"; adminEmail = "root@localhost"; }; services.nginx = { diff --git a/pkgs/development/python-modules/flask-versioned/default.nix b/pkgs/development/python-modules/flask-versioned/default.nix index c4e9f16bceb..3bd5ef98b32 100644 --- a/pkgs/development/python-modules/flask-versioned/default.nix +++ b/pkgs/development/python-modules/flask-versioned/default.nix @@ -15,7 +15,7 @@ buildPythonPackage rec { meta = with stdenv.lib; { description = "Flask plugin to rewrite file paths to add version info"; - homepage = https://github.com/pilt/flask-versioned; + homepage = "https://github.com/pilt/flask-versioned"; license = licenses.bsd3; maintainers = with maintainers; [ globin ]; }; diff --git a/pkgs/servers/privacyidea/default.nix b/pkgs/development/python-modules/privacyidea/default.nix similarity index 97% rename from pkgs/servers/privacyidea/default.nix rename to pkgs/development/python-modules/privacyidea/default.nix index af5451a9378..84cc4530b34 100644 --- a/pkgs/servers/privacyidea/default.nix +++ b/pkgs/development/python-modules/privacyidea/default.nix @@ -30,6 +30,8 @@ buildPythonPackage rec { # issues with hardware token tests doCheck = false; + pythonImportsCheck = [ "privacyidea" ]; + postPatch = '' substituteInPlace privacyidea/lib/resolvers/LDAPIdResolver.py --replace \ "/etc/privacyidea/ldap-ca.crt" \ diff --git a/pkgs/servers/privacyidea/ldap-proxy.nix b/pkgs/development/python-modules/privacyidea/ldap-proxy.nix similarity index 87% rename from pkgs/servers/privacyidea/ldap-proxy.nix rename to pkgs/development/python-modules/privacyidea/ldap-proxy.nix index bf15acb294e..ec87186a4fd 100644 --- a/pkgs/servers/privacyidea/ldap-proxy.nix +++ b/pkgs/development/python-modules/privacyidea/ldap-proxy.nix @@ -12,8 +12,12 @@ buildPythonPackage rec { }; propagatedBuildInputs = [ twisted ldaptor configobj ]; + + # python 2 zope.interface test import path issues doCheck = false; + pythonImportsCheck = [ "pi_ldapproxy" ]; + meta = with lib; { description = "LDAP Proxy to intercept LDAP binds and authenticate against privacyIDEA"; homepage = "https://github.com/privacyidea/privacyidea-ldap-proxy"; diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 7b246c6ce0a..4768f3ebb1b 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -3197,8 +3197,8 @@ in { priority = callPackage ../development/python-modules/priority { }; - privacyidea = callPackage ../servers/privacyidea { }; - privacyidea-ldap-proxy = callPackage ../servers/privacyidea/ldap-proxy.nix { }; + privacyidea = callPackage ../development/python-modules/privacyidea { }; + privacyidea-ldap-proxy = callPackage ../development/python-modules/privacyidea/ldap-proxy.nix { }; prov = callPackage ../development/python-modules/prov { };