Compare commits

...

41 Commits

Author SHA1 Message Date
0b7ebf0e07 release: 2021.5.1 2021-05-13 20:50:31 +02:00
ddca8ef3ca tests/integration: fix outpost tests
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 20:33:41 +02:00
709581f5a8 root: use ghcr images by default
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 20:15:29 +02:00
72e41c03f5 lifecycle: run worker as root and drop perms later to fix docker permission issues
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 20:11:49 +02:00
40503d06b7 web/admin: improve UI for plex source
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 18:12:07 +02:00
1df8790050 stages/authenticator_static: fix error when listing devices
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 18:09:55 +02:00
3c23ad340f web/admin: improve diagram api for flows
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 18:01:40 +02:00
f9f2e00913 core: improve error handling for backups
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 17:56:49 +02:00
8362507bdf outposts: fix GIT_BUILD_HASH not being set correctly
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 17:49:11 +02:00
a2181c3bf0 build(deps): bump actions/create-release from 1.0.0 to 1.1.4 (#876) 2021-05-13 15:40:05 +02:00
a07ded0dae build(deps): bump actions/github-script from 0.2.0 to 4.0.2 (#877) 2021-05-13 15:39:48 +02:00
3b0b9301ee build(deps): bump django from 3.2.2 to 3.2.3 (#878) 2021-05-13 15:39:40 +02:00
919f293fc7 tests/e2e: fix redirect_uri
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 13:09:30 +02:00
c4df2e5a50 Merge branch 'master' into next
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

# Conflicts:
#	Pipfile.lock
2021-05-13 12:47:55 +02:00
4d1500e0f3 outposts/proxy: revert to using request Host for redirect URI
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-13 12:34:53 +02:00
281bd4c69a build(deps): bump @babel/core from 7.14.0 to 7.14.2 in /web (#868)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.14.0 to 7.14.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.14.2/packages/babel-core)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-13 11:23:08 +02:00
e4678aa032 build(deps): bump @babel/plugin-transform-runtime in /web (#869)
Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.13.15 to 7.14.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.14.2/packages/babel-plugin-transform-runtime)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-13 11:21:52 +02:00
ff1c4d555a build(deps): bump @babel/preset-env from 7.14.1 to 7.14.2 in /web (#870)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.14.1 to 7.14.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.14.2/packages/babel-preset-env)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-13 11:20:46 +02:00
4a3e34d40a build(deps): bump @docusaurus/preset-classic in /website (#872)
Bumps [@docusaurus/preset-classic](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-preset-classic) from 2.0.0-alpha.75 to 2.0.0-beta.0.
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v2.0.0-beta.0/packages/docusaurus-preset-classic)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-13 11:18:39 +02:00
6939898bbe build(deps): bump @babel/plugin-proposal-decorators in /web (#871)
Bumps [@babel/plugin-proposal-decorators](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-decorators) from 7.13.15 to 7.14.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.14.2/packages/babel-plugin-proposal-decorators)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-13 11:18:30 +02:00
549607c5ed build(deps): bump kubernetes from 12.0.1 to 17.17.0 (#874)
Bumps [kubernetes](https://github.com/kubernetes-client/python) from 12.0.1 to 17.17.0.
- [Release notes](https://github.com/kubernetes-client/python/releases)
- [Changelog](https://github.com/kubernetes-client/python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes-client/python/compare/v12.0.1...v17.17.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-13 11:18:20 +02:00
f61acdfbfd build(deps): bump geoip2 from 4.1.0 to 4.2.0 (#873) 2021-05-13 11:15:25 +02:00
e3572bad76 build(deps): bump boto3 from 1.17.71 to 1.17.72 (#875) 2021-05-13 10:36:43 +02:00
8f99891a9d release: 2021.5.1-rc10 2021-05-12 21:25:18 +02:00
99d5262d41 ci: install git in final test containers
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 21:24:35 +02:00
97a3c2d88b release: 2021.5.1-rc9 2021-05-12 20:50:29 +02:00
e91ff4566d Merge branch 'next' into version-2021.5
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

# Conflicts:
#	outpost/pkg/version.go
2021-05-12 20:49:58 +02:00
dc942b2f4c outposts: build as gh-<commit hash>
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 20:37:55 +02:00
a3fccbdaff outposts: add build_hash for docker image
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 20:36:18 +02:00
bdf9f26d07 outposts: compare build hash in outdated check
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 19:05:29 +02:00
901cea1453 outposts: send build hash as part of hello
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 19:02:04 +02:00
37b57ac28f outposts: include git commit hash in build from git branch
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 18:56:44 +02:00
e9aa37ba67 outposts/ldap: fix user info caching, fix mixed case DN
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#864
2021-05-12 18:49:15 +02:00
9a0aa4c79b outposts/ldap: add infinite loop prevention
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 18:31:44 +02:00
34ab68a169 outposts: cleanup logging
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 18:01:46 +02:00
52cf4890cf root: remove servername from backup files
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 17:53:23 +02:00
8e5d03cb86 outposts: remove legacy API
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 16:41:54 +02:00
2190fa555b events/api: fix error when updating transports
closes #866

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 16:41:30 +02:00
ae1edde17b ci: install git in container for dbbackup
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-05-12 16:30:51 +02:00
3ad1c3f212 web/admin: fix AuthenticatorValidationStage's form not setting notConfiguredAction
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#802
2021-05-12 16:28:14 +02:00
65ec444e52 build(deps): bump boto3 from 1.17.70 to 1.17.71 (#865)
Bumps [boto3](https://github.com/boto/boto3) from 1.17.70 to 1.17.71.
- [Release notes](https://github.com/boto/boto3/releases)
- [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst)
- [Commits](https://github.com/boto/boto3/compare/1.17.70...1.17.71)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-12 10:46:06 +02:00
54 changed files with 5565 additions and 4493 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2021.5.1-rc8
current_version = 2021.5.1
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-?(?P<release>.*)

View File

@ -36,9 +36,9 @@ jobs:
with:
push: ${{ github.event_name == 'release' }}
tags: |
beryju/authentik:2021.5.1-rc8,
beryju/authentik:2021.5.1,
beryju/authentik:latest,
ghcr.io/goauthentik/server:2021.5.1-rc8,
ghcr.io/goauthentik/server:2021.5.1,
ghcr.io/goauthentik/server:latest
platforms: linux/amd64,linux/arm64
context: .
@ -75,9 +75,9 @@ jobs:
with:
push: ${{ github.event_name == 'release' }}
tags: |
beryju/authentik-proxy:2021.5.1-rc8,
beryju/authentik-proxy:2021.5.1,
beryju/authentik-proxy:latest,
ghcr.io/goauthentik/proxy:2021.5.1-rc8,
ghcr.io/goauthentik/proxy:2021.5.1,
ghcr.io/goauthentik/proxy:latest
context: outpost/
file: outpost/proxy.Dockerfile
@ -115,9 +115,9 @@ jobs:
with:
push: ${{ github.event_name == 'release' }}
tags: |
beryju/authentik-ldap:2021.5.1-rc8,
beryju/authentik-ldap:2021.5.1,
beryju/authentik-ldap:latest,
ghcr.io/goauthentik/ldap:2021.5.1-rc8,
ghcr.io/goauthentik/ldap:2021.5.1,
ghcr.io/goauthentik/ldap:latest
context: outpost/
file: outpost/ldap.Dockerfile
@ -139,7 +139,7 @@ jobs:
docker-compose pull -q
docker-compose up --no-start
docker-compose start postgresql redis
docker-compose run -u root --entrypoint /bin/bash server -c "pip install --no-cache -r requirements-dev.txt && ./manage.py test authentik"
docker-compose run -u root --entrypoint /bin/bash server -c "apt-get update && apt-get install -y --no-install-recommends git && pip install --no-cache -r requirements-dev.txt && ./manage.py test authentik"
sentry-release:
if: ${{ github.event_name == 'release' }}
needs:
@ -155,5 +155,5 @@ jobs:
SENTRY_PROJECT: authentik
SENTRY_URL: https://sentry.beryju.org
with:
version: authentik@2021.5.1-rc8
version: authentik@2021.5.1
environment: beryjuorg-prod

View File

@ -27,17 +27,17 @@ jobs:
-f Dockerfile .
docker-compose up --no-start
docker-compose start postgresql redis
docker-compose run -u root --entrypoint /bin/bash server -c "pip install --no-cache -r requirements-dev.txt && ./manage.py test authentik"
docker-compose run -u root --entrypoint /bin/bash server -c "apt-get update && apt-get install -y --no-install-recommends git && pip install --no-cache -r requirements-dev.txt && ./manage.py test authentik"
- name: Extract version number
id: get_version
uses: actions/github-script@0.2.0
uses: actions/github-script@v4.0.2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
return context.payload.ref.replace(/\/refs\/tags\/version\//, '');
- name: Create Release
id: create_release
uses: actions/create-release@v1.0.0
uses: actions/create-release@v1.1.4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:

View File

@ -48,7 +48,7 @@ ARG GIT_BUILD_HASH
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
RUN apt-get update && \
apt-get install -y --no-install-recommends curl ca-certificates gnupg git && \
apt-get install -y --no-install-recommends curl ca-certificates gnupg git runit && \
curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \
echo "deb http://apt.postgresql.org/pub/repos/apt buster-pgdg main" > /etc/apt/sources.list.d/pgdg.list && \
apt-get update && \
@ -58,14 +58,7 @@ RUN apt-get update && \
apt-get autoremove --purge -y && \
apt-get clean && \
rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/ && \
# This is quite hacky, but docker has no guaranteed Group ID
# we could instead check for the GID of the socket and add the user dynamically,
# but then we have to drop permmissions later
groupadd -g 998 docker_998 && \
groupadd -g 999 docker_999 && \
adduser --system --no-create-home --uid 1000 --group --home /authentik authentik && \
usermod -a -G docker_998 authentik && \
usermod -a -G docker_999 authentik && \
mkdir /backups && \
chown authentik:authentik /backups
@ -77,7 +70,6 @@ COPY ./lifecycle/ /lifecycle
COPY --from=builder /work/authentik /authentik-proxy
USER authentik
STOPSIGNAL SIGINT
ENV TMPDIR /dev/shm/
ENV PYTHONUBUFFERED 1
ENTRYPOINT [ "/lifecycle/bootstrap.sh" ]

View File

@ -36,11 +36,5 @@ gen:
--additional-properties=typescriptThreePlus=true,supportsES6=true,npmName=authentik-api,npmVersion=1.0.0
cd web/api && npx tsc
local-stack:
export AUTHENTIK_TAG=testing
docker build -t beryju/authentik:testng .
docker-compose up -d
docker-compose run --rm server migrate
run:
go run -v cmd/server/main.go

75
Pipfile.lock generated
View File

@ -122,19 +122,18 @@
},
"boto3": {
"hashes": [
"sha256:bcb1b76ca5a60586181ad202b19f4c50cb7c22ac68cae20f997abe311e22bf2a",
"sha256:edf9b3b36e08cd575a9458bf59871852335aceb5db2d07bfc8530bae3a97d045"
"sha256:3317722a1e9acbfc0d30cdf273d1708c823ceb19309e9cd91cac8a3604762341",
"sha256:ee3317fd79b443ef102469fac393a1ffb650ea51ac4fc27464013872c5e1ce31"
],
"index": "pypi",
"version": "==1.17.71"
"version": "==1.17.72"
},
"botocore": {
"hashes": [
"sha256:414e1721d381095767db1cf673257fdfec639da3be9405a41d49cc859b817d68",
"sha256:b7afebca1fd6ca1f8af79f377a445d474e3bd2cf88e704169d6713a6362a304f"
"sha256:0fa93a2e2daad5791c63ee526ada66896cc483d04cb2d32bfcadfeb881203453"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==1.20.71"
"version": "==1.20.72"
},
"cachetools": {
"hashes": [
@ -323,11 +322,11 @@
},
"django": {
"hashes": [
"sha256:0a1d195ad65c52bf275b8277b3d49680bd1137a5f55039a806f25f6b9752ce3d",
"sha256:18dd3145ddbd04bf189ff79b9954d08fda5171ea7b57bf705789fea766a07d50"
"sha256:13ac78dbfd189532cad8f383a27e58e18b3d33f80009ceb476d7fcbfc5dcebd8",
"sha256:7e0a1393d18c16b503663752a8b6790880c5084412618990ce8a81cc908b4962"
],
"index": "pypi",
"version": "==3.2.2"
"version": "==3.2.3"
},
"django-dbbackup": {
"git": "https://github.com/django-dbbackup/django-dbbackup.git",
@ -441,11 +440,11 @@
},
"geoip2": {
"hashes": [
"sha256:57d8d15de2527e0697bbef44fc16812bba709f03a07ef99297bd56c1df3b1efd",
"sha256:707025542ef076bd8fd80e97138bebdb7812527b2a007d141a27ad98b0370fff"
"sha256:906a1dbf15a179a1af3522970e8420ab15bb3e0afc526942cc179e12146d9c1d",
"sha256:b97b44031fdc463e84eb1316b4f19edd978cb1d78703465fcb1e36dc5a822ba6"
],
"index": "pypi",
"version": "==4.1.0"
"version": "==4.2.0"
},
"google-auth": {
"hashes": [
@ -607,19 +606,19 @@
},
"kubernetes": {
"hashes": [
"sha256:23c85d8571df8f56e773f1a413bc081537536dc47e2b5e8dc2e6262edb2c57ca",
"sha256:ec52ea01d52e2ec3da255992f7e859f3a76f2bdb51cf65ba8cd71dfc309d8daa"
"sha256:225a95a0aadbd5b645ab389d941a7980db8cdad2a776fde64d1b43fc3299bde9",
"sha256:c69b318696ba797dcf63eb928a8d4370c52319f4140023c502d7dfdf2080eb79"
],
"index": "pypi",
"version": "==12.0.1"
"version": "==17.17.0"
},
"ldap3": {
"hashes": [
"sha256:c1df41d89459be6f304e0ceec4b00fdea533dbbcd83c802b1272dcdb94620b57",
"sha256:18c3ee656a6775b9b0d60f7c6c5b094d878d1d90fc03d56731039f0a4b546a91",
"sha256:4139c91f0eef9782df7b77c8cbc6243086affcb6a8a249b768a9658438e5da59",
"sha256:8c949edbad2be8a03e719ba48bd6779f327ec156929562814b3e84ab56889c8c",
"sha256:afc6fc0d01f02af82cd7bfabd3bbfd5dc96a6ae91e97db0a2dab8a0f1b436056",
"sha256:c1df41d89459be6f304e0ceec4b00fdea533dbbcd83c802b1272dcdb94620b57"
"sha256:4139c91f0eef9782df7b77c8cbc6243086affcb6a8a249b768a9658438e5da59"
],
"index": "pypi",
"version": "==2.9"
@ -874,37 +873,37 @@
},
"pyasn1": {
"hashes": [
"sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359",
"sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576",
"sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf",
"sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7",
"sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d",
"sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00",
"sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8",
"sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86",
"sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12",
"sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776",
"sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12",
"sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359",
"sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3",
"sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba",
"sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2",
"sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"
"sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86",
"sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576",
"sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8",
"sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7",
"sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"
],
"version": "==0.4.8"
},
"pyasn1-modules": {
"hashes": [
"sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8",
"sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199",
"sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811",
"sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed",
"sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd",
"sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45",
"sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4",
"sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d",
"sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0",
"sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811",
"sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8",
"sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e",
"sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74",
"sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb",
"sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45",
"sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd",
"sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0",
"sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d",
"sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"
"sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405",
"sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed",
"sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"
],
"version": "==0.2.8"
},
@ -1603,11 +1602,11 @@
},
"gitpython": {
"hashes": [
"sha256:3283ae2fba31c913d857e12e5ba5f9a7772bbc064ae2bb09efafa71b0dd4939b",
"sha256:be27633e7509e58391f10207cd32b2a6cf5b908f92d9cd30da2e514e1137af61"
"sha256:2bfcd25e6b81fe431fa3ab1f0975986cfddabf7870a323c183f3afbc9447c0c5",
"sha256:37ac36cacf2e2be5e88f0810187c5833e71c1a2a8cf81588f5699d1b70183baa"
],
"markers": "python_version >= '3.4'",
"version": "==3.1.14"
"markers": "python_version >= '3.5'",
"version": "==3.1.16"
},
"idna": {
"hashes": [

View File

@ -1,3 +1,3 @@
"""authentik"""
__version__ = "2021.5.1-rc8"
__version__ = "2021.5.1"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -75,5 +75,6 @@ def backup_database(self: MonitoredTask): # pragma: no cover
Boto3Error,
PermissionError,
CommandConnectorError,
ValueError,
) as exc:
self.set_status(TaskResult(TaskResultStatus.ERROR).with_error(exc))

View File

@ -2,22 +2,25 @@
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.groups import GroupSerializer
from authentik.events.models import NotificationRule
class NotificationRuleSerializer(ModelSerializer):
"""NotificationRule Serializer"""
group_obj = GroupSerializer(read_only=True, source="group")
class Meta:
model = NotificationRule
depth = 2
fields = [
"pk",
"name",
"transports",
"severity",
"group",
"group_obj",
]

View File

@ -210,6 +210,7 @@ class FlowViewSet(ModelViewSet):
request.user, "authentik_policies.view_policybinding"
)
.filter(target=stage_binding)
.exclude(policy__isnull=True)
.order_by("order")
):
body.append(

View File

@ -42,7 +42,8 @@ outposts:
# Placeholders:
# %(type)s: Outpost type; proxy, ldap, etc
# %(version)s: Current version; 2021.4.1
docker_image_base: "beryju/authentik-%(type)s:%(version)s"
# %(build_hash)s: Build hash if you're running a beta version
docker_image_base: "ghcr.io/goauthentik/%(type)s:%(version)s"
authentik:
avatars: gravatar # gravatar or none

View File

@ -4,6 +4,7 @@ from typing import Optional
from aioredis.errors import ConnectionClosedError, ReplyError
from billiard.exceptions import WorkerLostError
from botocore.client import ClientError
from botocore.exceptions import BotoCoreError
from celery.exceptions import CeleryError
from channels.middleware import BaseMiddleware
from channels_redis.core import ChannelFull
@ -72,6 +73,7 @@ def before_send(event: dict, hint: dict) -> Optional[dict]:
WorkerLostError,
CeleryError,
# S3 errors
BotoCoreError,
ClientError,
# custom baseclass
SentryIgnoredException,
@ -87,6 +89,6 @@ def before_send(event: dict, hint: dict) -> Optional[dict]:
if isinstance(exc_value, ignored_classes):
return None
if "logger" in event:
if event["logger"] in ["dbbackup"]:
if event["logger"] in ["dbbackup", "botocore"]:
return None
return event

View File

@ -18,8 +18,6 @@ class OutpostSerializer(ModelSerializer):
"""Outpost Serializer"""
config = JSONField(validators=[is_dict], source="_config")
# TODO: Remove _config again, this is only here for legacy with older outposts
_config = JSONField(validators=[is_dict], read_only=True)
providers_obj = ProviderSerializer(source="providers", many=True, read_only=True)
def validate_config(self, config) -> dict:
@ -42,7 +40,6 @@ class OutpostSerializer(ModelSerializer):
"service_connection",
"token_identifier",
"config",
"_config",
]

View File

@ -82,6 +82,7 @@ class OutpostConsumer(AuthJsonConsumer):
)
if msg.instruction == WebsocketMessageInstruction.HELLO:
state.version = msg.args.get("version", None)
state.build_hash = msg.args.get("buildHash", "")
elif msg.instruction == WebsocketMessageInstruction.ACK:
return
state.save(timeout=OUTPOST_HELLO_INTERVAL * 1.5)

View File

@ -1,11 +1,12 @@
"""Base Controller"""
from dataclasses import dataclass
from os import environ
from typing import Optional
from structlog.stdlib import get_logger
from structlog.testing import capture_logs
from authentik import __version__
from authentik import ENV_GIT_HASH_KEY, __version__
from authentik.lib.config import CONFIG
from authentik.lib.sentry import SentryIgnoredException
from authentik.outposts.models import Outpost, OutpostServiceConnection
@ -69,4 +70,8 @@ class BaseController:
def get_container_image(self) -> str:
"""Get container image to use for this outpost"""
image_name_template: str = CONFIG.y("outposts.docker_image_base")
return image_name_template % {"type": self.outpost.type, "version": __version__}
return image_name_template % {
"type": self.outpost.type,
"version": __version__,
"build_hash": environ.get(ENV_GIT_HASH_KEY, ""),
}

View File

@ -1,6 +1,7 @@
"""Outpost models"""
from dataclasses import asdict, dataclass, field
from datetime import datetime
from os import environ
from typing import Iterable, Optional, Union
from uuid import uuid4
@ -26,7 +27,7 @@ from packaging.version import LegacyVersion, Version, parse
from structlog.stdlib import get_logger
from urllib3.exceptions import HTTPError
from authentik import __version__
from authentik import ENV_GIT_HASH_KEY, __version__
from authentik.core.models import USER_ATTRIBUTE_SA, Provider, Token, TokenIntents, User
from authentik.crypto.models import CertificateKeyPair
from authentik.lib.config import CONFIG
@ -411,6 +412,7 @@ class OutpostState:
last_seen: Optional[datetime] = field(default=None)
version: Optional[str] = field(default=None)
version_should: Union[Version, LegacyVersion] = field(default=OUR_VERSION)
build_hash: str = field(default="")
_outpost: Optional[Outpost] = field(default=None)
@ -419,6 +421,8 @@ class OutpostState:
"""Check if outpost version matches our version"""
if not self.version:
return False
if self.build_hash != environ.get(ENV_GIT_HASH_KEY, ""):
return False
return parse(self.version) < OUR_VERSION
@staticmethod

View File

@ -320,6 +320,7 @@ CELERY_RESULT_BACKEND = (
# Database backup
DBBACKUP_STORAGE = "django.core.files.storage.FileSystemStorage"
DBBACKUP_STORAGE_OPTIONS = {"location": "./backups" if DEBUG else "/backups"}
DBBACKUP_FILENAME_TEMPLATE = "authentik-backup-{datetime}.sql"
if CONFIG.y("postgresql.s3_backup"):
DBBACKUP_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
DBBACKUP_STORAGE_OPTIONS = {

View File

@ -1,9 +1,8 @@
"""AuthenticatorStaticStage API Views"""
from django_filters import OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from django_otp.plugins.otp_static.models import StaticDevice
from guardian.utils import get_anonymous_user
from rest_framework.filters import SearchFilter
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAdminUser
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet

View File

@ -21,7 +21,7 @@ services:
networks:
- internal
server:
image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.5.1-rc8}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.5.1}
restart: unless-stopped
command: server
environment:
@ -52,7 +52,7 @@ services:
- "0.0.0.0:9000:9000"
- "0.0.0.0:9443:9443"
worker:
image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.5.1-rc8}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.5.1}
restart: unless-stopped
command: worker
networks:
@ -64,8 +64,13 @@ services:
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
# AUTHENTIK_ERROR_REPORTING__ENABLED: "true"
# This is optional, and can be removed. If you remove this, the following will happen
# - The permissions for the /backups and /media folders aren't fixed, so make sure they are 1000:1000
# - The docker socket can't be accessed anymore
user: root
volumes:
- ./backups:/backups
- ./media:/media
- /var/run/docker.sock:/var/run/docker.sock
- ./custom-templates:/templates
- geoip:/geoip

View File

@ -1,3 +1,3 @@
package constants
const VERSION = "2021.5.1-rc8"
const VERSION = "2021.5.1"

View File

@ -1,14 +1,29 @@
#!/bin/bash -e
python -m lifecycle.wait_for_db
printf '{"event": "Bootstrap completed", "level": "info", "logger": "bootstrap", "command": "%s"}\n' "$@" > /dev/stderr
function check_if_root {
if [[ $EUID -ne 0 ]]; then
printf '{"event": "Not running as root, disabling permission fixes", "level": "info", "logger": "bootstrap", "command": "%s"}\n' "$@" > /dev/stderr
return
fi
SOCKET="/var/run/docker.sock"
if [[ -e "$SOCKET" ]]; then
# Get group ID of the docker socket, so we can create a matching group and
# add ourselves to it
DOCKER_GID=$(stat -c '%g' $SOCKET)
usermod -a -G $DOCKER_GID authentik
fi
# Fix permissions of backups and media
chown -R authentik:authentik /media /backups
}
if [[ "$1" == "server" ]]; then
python -m lifecycle.migrate
/authentik-proxy
elif [[ "$1" == "worker" ]]; then
celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events
elif [[ "$1" == "migrate" ]]; then
printf "DEPERECATED: database migrations are now executed automatically on startup."
python -m lifecycle.migrate
check_if_root
chpst -u authentik env HOME=/authentik celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events
elif [[ "$1" == "backup" ]]; then
python -m manage dbbackup --clean
elif [[ "$1" == "restore" ]]; then

View File

@ -113,10 +113,21 @@ stages:
inputs:
containerRegistry: 'beryjuorg-harbor'
repository: 'authentik/outpost-proxy'
command: 'buildAndPush'
command: 'build'
Dockerfile: 'outpost/proxy.Dockerfile'
buildContext: 'outpost/'
tags: "gh-$(branchName)"
tags: |
gh-$(branchName)
gh-$(Build.SourceVersion)
arguments: '--build-arg GIT_BUILD_HASH=$(Build.SourceVersion)'
- task: Docker@2
inputs:
containerRegistry: 'beryjuorg-harbor'
repository: 'authentik/outpost-proxy'
command: 'push'
tags: |
gh-$(branchName)
gh-$(Build.SourceVersion)
- job: ldap_build_docker
pool:
vmImage: 'ubuntu-latest'
@ -138,7 +149,18 @@ stages:
inputs:
containerRegistry: 'beryjuorg-harbor'
repository: 'authentik/outpost-ldap'
command: 'buildAndPush'
command: 'build'
Dockerfile: 'outpost/ldap.Dockerfile'
buildContext: 'outpost/'
tags: "gh-$(branchName)"
tags: |
gh-$(branchName)
gh-$(Build.SourceVersion)
arguments: '--build-arg GIT_BUILD_HASH=$(Build.SourceVersion)'
- task: Docker@2
inputs:
containerRegistry: 'beryjuorg-harbor'
repository: 'authentik/outpost-ldap'
command: 'push'
tags: |
gh-$(branchName)
gh-$(Build.SourceVersion)

View File

@ -1,4 +1,6 @@
FROM golang:1.16.4 AS builder
ARG GIT_BUILD_HASH
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
WORKDIR /work

View File

@ -1,7 +1,6 @@
package ak
import (
"fmt"
"math/rand"
"net/url"
"os"
@ -43,7 +42,7 @@ type APIController struct {
// NewAPIController initialise new API Controller instance from URL and API token
func NewAPIController(akURL url.URL, token string) *APIController {
transport := httptransport.New(akURL.Host, client.DefaultBasePath, []string{akURL.Scheme})
transport.Transport = SetUserAgent(getTLSTransport(), fmt.Sprintf("authentik-proxy@%s", pkg.VERSION))
transport.Transport = SetUserAgent(getTLSTransport(), pkg.UserAgent())
// create the transport
auth := httptransport.BearerToken(token)

View File

@ -23,7 +23,7 @@ func (ac *APIController) initWS(akURL url.URL, outpostUUID strfmt.UUID) {
header := http.Header{
"Authorization": []string{authHeader},
"User-Agent": []string{fmt.Sprintf("authentik-proxy@%s", pkg.VERSION)},
"User-Agent": []string{pkg.UserAgent()},
}
value, set := os.LookupEnv("AUTHENTIK_INSECURE")
@ -46,8 +46,9 @@ func (ac *APIController) initWS(akURL url.URL, outpostUUID strfmt.UUID) {
msg := websocketMessage{
Instruction: WebsocketInstructionHello,
Args: map[string]interface{}{
"version": pkg.VERSION,
"uuid": ac.instanceUUID.String(),
"version": pkg.VERSION,
"buildHash": pkg.BUILD(),
"uuid": ac.instanceUUID.String(),
},
}
err := ws.WriteJSON(msg)
@ -76,7 +77,7 @@ func (ac *APIController) startWSHandler() {
var wsMsg websocketMessage
err := ac.wsConn.ReadJSON(&wsMsg)
if err != nil {
logger.Println("read:", err)
logger.WithError(err).Warning("ws write error, reconnecting")
ac.wsConn.CloseAndReconnect()
continue
}
@ -100,14 +101,15 @@ func (ac *APIController) startWSHealth() {
aliveMsg := websocketMessage{
Instruction: WebsocketInstructionHello,
Args: map[string]interface{}{
"version": pkg.VERSION,
"uuid": ac.instanceUUID.String(),
"version": pkg.VERSION,
"buildHash": pkg.BUILD(),
"uuid": ac.instanceUUID.String(),
},
}
err := ac.wsConn.WriteJSON(aliveMsg)
ac.logger.WithField("loop", "ws-health").Trace("hello'd")
if err != nil {
ac.logger.WithField("loop", "ws-health").Println("write:", err)
ac.logger.WithField("loop", "ws-health").WithError(err).Warning("ws write error, reconnecting")
ac.wsConn.CloseAndReconnect()
continue
}

View File

@ -33,7 +33,7 @@ func doGlobalSetup(config map[string]interface{}) {
default:
log.SetLevel(log.DebugLevel)
}
log.WithField("version", pkg.VERSION).Info("Starting authentik outpost")
log.WithField("buildHash", pkg.BUILD()).WithField("version", pkg.VERSION).Info("Starting authentik outpost")
var dsn string
if config[ConfigErrorReportingEnabled].(bool) {

View File

@ -2,20 +2,22 @@ package ldap
import (
"net"
"strings"
"github.com/nmcclain/ldap"
)
func (ls *LDAPServer) Bind(bindDN string, bindPW string, conn net.Conn) (ldap.LDAPResultCode, error) {
ls.log.WithField("boundDN", bindDN).Info("bind")
ls.log.WithField("bindDN", bindDN).Info("bind")
bindDN = strings.ToLower(bindDN)
for _, instance := range ls.providers {
username, err := instance.getUsername(bindDN)
if err == nil {
return instance.Bind(username, bindPW, conn)
return instance.Bind(username, bindDN, bindPW, conn)
} else {
ls.log.WithError(err).Debug("Username not for instance")
}
}
ls.log.WithField("boundDN", bindDN).WithField("request", "bind").Warning("No provider found for request")
ls.log.WithField("bindDN", bindDN).WithField("request", "bind").Warning("No provider found for request")
return ldap.LDAPResultOperationsError, nil
}

View File

@ -47,7 +47,7 @@ func (pi *ProviderInstance) getUsername(dn string) (string, error) {
return "", errors.New("failed to find cn")
}
func (pi *ProviderInstance) Bind(username string, bindPW string, conn net.Conn) (ldap.LDAPResultCode, error) {
func (pi *ProviderInstance) Bind(username string, bindDN, bindPW string, conn net.Conn) (ldap.LDAPResultCode, error) {
jar, err := cookiejar.New(nil)
if err != nil {
pi.log.WithError(err).Warning("Failed to create cookiejar")
@ -67,9 +67,9 @@ func (pi *ProviderInstance) Bind(username string, bindPW string, conn net.Conn)
}
params := url.Values{}
params.Add("goauthentik.io/outpost/ldap", "true")
passed, err := pi.solveFlowChallenge(username, bindPW, client, params.Encode())
passed, err := pi.solveFlowChallenge(username, bindPW, client, params.Encode(), 1)
if err != nil {
pi.log.WithField("boundDN", username).WithError(err).Warning("failed to solve challenge")
pi.log.WithField("bindDN", bindDN).WithError(err).Warning("failed to solve challenge")
return ldap.LDAPResultOperationsError, nil
}
if !passed {
@ -82,25 +82,25 @@ func (pi *ProviderInstance) Bind(username string, bindPW string, conn net.Conn)
}, httptransport.PassThroughAuth)
if err != nil {
if _, denied := err.(*core.CoreApplicationsCheckAccessForbidden); denied {
pi.log.WithField("boundDN", username).Info("Access denied for user")
pi.log.WithField("bindDN", bindDN).Info("Access denied for user")
return ldap.LDAPResultInsufficientAccessRights, nil
}
pi.log.WithField("boundDN", username).WithError(err).Warning("failed to check access")
pi.log.WithField("bindDN", bindDN).WithError(err).Warning("failed to check access")
return ldap.LDAPResultOperationsError, nil
}
pi.log.WithField("boundDN", username).Info("User has access")
pi.log.WithField("bindDN", bindDN).Info("User has access")
// Get user info to store in context
userInfo, err := pi.s.ac.Client.Core.CoreUsersMe(&core.CoreUsersMeParams{
Context: context.Background(),
HTTPClient: client,
}, httptransport.PassThroughAuth)
if err != nil {
pi.log.WithField("boundDN", username).WithError(err).Warning("failed to get user info")
pi.log.WithField("bindDN", bindDN).WithError(err).Warning("failed to get user info")
return ldap.LDAPResultOperationsError, nil
}
pi.boundUsersMutex.Lock()
pi.boundUsers[username] = UserFlags{
UserInfo: userInfo.Payload.User,
pi.boundUsers[bindDN] = UserFlags{
UserInfo: *userInfo.Payload.User,
CanSearch: pi.SearchAccessCheck(userInfo.Payload.User),
}
defer pi.boundUsersMutex.Unlock()
@ -112,7 +112,8 @@ func (pi *ProviderInstance) Bind(username string, bindPW string, conn net.Conn)
func (pi *ProviderInstance) SearchAccessCheck(user *models.User) bool {
for _, group := range user.Groups {
for _, allowedGroup := range pi.searchAllowedGroups {
if &group.Pk == allowedGroup {
pi.log.WithField("userGroup", group.Pk).WithField("allowedGroup", allowedGroup).Trace("Checking search access")
if group.Pk.String() == allowedGroup.String() {
pi.log.WithField("group", group.Name).Info("Allowed access to search")
return true
}
@ -139,7 +140,7 @@ func (pi *ProviderInstance) delayDeleteUserInfo(dn string) {
}()
}
func (pi *ProviderInstance) solveFlowChallenge(bindDN string, password string, client *http.Client, urlParams string) (bool, error) {
func (pi *ProviderInstance) solveFlowChallenge(bindDN string, password string, client *http.Client, urlParams string, depth int) (bool, error) {
challenge, err := pi.s.ac.Client.Flows.FlowsExecutorGet(&flows.FlowsExecutorGetParams{
FlowSlug: pi.flowSlug,
Query: urlParams,
@ -169,6 +170,10 @@ func (pi *ProviderInstance) solveFlowChallenge(bindDN string, password string, c
}
response, err := pi.s.ac.Client.Flows.FlowsExecutorSolve(responseParams, pi.s.ac.Auth)
pi.log.WithField("component", response.Payload.Component).WithField("type", *response.Payload.Type).Debug("Got response")
switch response.Payload.Component {
case "ak-stage-access-denied":
return false, errors.New("got ak-stage-access-denied")
}
if *response.Payload.Type == "redirect" {
return true, nil
}
@ -184,5 +189,8 @@ func (pi *ProviderInstance) solveFlowChallenge(bindDN string, password string, c
}
}
}
return pi.solveFlowChallenge(bindDN, password, client, urlParams)
if depth >= 10 {
return false, errors.New("exceeded stage recursion depth")
}
return pi.solveFlowChallenge(bindDN, password, client, urlParams, depth+1)
}

View File

@ -29,10 +29,13 @@ func (pi *ProviderInstance) Search(bindDN string, searchReq ldap.SearchRequest,
pi.boundUsersMutex.RLock()
defer pi.boundUsersMutex.RUnlock()
flags, ok := pi.boundUsers[bindDN]
pi.log.WithField("bindDN", bindDN).WithField("ok", ok).Debugf("%+v\n", flags)
if !ok {
pi.log.Debug("User info not cached")
return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultInsufficientAccessRights}, errors.New("access denied")
}
if !flags.CanSearch {
pi.log.Debug("User can't search")
return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultInsufficientAccessRights}, errors.New("access denied")
}

View File

@ -31,7 +31,7 @@ type ProviderInstance struct {
}
type UserFlags struct {
UserInfo *models.User
UserInfo models.User
CanSearch bool
}

View File

@ -8,8 +8,8 @@ import (
"github.com/nmcclain/ldap"
)
func (ls *LDAPServer) Search(boundDN string, searchReq ldap.SearchRequest, conn net.Conn) (ldap.ServerSearchResult, error) {
ls.log.WithField("boundDN", boundDN).WithField("baseDN", searchReq.BaseDN).Info("search")
func (ls *LDAPServer) Search(bindDN string, searchReq ldap.SearchRequest, conn net.Conn) (ldap.ServerSearchResult, error) {
ls.log.WithField("bindDN", bindDN).WithField("baseDN", searchReq.BaseDN).Info("search")
if searchReq.BaseDN == "" {
return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultSuccess}, nil
}
@ -21,7 +21,7 @@ func (ls *LDAPServer) Search(boundDN string, searchReq ldap.SearchRequest, conn
for _, provider := range ls.providers {
providerBase, _ := goldap.ParseDN(provider.BaseDN)
if providerBase.AncestorOf(bd) {
return provider.Search(boundDN, searchReq, conn)
return provider.Search(bindDN, searchReq, conn)
}
}
return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, errors.New("no provider could handle request")

View File

@ -161,7 +161,7 @@ func (p *OAuthProxy) OAuthStart(rw http.ResponseWriter, req *http.Request) {
p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
return
}
redirectURI := p.GetRedirectURI(getHost(req))
redirectURI := p.GetRedirectURI(req.Host)
http.Redirect(rw, req, p.provider.GetLoginURL(redirectURI, fmt.Sprintf("%v:%v", nonce, redirect)), http.StatusFound)
}

View File

@ -1,3 +1,16 @@
package pkg
const VERSION = "2021.5.1-rc8"
import (
"fmt"
"os"
)
const VERSION = "2021.5.1"
func BUILD() string {
return os.Getenv("GIT_BUILD_HASH")
}
func UserAgent() string {
return fmt.Sprintf("authentik-outpost@%s (%s)", VERSION, BUILD())
}

View File

@ -1,4 +1,6 @@
FROM golang:1.16.4 AS builder
ARG GIT_BUILD_HASH
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
WORKDIR /work

View File

@ -15694,6 +15694,7 @@ definitions:
NotificationRule:
required:
- name
- transports
type: object
properties:
pk:
@ -15706,38 +15707,17 @@ definitions:
type: string
minLength: 1
transports:
description: Select which transports should be used to notify the user. If
none are selected, the notification will only be shown in the authentik
UI.
type: array
items:
required:
- name
- mode
type: object
properties:
uuid:
title: Uuid
type: string
format: uuid
readOnly: true
name:
title: Name
type: string
minLength: 1
mode:
title: Mode
type: string
enum:
- webhook
- webhook_slack
- email
webhook_url:
title: Webhook url
type: string
send_once:
title: Send once
description: Only send notification once, for example when sending a
webhook into a chat channel.
type: boolean
readOnly: true
description: Select which transports should be used to notify the user.
If none are selected, the notification will only be shown in the authentik
UI.
type: string
format: uuid
uniqueItems: true
severity:
title: Severity
description: Controls which severity level the created notifications will
@ -15748,57 +15728,14 @@ definitions:
- warning
- alert
group:
required:
- name
type: object
properties:
group_uuid:
title: Group uuid
type: string
format: uuid
readOnly: true
name:
title: Name
type: string
maxLength: 80
minLength: 1
is_superuser:
title: Is superuser
description: Users added to this group will be superusers.
type: boolean
attributes:
title: Attributes
type: object
parent:
required:
- name
- parent
type: object
properties:
group_uuid:
title: Group uuid
type: string
format: uuid
readOnly: true
name:
title: Name
type: string
maxLength: 80
minLength: 1
is_superuser:
title: Is superuser
description: Users added to this group will be superusers.
type: boolean
attributes:
title: Attributes
type: object
parent:
title: Parent
type: string
format: uuid
x-nullable: true
readOnly: true
readOnly: true
title: Group
description: Define which group of users this notification should be sent
and shown to. If left empty, Notification won't ben sent.
type: string
format: uuid
x-nullable: true
group_obj:
$ref: '#/definitions/Group'
NotificationTransport:
required:
- name

View File

@ -70,7 +70,7 @@ class TestProviderProxy(SeleniumTestCase):
authorization_flow=Flow.objects.get(
slug="default-provider-authorization-implicit-consent"
),
internal_host="http://localhost:80",
internal_host="http://localhost",
external_host="http://localhost:4180",
)
# Ensure OAuth2 Params are set
@ -123,7 +123,7 @@ class TestProviderProxyConnect(ChannelsLiveServerTestCase):
authorization_flow=Flow.objects.get(
slug="default-provider-authorization-implicit-consent"
),
internal_host="http://localhost:80",
internal_host="http://localhost",
external_host="http://localhost:4180",
)
# Ensure OAuth2 Params are set

View File

@ -104,5 +104,5 @@ class OutpostDockerTests(TestCase):
self.assertEqual(compose["version"], "3.5")
self.assertEqual(
compose["services"]["authentik_proxy"]["image"],
f"beryju/authentik-proxy:{__version__}",
f"ghcr.io/goauthentik/proxy:{__version__}",
)

View File

@ -104,5 +104,5 @@ class TestProxyDocker(TestCase):
self.assertEqual(compose["version"], "3.5")
self.assertEqual(
compose["services"]["authentik_proxy"]["image"],
f"beryju/authentik-proxy:{__version__}",
f"ghcr.io/goauthentik/proxy:{__version__}",
)

View File

@ -81,7 +81,7 @@ http {
location /static/ {
expires 31d;
add_header Cache-Control "public, no-transform";
add_header X-authentik-version "2021.5.1-rc8";
add_header X-authentik-version "2021.5.1";
add_header Vary X-authentik-version;
}

1379
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -35,10 +35,10 @@
]
},
"dependencies": {
"@babel/core": "^7.14.0",
"@babel/plugin-proposal-decorators": "^7.13.15",
"@babel/plugin-transform-runtime": "^7.13.15",
"@babel/preset-env": "^7.14.1",
"@babel/core": "^7.14.2",
"@babel/plugin-proposal-decorators": "^7.14.2",
"@babel/plugin-transform-runtime": "^7.14.2",
"@babel/preset-env": "^7.14.2",
"@babel/preset-typescript": "^7.13.0",
"@fortawesome/fontawesome-free": "^5.15.3",
"@lingui/cli": "^3.8.10",

View File

@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
export const ERROR_CLASS = "pf-m-danger";
export const PROGRESS_CLASS = "pf-m-in-progress";
export const CURRENT_CLASS = "pf-m-current";
export const VERSION = "2021.5.1-rc8";
export const VERSION = "2021.5.1";
export const PAGE_SIZE = 20;
export const EVENT_REFRESH = "ak-refresh";
export const EVENT_NOTIFICATION_TOGGLE = "ak-notification-toggle";

View File

@ -67,7 +67,7 @@ export class RuleForm extends ModelForm<NotificationRule, string> {
<option value="" ?selected=${this.instance?.group === undefined}>---------</option>
${until(new CoreApi(DEFAULT_CONFIG).coreGroupsList({}).then(groups => {
return groups.results.map(group => {
return html`<option value=${ifDefined(group.pk)} ?selected=${this.instance?.group?.groupUuid === group.pk}>${group.name}</option>`;
return html`<option value=${ifDefined(group.pk)} ?selected=${this.instance?.group === group.pk}>${group.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -80,7 +80,7 @@ export class RuleForm extends ModelForm<NotificationRule, string> {
${until(new EventsApi(DEFAULT_CONFIG).eventsTransportsList({}).then(transports => {
return transports.results.map(transport => {
const selected = Array.from(this.instance?.transports || []).some(su => {
return su.uuid == transport.pk;
return su == transport.pk;
});
return html`<option value=${ifDefined(transport.pk)} ?selected=${selected}>${transport.name}</option>`;
});

View File

@ -55,7 +55,7 @@ export class RuleListPage extends TablePage<NotificationRule> {
return [
html`${item.name}`,
html`${item.severity}`,
html`${item.group?.name || t`None (rule disabled)`}`,
html`${item.groupObj?.name || t`None (rule disabled)`}`,
html`
<ak-forms-modal>
<span slot="submit">

View File

@ -58,14 +58,6 @@ export class FlowViewPage extends LitElement {
<ak-tabs>
<div slot="page-overview" data-tab-title="${t`Flow Overview`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-l-gallery pf-m-gutter">
<div class="pf-c-card pf-l-gallery__item" style="grid-column-end: span 4;grid-row-end: span 2;">
<div class="pf-c-card">
<div class="pf-c-card__body">
<ak-flow-diagram flowSlug=${this.flow.slug}>
</ak-flow-diagram>
</div>
</div>
</div>
<div class="pf-c-card pf-l-gallery__item">
<div class="pf-c-card__title">${t`Related`}</div>
<div class="pf-c-card__body">
@ -94,6 +86,14 @@ export class FlowViewPage extends LitElement {
</dl>
</div>
</div>
<div class="pf-c-card pf-l-gallery__item" style="grid-column-end: span 4;grid-row-end: span 2;">
<div class="pf-c-card">
<div class="pf-c-card__body">
<ak-flow-diagram flowSlug=${this.flow.slug}>
</ak-flow-diagram>
</div>
</div>
</div>
</div>
</div>
<div slot="page-stage-bindings" data-tab-title="${t`Stage Bindings`}" class="pf-c-page__main-section pf-m-no-padding-mobile">

View File

@ -42,13 +42,12 @@ export class OutpostHealthElement extends LitElement {
return html`<ak-spinner></ak-spinner>`;
}
if (this.outpostHealth.length === 0) {
return html`<li>
return html`
<ul>
<li role="cell">
<ak-label color=${PFColor.Grey} text=${t`Not available`}></ak-label>
</li>
</ul>
</li>`;
</ul>`;
}
return html`<ul>${this.outpostHealth.map((h) => {
return html`<li>

View File

@ -76,6 +76,40 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
this.plexResources = await new PlexAPIClient(this.plexToken).getServers();
}
renderSettings(): TemplateResult {
if (!this.plexToken) {
return html`
<button class="pf-c-button pf-m-primary" type="button" @click=${() => {
this.doAuth();
}}>
${t`Load servers`}
</button>`;
}
return html`<ak-form-element-horizontal name="allowFriends">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.allowFriends, true)}>
<label class="pf-c-check__label">
${t`Allow friends to authenticate via Plex, even if you don't share any servers`}
</label>
</div>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Allowed servers`}
?required=${true}
name="allowedServers">
<select class="pf-c-form-control" multiple>
${this.plexResources?.map(r => {
const selected = Array.from(this.instance?.allowedServers || []).some(server => {
return server == r.clientIdentifier;
});
return html`<option value=${r.clientIdentifier} ?selected=${selected}>${r.name}</option>`;
})}
</select>
<p class="pf-c-form__helper-text">${t`Select which server a user has to be a member of to be allowed to authenticate.`}</p>
<p class="pf-c-form__helper-text">${t`Hold control/command to select multiple items.`}</p>
</ak-form-element-horizontal>`;
}
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
@ -132,36 +166,7 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
name="clientId">
<input type="text" value="${first(this.instance?.clientId)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="allowFriends">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.allowFriends, true)}>
<label class="pf-c-check__label">
${t`Allow friends to authenticate via Plex, even if you don't share any servers`}
</label>
</div>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Allowed servers`}
?required=${true}
name="allowedServers">
<select class="pf-c-form-control" multiple>
${this.plexResources?.map(r => {
const selected = Array.from(this.instance?.allowedServers || []).some(server => {
return server == r.clientIdentifier;
});
return html`<option value=${r.clientIdentifier} ?selected=${selected}>${r.name}</option>`;
})}
</select>
<p class="pf-c-form__helper-text">${t`Select which server a user has to be a member of to be allowed to authenticate.`}</p>
<p class="pf-c-form__helper-text">${t`Hold control/command to select multiple items.`}</p>
<p class="pf-c-form__helper-text">
<button class="pf-c-button pf-m-primary" type="button" @click=${() => {
this.doAuth();
}}>
${t`Load servers`}
</button>
</p>
</ak-form-element-horizontal>
${this.renderSettings()}
</div>
</ak-form-group>
<ak-form-group>

View File

@ -70,7 +70,7 @@ export class AuthenticatorValidateStageForm extends ModelForm<AuthenticatorValid
<ak-form-element-horizontal
label=${t`Not configured action`}
?required=${true}
name="mode">
name="notConfiguredAction">
<select class="pf-c-form-control" @change=${(ev: Event) => {
const target = ev.target as HTMLSelectElement;
if (target.selectedOptions[0].value === AuthenticatorValidateStageNotConfiguredActionEnum.Configure) {

View File

@ -16,7 +16,7 @@ Download the latest `docker-compose.yml` from [here](https://raw.githubuserconte
To optionally enable error-reporting, run `echo AUTHENTIK_ERROR_REPORTING__ENABLED=true >> .env`
To optionally deploy a different version run `echo AUTHENTIK_TAG=2021.5.1-rc8 >> .env`
To optionally deploy a different version run `echo AUTHENTIK_TAG=2021.5.1 >> .env`
If this is a fresh authentik install run the following commands to generate a password:

View File

@ -11,7 +11,7 @@ version: "3.5"
services:
authentik_proxy:
image: beryju/authentik-proxy:2021.5.1-rc8
image: beryju/authentik-proxy:2021.5.1
ports:
- 4180:4180
- 4443:4443

View File

@ -14,7 +14,7 @@ metadata:
app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1-rc8
app.kubernetes.io/version: 2021.5.1
name: authentik-outpost-api
stringData:
authentik_host: "__AUTHENTIK_URL__"
@ -29,7 +29,7 @@ metadata:
app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1-rc8
app.kubernetes.io/version: 2021.5.1
name: authentik-outpost
spec:
ports:
@ -54,7 +54,7 @@ metadata:
app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1-rc8
app.kubernetes.io/version: 2021.5.1
name: authentik-outpost
spec:
selector:
@ -62,14 +62,14 @@ spec:
app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1-rc8
app.kubernetes.io/version: 2021.5.1
template:
metadata:
labels:
app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1-rc8
app.kubernetes.io/version: 2021.5.1
spec:
containers:
- env:
@ -88,7 +88,7 @@ spec:
secretKeyRef:
key: authentik_host_insecure
name: authentik-outpost-api
image: beryju/authentik-proxy:2021.5.1-rc8
image: beryju/authentik-proxy:2021.5.1
name: proxy
ports:
- containerPort: 4180
@ -110,7 +110,7 @@ metadata:
app.kubernetes.io/instance: __OUTPOST_NAME__
app.kubernetes.io/managed-by: goauthentik.io
app.kubernetes.io/name: authentik-proxy
app.kubernetes.io/version: 2021.5.1-rc8
app.kubernetes.io/version: 2021.5.1
name: authentik-outpost
spec:
rules:

View File

@ -34,7 +34,7 @@ module.exports = {
position: "left",
},
{
href: "https://github.com/beryju/authentik",
href: "https://github.com/goauthentik/authentik",
label: "GitHub",
position: "right",
},
@ -69,7 +69,7 @@ module.exports = {
items: [
{
label: "GitHub",
href: "https://github.com/beryju/authentik",
href: "https://github.com/goauthentik/authentik",
},
{
label: "Discord",
@ -95,7 +95,7 @@ module.exports = {
docs: {
id: "docs",
sidebarPath: require.resolve("./sidebars.js"),
editUrl: "https://github.com/beryju/authentik/edit/master/website/",
editUrl: "https://github.com/goauthentik/authentik/edit/master/website/",
},
theme: {
customCss: require.resolve("./src/css/custom.css"),
@ -111,7 +111,7 @@ module.exports = {
path: 'developer-docs',
routeBasePath: 'developer-docs',
sidebarPath: require.resolve('./sidebarsDev.js'),
editUrl: "https://github.com/beryju/authentik/edit/master/website/",
editUrl: "https://github.com/goauthentik/authentik/edit/master/website/",
},
],
],

8127
website/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
"serve": "docusaurus serve"
},
"dependencies": {
"@docusaurus/preset-classic": "2.0.0-alpha.75",
"@docusaurus/preset-classic": "2.0.0-beta.0",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.1.1",
"postcss": "^8.2.15",