nixpkgs/pkgs/by-name/au/authentik/package.nix
2024-07-23 12:30:33 +02:00

429 lines
11 KiB
Nix

{ lib
, stdenvNoCC
, callPackages
, fetchFromGitHub
, fetchpatch
, fetchzip
, buildNpmPackage
, buildGoModule
, runCommand
, openapi-generator-cli
, nodejs
, python312
, codespell
, makeWrapper }:
let
version = "2024.6.1";
src = fetchFromGitHub {
owner = "goauthentik";
repo = "authentik";
rev = "version/${version}";
hash = "sha256-SMupiJGJbkBn33JP4WLF3IsBdt3SN3JvZg/EYlz443g=";
};
meta = with lib; {
description = "Authentication glue you need";
changelog = "https://github.com/goauthentik/authentik/releases/tag/version%2F${version}";
homepage = "https://goauthentik.io/";
license = licenses.mit;
platforms = platforms.linux;
maintainers = with maintainers; [ jvanbruegge risson ];
};
website = buildNpmPackage {
pname = "authentik-website";
inherit version src meta;
npmDepsHash = "sha256-JM+ae+zDsMdvovd2p4IJIH89KlMeDU7HOZjFbDCyehw=";
NODE_ENV = "production";
NODE_OPTIONS = "--openssl-legacy-provider";
postPatch = ''
cd website
'';
installPhase = ''
mkdir $out
cp -r build $out/help
'';
npmBuildScript = "build-bundled";
npmFlags = [ "--ignore-scripts" ];
};
clientapi = stdenvNoCC.mkDerivation {
pname = "authentik-client-api";
inherit version src meta;
postPatch = ''
rm Makefile
substituteInPlace ./scripts/api-ts-config.yaml \
--replace-fail '/local' "$(pwd)/"
'';
nativeBuildInputs = [ openapi-generator-cli ];
buildPhase = ''
runHook preBuild
openapi-generator-cli generate -i ./schema.yml \
-g typescript-fetch -o $out \
-c ./scripts/api-ts-config.yaml \
--additional-properties=npmVersion=${nodejs.pkgs.npm.version} \
--git-repo-id authentik --git-user-id goauthentik
runHook postBuild
'';
};
webui = buildNpmPackage {
pname = "authentik-webui";
inherit version meta;
src = runCommand "authentik-webui-source" {} ''
mkdir -p $out/web/node_modules/@goauthentik/
cp -r ${src}/web $out/
ln -s ${src}/package.json $out/
ln -s ${src}/website $out/
ln -s ${clientapi} $out/web/node_modules/@goauthentik/api
'';
npmDepsHash = "sha256-v9oD8qV5UDJeZn4GZDEPlVM/jGVSeTqdIUDJl6tYXZw=";
postPatch = ''
cd web
'';
installPhase = ''
runHook preInstall
mkdir $out
cp -r dist $out/dist
cp -r authentik $out/authentik
runHook postInstall
'';
NODE_ENV = "production";
NODE_OPTIONS = "--openssl-legacy-provider";
npmInstallFlags = [ "--include=dev" ];
};
python = python312.override {
self = python;
packageOverrides = final: prev: {
django-tenants = prev.buildPythonPackage rec {
pname = "django-tenants";
version = "unstable-2024-01-11";
src = fetchFromGitHub {
owner = "rissson";
repo = pname;
rev = "a7f37c53f62f355a00142473ff1e3451bb794eca";
hash = "sha256-YBT0kcCfETXZe0j7/f1YipNIuRrcppRVh1ecFS3cvNo=";
};
format = "setuptools";
doCheck = false; # Tests require postgres
propagatedBuildInputs = with final; [
django
psycopg
gunicorn
];
};
django-cte = prev.buildPythonPackage rec {
pname = "django-cte";
version = "1.3.3";
src = fetchFromGitHub {
owner = "dimagi";
repo = pname;
rev = "v${version}";
hash = "sha256-OCENg94xHBeeE4A2838Cu3q2am2im2X4SkFSjc6DuhE=";
};
doCheck = false; # Tests require postgres
format = "setuptools";
};
django-pgactivity = prev.buildPythonPackage rec {
pname = "django-pgactivity";
version = "1.4.1";
src = fetchFromGitHub {
owner = "Opus10";
repo = pname;
rev = version;
hash = "sha256-VwH7fwLcoH2Z9D/OY9iieM0cRhyDKOpAzqQ+4YVE3vU=";
};
nativeBuildInputs = with prev; [
poetry-core
];
propagatedBuildInputs = with final; [
django
];
pyproject = true;
};
django-pglock = prev.buildPythonPackage rec {
pname = "django-pglock";
version = "1.5.1";
src = fetchFromGitHub {
owner = "Opus10";
repo = pname;
rev = version;
hash = "sha256-ZoEHDkGmrcNiMe/rbwXsEPZo3LD93cZp6zjftMKjLeg=";
};
nativeBuildInputs = with prev; [
poetry-core
];
propagatedBuildInputs = with final; [
django
django-pgactivity
];
pyproject = true;
};
# Use 3.14.0 until https://github.com/encode/django-rest-framework/issues/9358 is fixed.
# Otherwise applying blueprints/default/default-brand.yaml fails with:
# authentik.flows.models.RelatedObjectDoesNotExist: FlowStageBinding has no target.
djangorestframework = prev.buildPythonPackage rec {
pname = "djangorestframework";
version = "3.14.0";
format = "setuptools";
src = fetchFromGitHub {
owner = "encode";
repo = "django-rest-framework";
rev = version;
hash = "sha256-Fnj0n3NS3SetOlwSmGkLE979vNJnYE6i6xwVBslpNz4=";
};
propagatedBuildInputs = with final; [
django
pytz
];
nativeCheckInputs = with final; [
pytest-django
pytest7CheckHook
# optional tests
coreapi
django-guardian
pyyaml
uritemplate
];
pythonImportsCheck = [ "rest_framework" ];
};
tenant-schemas-celery = prev.buildPythonPackage rec {
pname = "tenant-schemas-celery";
version = "3.0.0";
src = fetchFromGitHub {
owner = "maciej-gol";
repo = pname;
rev = version;
hash = "sha256-3ZUXSAOBMtj72sk/VwPV24ysQK+E4l1HdwKa78xrDtg=";
};
format = "setuptools";
doCheck = false;
propagatedBuildInputs = with final; [
freezegun
more-itertools
psycopg2
];
};
scim2-filter-parser = prev.buildPythonPackage rec {
pname = "scim2-filter-parser";
version = "0.5.1";
# For some reason the normal fetchPypi does not work
src = fetchzip {
url = "https://files.pythonhosted.org/packages/54/df/ad9718acce76e81a93c57327356eecd23701625f240fbe03d305250399e6/scim2_filter_parser-0.5.1.tar.gz";
hash = "sha256-DZAdRj6qyySggsvJZC47vdvXbHrB1ra3qiYBEUiceJ4=";
};
postPatch = ''
substituteInPlace pyproject.toml \
--replace-fail 'poetry>=0.12' 'poetry-core>=1.0.0' \
--replace-fail 'poetry.masonry.api' 'poetry.core.masonry.api'
'';
nativeBuildInputs = [ prev.poetry-core ];
pyproject = true;
propagatedBuildInputs = with final; [
sly
];
};
authentik-django = prev.buildPythonPackage {
pname = "authentik-django";
inherit version src meta;
pyproject = true;
patches = [
(fetchpatch {
name = "scim-schema-load.patch";
url = "https://github.com/goauthentik/authentik/commit/f3640bd3c0ee2f43efcfd506bb71d2b7b6761017.patch";
hash = "sha256-4AC7Dc4TM7ok964ztc+XdHvoU/DKyi9yJoz5u1dljEM=";
})
];
postPatch = ''
rm lifecycle/system_migrations/tenant_files.py
substituteInPlace authentik/root/settings.py \
--replace-fail 'Path(__file__).absolute().parent.parent.parent' "Path(\"$out\")"
substituteInPlace authentik/lib/default.yml \
--replace-fail '/blueprints' "$out/blueprints" \
--replace-fail './media' '/var/lib/authentik/media'
substituteInPlace pyproject.toml \
--replace-fail 'dumb-init = "*"' "" \
--replace-fail 'djangorestframework-guardian' 'djangorestframework-guardian2'
substituteInPlace authentik/stages/email/utils.py \
--replace-fail 'web/' '${webui}/'
'';
nativeBuildInputs = [ prev.poetry-core ];
propagatedBuildInputs = with final; [
argon2-cffi
celery
channels
channels-redis
colorama
dacite
daphne
deepmerge
defusedxml
django
django-cte
django-filter
django-guardian
django-model-utils
django-pglock
django-prometheus
django-redis
django-storages
django-tenants
djangorestframework
djangorestframework-guardian2
docker
drf-spectacular
duo-client
facebook-sdk
fido2
flower
geoip2
google-api-python-client
gunicorn
jsonpatch
kubernetes
ldap3
lxml
msgraph-sdk
opencontainers
packaging
paramiko
psycopg
pycryptodome
pydantic
pydantic-scim
pyjwt
pyyaml
requests-oauthlib
scim2-filter-parser
sentry-sdk
service-identity
setproctitle
structlog
swagger-spec-validator
tenant-schemas-celery
twilio
twisted
ua-parser
urllib3
uvicorn
watchdog
webauthn
websockets
wsproto
xmlsec
zxcvbn
]
++ uvicorn.optional-dependencies.standard
++ [ codespell ];
postInstall = ''
mkdir -p $out/web $out/website
cp -r lifecycle manage.py $out/${prev.python.sitePackages}/
cp -r blueprints $out/
cp -r ${webui}/dist ${webui}/authentik $out/web/
cp -r ${website} $out/website/help
ln -s $out/${prev.python.sitePackages}/authentik $out/authentik
ln -s $out/${prev.python.sitePackages}/lifecycle $out/lifecycle
'';
};
};
};
inherit (python.pkgs) authentik-django;
proxy = buildGoModule {
pname = "authentik-proxy";
inherit version src meta;
postPatch = ''
substituteInPlace internal/gounicorn/gounicorn.go \
--replace-fail './lifecycle' "${authentik-django}/lifecycle"
substituteInPlace web/static.go \
--replace-fail './web' "${authentik-django}/web"
substituteInPlace internal/web/static.go \
--replace-fail './web' "${authentik-django}/web"
'';
CGO_ENABLED = 0;
vendorHash = "sha256-hxtyXyCfVemsjYQeo//gd68x4QO/4Vcww8i2ocsUVW8=";
postInstall = ''
mv $out/bin/server $out/bin/authentik
'';
subPackages = [ "cmd/server" ];
};
in stdenvNoCC.mkDerivation {
pname = "authentik";
inherit src version;
postPatch = ''
rm Makefile
patchShebangs lifecycle/ak
# This causes issues in systemd services
substituteInPlace lifecycle/ak \
--replace-fail 'printf' '>&2 printf' \
--replace-fail '> /dev/stderr' ""
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp -r lifecycle/ak $out/bin/
wrapProgram $out/bin/ak \
--prefix PATH : ${lib.makeBinPath [ (python.withPackages (ps: [ps.authentik-django])) proxy ]} \
--set TMPDIR /dev/shm \
--set PYTHONDONTWRITEBYTECODE 1 \
--set PYTHONUNBUFFERED 1
runHook postInstall
'';
passthru.outposts = callPackages ./outposts.nix { };
nativeBuildInputs = [ makeWrapper ];
meta = meta // {
mainProgram = "ak";
};
}