Compare commits
101 Commits
version-20
...
version/20
| Author | SHA1 | Date | |
|---|---|---|---|
| 3d724db0e3 | |||
| 2997542114 | |||
| 84b18fff96 | |||
| 1dce408c72 | |||
| e5ff47bf14 | |||
| b53bf331c3 | |||
| 90e9a8b34c | |||
| 845f842783 | |||
| 7397849c60 | |||
| 6dd46b5fc5 | |||
| 89ca79ed10 | |||
| 713bef895c | |||
| 925115e9ce | |||
| 42f5cf8c93 | |||
| 82cc1d536a | |||
| 08af2fd46b | |||
| 70e3b27a4d | |||
| 6a411d7960 | |||
| 33567b56d7 | |||
| 0c1954aeb7 | |||
| f4a6c70e98 | |||
| 5f198e7fe4 | |||
| d172d32817 | |||
| af3fb5c2cd | |||
| 885efb526e | |||
| 3bfb8b2cb2 | |||
| 9fc5ff4b77 | |||
| dd8b579dd6 | |||
| e12cbd8711 | |||
| 62d35f8f8c | |||
| 49be504c13 | |||
| edad55e51d | |||
| 38086fa8bb | |||
| c4f9a3e9a7 | |||
| 930df791bd | |||
| 9a6086634c | |||
| b68e65355a | |||
| 72d33a91dd | |||
| 7067e3d69a | |||
| 4db370d24e | |||
| 41e7b9b73f | |||
| 7f47f93e4e | |||
| 89abd44b76 | |||
| 14c7d8c4f4 | |||
| 525976a81b | |||
| 64a2126ea4 | |||
| 994c5882ab | |||
| ad64d51e85 | |||
| a184a7518a | |||
| 943fd80920 | |||
| 01bb18b8c4 | |||
| 94baaaa5a5 | |||
| 40b164ce94 | |||
| 1d7c7801e7 | |||
| 0db0a12ef3 | |||
| 8008aba450 | |||
| eaeab27004 | |||
| 111fbf119b | |||
| 300ad88447 | |||
| 92cc0c9c64 | |||
| 18ff803370 | |||
| 819af78e2b | |||
| 6338785ce1 | |||
| 973e151dff | |||
| fae6d83f27 | |||
| ed84fe0b8d | |||
| 1ee603403e | |||
| 7db7b7cc4d | |||
| 68a98cd86c | |||
| e758db5727 | |||
| 4d7d700afa | |||
| f9a5add01d | |||
| 2986b56389 | |||
| 58f79b525d | |||
| 0a1c0dae05 | |||
| e18ef8dab6 | |||
| 3cacc59bec | |||
| 4eea46d399 | |||
| 11e25617bd | |||
| 4817126811 | |||
| 0181361efa | |||
| 8ff8e1d5f7 | |||
| 19d5902a92 | |||
| 71dffb21a9 | |||
| bd283c506d | |||
| ef564e5f1a | |||
| 2543224c7c | |||
| 077eee9310 | |||
| d894eeaa67 | |||
| 452bfb39bf | |||
| 6b6702521f | |||
| c07b8d95d0 | |||
| bf347730b3 | |||
| ececfc3a30 | |||
| b76546de0c | |||
| 424d490a60 | |||
| 127dd85214 | |||
| 10570ac7f8 | |||
| dc5667b0b8 | |||
| ec9cacb610 | |||
| 0027dbc0e5 |
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 2021.12.5
|
||||
current_version = 2022.1.2
|
||||
tag = True
|
||||
commit = True
|
||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-?(?P<release>.*)
|
||||
|
||||
26
.github/workflows/ci-main.yml
vendored
26
.github/workflows/ci-main.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: ~/.cache/pypoetry/virtualenvs
|
||||
key: ${{ runner.os }}-poetry-cache-v3-${{ hashFiles('**/poetry.lock') }}
|
||||
key: ${{ runner.os }}-poetry-cache-v2-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: prepare
|
||||
env:
|
||||
INSTALL: ${{ steps.cache-poetry.outputs.cache-hit }}
|
||||
@ -56,7 +56,7 @@ jobs:
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: ~/.cache/pypoetry/virtualenvs
|
||||
key: ${{ runner.os }}-poetry-cache-v3-${{ hashFiles('**/poetry.lock') }}
|
||||
key: ${{ runner.os }}-poetry-cache-v2-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: prepare
|
||||
env:
|
||||
INSTALL: ${{ steps.cache-poetry.outputs.cache-hit }}
|
||||
@ -79,7 +79,7 @@ jobs:
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: ~/.cache/pypoetry/virtualenvs
|
||||
key: ${{ runner.os }}-poetry-cache-v3-${{ hashFiles('**/poetry.lock') }}
|
||||
key: ${{ runner.os }}-poetry-cache-v2-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: checkout stable
|
||||
run: |
|
||||
# Copy current, latest config to local
|
||||
@ -95,11 +95,7 @@ jobs:
|
||||
INSTALL: ${{ steps.cache-poetry.outputs.cache-hit }}
|
||||
run: |
|
||||
scripts/ci_prepare.sh
|
||||
# Sync anyways since stable will have different dependencies
|
||||
# TODO: Remove after next stable release
|
||||
if [[ -f "Pipfile.lock" ]]; then
|
||||
pipenv install --dev
|
||||
fi
|
||||
# install anyways since stable will have different dependencies
|
||||
poetry install
|
||||
- name: run migrations to stable
|
||||
run: poetry run python -m lifecycle.migrate
|
||||
@ -108,13 +104,7 @@ jobs:
|
||||
set -x
|
||||
git fetch
|
||||
git reset --hard HEAD
|
||||
# TODO: Remove after next stable release
|
||||
rm -f poetry.lock
|
||||
git checkout $GITHUB_SHA
|
||||
# TODO: Remove after next stable release
|
||||
if [[ -f "Pipfile.lock" ]]; then
|
||||
pipenv install --dev
|
||||
fi
|
||||
poetry install
|
||||
- name: prepare
|
||||
env:
|
||||
@ -131,7 +121,7 @@ jobs:
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: ~/.cache/pypoetry/virtualenvs
|
||||
key: ${{ runner.os }}-poetry-cache-v3-${{ hashFiles('**/poetry.lock') }}
|
||||
key: ${{ runner.os }}-poetry-cache-v2-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: prepare
|
||||
env:
|
||||
INSTALL: ${{ steps.cache-poetry.outputs.cache-hit }}
|
||||
@ -158,7 +148,7 @@ jobs:
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: ~/.cache/pypoetry/virtualenvs
|
||||
key: ${{ runner.os }}-poetry-cache-v3-${{ hashFiles('**/poetry.lock') }}
|
||||
key: ${{ runner.os }}-poetry-cache-v2-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: prepare
|
||||
env:
|
||||
INSTALL: ${{ steps.cache-poetry.outputs.cache-hit }}
|
||||
@ -195,7 +185,7 @@ jobs:
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: ~/.cache/pypoetry/virtualenvs
|
||||
key: ${{ runner.os }}-poetry-cache-v3-${{ hashFiles('**/poetry.lock') }}
|
||||
key: ${{ runner.os }}-poetry-cache-v2-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: prepare
|
||||
env:
|
||||
INSTALL: ${{ steps.cache-poetry.outputs.cache-hit }}
|
||||
@ -240,7 +230,7 @@ jobs:
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: ~/.cache/pypoetry/virtualenvs
|
||||
key: ${{ runner.os }}-poetry-cache-v3-${{ hashFiles('**/poetry.lock') }}
|
||||
key: ${{ runner.os }}-poetry-cache-v2-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: prepare
|
||||
env:
|
||||
INSTALL: ${{ steps.cache-poetry.outputs.cache-hit }}
|
||||
|
||||
2
.github/workflows/ci-outpost.yml
vendored
2
.github/workflows/ci-outpost.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
||||
--rm \
|
||||
-v $(pwd):/app \
|
||||
-w /app \
|
||||
golangci/golangci-lint:v1.39.0 \
|
||||
golangci/golangci-lint:v1.43 \
|
||||
golangci-lint run -v --timeout 200s
|
||||
ci-outpost-mark:
|
||||
needs:
|
||||
|
||||
14
.github/workflows/release-publish.yml
vendored
14
.github/workflows/release-publish.yml
vendored
@ -30,14 +30,14 @@ jobs:
|
||||
with:
|
||||
push: ${{ github.event_name == 'release' }}
|
||||
tags: |
|
||||
beryju/authentik:2021.12.5,
|
||||
beryju/authentik:2022.1.2,
|
||||
beryju/authentik:latest,
|
||||
ghcr.io/goauthentik/server:2021.12.5,
|
||||
ghcr.io/goauthentik/server:2022.1.2,
|
||||
ghcr.io/goauthentik/server:latest
|
||||
platforms: linux/amd64,linux/arm64
|
||||
context: .
|
||||
- name: Building Docker Image (stable)
|
||||
if: ${{ github.event_name == 'release' && !contains('2021.12.5', 'rc') }}
|
||||
if: ${{ github.event_name == 'release' && !contains('2022.1.2', 'rc') }}
|
||||
run: |
|
||||
docker pull beryju/authentik:latest
|
||||
docker tag beryju/authentik:latest beryju/authentik:stable
|
||||
@ -78,14 +78,14 @@ jobs:
|
||||
with:
|
||||
push: ${{ github.event_name == 'release' }}
|
||||
tags: |
|
||||
beryju/authentik-${{ matrix.type }}:2021.12.5,
|
||||
beryju/authentik-${{ matrix.type }}:2022.1.2,
|
||||
beryju/authentik-${{ matrix.type }}:latest,
|
||||
ghcr.io/goauthentik/${{ matrix.type }}:2021.12.5,
|
||||
ghcr.io/goauthentik/${{ matrix.type }}:2022.1.2,
|
||||
ghcr.io/goauthentik/${{ matrix.type }}:latest
|
||||
file: ${{ matrix.type }}.Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
- name: Building Docker Image (stable)
|
||||
if: ${{ github.event_name == 'release' && !contains('2021.12.5', 'rc') }}
|
||||
if: ${{ github.event_name == 'release' && !contains('2022.1.2', 'rc') }}
|
||||
run: |
|
||||
docker pull beryju/authentik-${{ matrix.type }}:latest
|
||||
docker tag beryju/authentik-${{ matrix.type }}:latest beryju/authentik-${{ matrix.type }}:stable
|
||||
@ -170,7 +170,7 @@ jobs:
|
||||
SENTRY_PROJECT: authentik
|
||||
SENTRY_URL: https://sentry.beryju.org
|
||||
with:
|
||||
version: authentik@2021.12.5
|
||||
version: authentik@2022.1.2
|
||||
environment: beryjuorg-prod
|
||||
sourcemaps: './web/dist'
|
||||
url_prefix: '~/static/dist'
|
||||
|
||||
2
.github/workflows/translation-compile.yml
vendored
2
.github/workflows/translation-compile.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: ~/.cache/pypoetry/virtualenvs
|
||||
key: ${{ runner.os }}-poetry-cache-v3-${{ hashFiles('**/poetry.lock') }}
|
||||
key: ${{ runner.os }}-poetry-cache-v2-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: prepare
|
||||
env:
|
||||
INSTALL: ${{ steps.cache-poetry.outputs.cache-hit }}
|
||||
|
||||
@ -1 +0,0 @@
|
||||
3.9.7
|
||||
@ -16,7 +16,7 @@ ENV NODE_ENV=production
|
||||
RUN cd /work/web && npm i && npm run build
|
||||
|
||||
# Stage 3: Build go proxy
|
||||
FROM docker.io/golang:1.17.5-bullseye AS builder
|
||||
FROM docker.io/golang:1.17.6-bullseye AS builder
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
@ -32,7 +32,7 @@ COPY ./go.sum /work/go.sum
|
||||
RUN go build -o /work/authentik ./cmd/server/main.go
|
||||
|
||||
# Stage 4: Run
|
||||
FROM docker.io/python:3.10.1-slim-bullseye
|
||||
FROM docker.io/python:3.10.2-slim-bullseye
|
||||
|
||||
LABEL org.opencontainers.image.url https://goauthentik.io
|
||||
LABEL org.opencontainers.image.description goauthentik.io Main server image, see https://goauthentik.io for more info.
|
||||
|
||||
@ -1,3 +1,19 @@
|
||||
"""authentik"""
|
||||
__version__ = "2021.12.5"
|
||||
from os import environ
|
||||
from typing import Optional
|
||||
|
||||
__version__ = "2022.1.2"
|
||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
||||
|
||||
|
||||
def get_build_hash(fallback: Optional[str] = None) -> str:
|
||||
"""Get build hash"""
|
||||
return environ.get(ENV_GIT_HASH_KEY, fallback if fallback else "")
|
||||
|
||||
|
||||
def get_full_version() -> str:
|
||||
"""Get full version, with build hash appended"""
|
||||
version = __version__
|
||||
if (build_hash := get_build_hash()) != "":
|
||||
version += "." + build_hash
|
||||
return version
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
"""authentik administration overview"""
|
||||
from os import environ
|
||||
|
||||
from django.core.cache import cache
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from packaging.version import parse
|
||||
@ -10,7 +8,7 @@ from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from authentik import ENV_GIT_HASH_KEY, __version__
|
||||
from authentik import __version__, get_build_hash
|
||||
from authentik.admin.tasks import VERSION_CACHE_KEY, update_latest_version
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
|
||||
@ -25,7 +23,7 @@ class VersionSerializer(PassiveSerializer):
|
||||
|
||||
def get_build_hash(self, _) -> str:
|
||||
"""Get build hash, if version is not latest or released"""
|
||||
return environ.get(ENV_GIT_HASH_KEY, "")
|
||||
return get_build_hash()
|
||||
|
||||
def get_version_current(self, _) -> str:
|
||||
"""Get current version"""
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
"""authentik admin app config"""
|
||||
from importlib import import_module
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
@ -13,3 +15,4 @@ class AuthentikAdminConfig(AppConfig):
|
||||
from authentik.admin.tasks import clear_update_notifications
|
||||
|
||||
clear_update_notifications.delay()
|
||||
import_module("authentik.admin.signals")
|
||||
|
||||
23
authentik/admin/signals.py
Normal file
23
authentik/admin/signals.py
Normal file
@ -0,0 +1,23 @@
|
||||
"""admin signals"""
|
||||
from django.dispatch import receiver
|
||||
|
||||
from authentik.admin.api.tasks import TaskInfo
|
||||
from authentik.admin.api.workers import GAUGE_WORKERS
|
||||
from authentik.root.celery import CELERY_APP
|
||||
from authentik.root.monitoring import monitoring_set
|
||||
|
||||
|
||||
@receiver(monitoring_set)
|
||||
# pylint: disable=unused-argument
|
||||
def monitoring_set_workers(sender, **kwargs):
|
||||
"""Set worker gauge"""
|
||||
count = len(CELERY_APP.control.ping(timeout=0.5))
|
||||
GAUGE_WORKERS.set(count)
|
||||
|
||||
|
||||
@receiver(monitoring_set)
|
||||
# pylint: disable=unused-argument
|
||||
def monitoring_set_tasks(sender, **kwargs):
|
||||
"""Set task gauges"""
|
||||
for task in TaskInfo.all().values():
|
||||
task.set_prom_metrics()
|
||||
@ -1,6 +1,5 @@
|
||||
"""authentik admin tasks"""
|
||||
import re
|
||||
from os import environ
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.core.validators import URLValidator
|
||||
@ -9,7 +8,7 @@ from prometheus_client import Info
|
||||
from requests import RequestException
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik import ENV_GIT_HASH_KEY, __version__
|
||||
from authentik import __version__, get_build_hash
|
||||
from authentik.events.models import Event, EventAction, Notification
|
||||
from authentik.events.monitored_tasks import (
|
||||
MonitoredTask,
|
||||
@ -36,7 +35,7 @@ def _set_prom_info():
|
||||
{
|
||||
"version": __version__,
|
||||
"latest": cache.get(VERSION_CACHE_KEY, ""),
|
||||
"build_hash": environ.get(ENV_GIT_HASH_KEY, ""),
|
||||
"build_hash": get_build_hash(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ function getCookie(name) {
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
const rapidocEl = document.querySelector('rapi-doc');
|
||||
rapidocEl.addEventListener('before-try', (e) => {
|
||||
e.detail.request.headers.append('X-CSRFToken', getCookie("authentik_csrf"));
|
||||
e.detail.request.headers.append('X-authentik-CSRF', getCookie("authentik_csrf"));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -4,7 +4,5 @@ from django.urls import include, path
|
||||
from authentik.api.v3.urls import urlpatterns as v3_urls
|
||||
|
||||
urlpatterns = [
|
||||
# TODO: Remove in 2022.1
|
||||
path("v2beta/", include(v3_urls)),
|
||||
path("v3/", include(v3_urls)),
|
||||
]
|
||||
|
||||
@ -80,7 +80,7 @@ class ConfigView(APIView):
|
||||
config = ConfigSerializer(
|
||||
{
|
||||
"error_reporting": {
|
||||
"enabled": CONFIG.y("error_reporting.enabled"),
|
||||
"enabled": CONFIG.y("error_reporting.enabled") and not settings.DEBUG,
|
||||
"environment": CONFIG.y("error_reporting.environment"),
|
||||
"send_pii": CONFIG.y("error_reporting.send_pii"),
|
||||
"traces_sample_rate": float(CONFIG.y("error_reporting.sample_rate", 0.4)),
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
"""Tokens API Viewset"""
|
||||
from typing import Any
|
||||
|
||||
from django.http.response import Http404
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||
from guardian.shortcuts import get_anonymous_user
|
||||
@ -114,7 +113,5 @@ class TokenViewSet(UsedByMixin, ModelViewSet):
|
||||
def view_key(self, request: Request, identifier: str) -> Response:
|
||||
"""Return token key and log access"""
|
||||
token: Token = self.get_object()
|
||||
if token.is_expired:
|
||||
raise Http404
|
||||
Event.new(EventAction.SECRET_VIEW, secret=token).from_http(request) # noqa # nosec
|
||||
return Response(TokenViewSerializer({"key": token.key}).data)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
"""authentik core signals"""
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from django.apps import apps
|
||||
from django.contrib.auth.signals import user_logged_in, user_logged_out
|
||||
from django.contrib.sessions.backends.cache import KEY_PREFIX
|
||||
from django.core.cache import cache
|
||||
@ -11,6 +12,8 @@ from django.dispatch import receiver
|
||||
from django.http.request import HttpRequest
|
||||
from prometheus_client import Gauge
|
||||
|
||||
from authentik.root.monitoring import monitoring_set
|
||||
|
||||
# Arguments: user: User, password: str
|
||||
password_changed = Signal()
|
||||
|
||||
@ -20,6 +23,17 @@ if TYPE_CHECKING:
|
||||
from authentik.core.models import AuthenticatedSession, User
|
||||
|
||||
|
||||
@receiver(monitoring_set)
|
||||
# pylint: disable=unused-argument
|
||||
def monitoring_set_models(sender, **kwargs):
|
||||
"""set models gauges"""
|
||||
for model in apps.get_models():
|
||||
GAUGE_MODELS.labels(
|
||||
model_name=model._meta.model_name,
|
||||
app=model._meta.app_label,
|
||||
).set(model.objects.count())
|
||||
|
||||
|
||||
@receiver(post_save)
|
||||
# pylint: disable=unused-argument
|
||||
def post_save_application(sender: type[Model], instance, created: bool, **_):
|
||||
@ -27,11 +41,6 @@ def post_save_application(sender: type[Model], instance, created: bool, **_):
|
||||
from authentik.core.api.applications import user_app_cache_key
|
||||
from authentik.core.models import Application
|
||||
|
||||
GAUGE_MODELS.labels(
|
||||
model_name=sender._meta.model_name,
|
||||
app=sender._meta.app_label,
|
||||
).set(sender.objects.count())
|
||||
|
||||
if sender != Application:
|
||||
return
|
||||
if not created: # pragma: no cover
|
||||
|
||||
@ -17,6 +17,7 @@ from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import ModelSerializer, ValidationError
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.api.decorators import permission_required
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
@ -26,6 +27,8 @@ from authentik.crypto.managed import MANAGED_KEY
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.events.models import Event, EventAction
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
class CertificateKeyPairSerializer(ModelSerializer):
|
||||
"""CertificateKeyPair Serializer"""
|
||||
@ -76,8 +79,11 @@ class CertificateKeyPairSerializer(ModelSerializer):
|
||||
def validate_certificate_data(self, value: str) -> str:
|
||||
"""Verify that input is a valid PEM x509 Certificate"""
|
||||
try:
|
||||
load_pem_x509_certificate(value.encode("utf-8"), default_backend())
|
||||
except ValueError:
|
||||
# Cast to string to fully load and parse certificate
|
||||
# Prevents issues like https://github.com/goauthentik/authentik/issues/2082
|
||||
str(load_pem_x509_certificate(value.encode("utf-8"), default_backend()))
|
||||
except ValueError as exc:
|
||||
LOGGER.warning("Failed to load certificate", exc=exc)
|
||||
raise ValidationError("Unable to load certificate.")
|
||||
return value
|
||||
|
||||
@ -86,12 +92,17 @@ class CertificateKeyPairSerializer(ModelSerializer):
|
||||
# Since this field is optional, data can be empty.
|
||||
if value != "":
|
||||
try:
|
||||
load_pem_private_key(
|
||||
str.encode("\n".join([x.strip() for x in value.split("\n")])),
|
||||
password=None,
|
||||
backend=default_backend(),
|
||||
# Cast to string to fully load and parse certificate
|
||||
# Prevents issues like https://github.com/goauthentik/authentik/issues/2082
|
||||
str(
|
||||
load_pem_private_key(
|
||||
str.encode("\n".join([x.strip() for x in value.split("\n")])),
|
||||
password=None,
|
||||
backend=default_backend(),
|
||||
)
|
||||
)
|
||||
except (ValueError, TypeError):
|
||||
except (ValueError, TypeError) as exc:
|
||||
LOGGER.warning("Failed to load private key", exc=exc)
|
||||
raise ValidationError("Unable to load private key (possibly encrypted?).")
|
||||
return value
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ from typing import Any, Optional
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.http import HttpRequest
|
||||
from prometheus_client import Histogram
|
||||
from prometheus_client import Gauge, Histogram
|
||||
from sentry_sdk.hub import Hub
|
||||
from sentry_sdk.tracing import Span
|
||||
from structlog.stdlib import BoundLogger, get_logger
|
||||
@ -16,7 +16,6 @@ from authentik.flows.markers import ReevaluateMarker, StageMarker
|
||||
from authentik.flows.models import Flow, FlowStageBinding, Stage
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.policies.engine import PolicyEngine
|
||||
from authentik.root.monitoring import UpdatingGauge
|
||||
|
||||
LOGGER = get_logger()
|
||||
PLAN_CONTEXT_PENDING_USER = "pending_user"
|
||||
@ -27,10 +26,9 @@ PLAN_CONTEXT_SOURCE = "source"
|
||||
# Is set by the Flow Planner when a FlowToken was used, and the currently active flow plan
|
||||
# was restored.
|
||||
PLAN_CONTEXT_IS_RESTORED = "is_restored"
|
||||
GAUGE_FLOWS_CACHED = UpdatingGauge(
|
||||
GAUGE_FLOWS_CACHED = Gauge(
|
||||
"authentik_flows_cached",
|
||||
"Cached flows",
|
||||
update_func=lambda: len(cache.keys("flow_*") or []),
|
||||
)
|
||||
HIST_FLOWS_PLAN_TIME = Histogram(
|
||||
"authentik_flows_plan_time",
|
||||
@ -171,7 +169,6 @@ class FlowPlanner:
|
||||
)
|
||||
plan = self._build_plan(user, request, default_context)
|
||||
cache.set(cache_key(self.flow, user), plan, CACHE_TIMEOUT)
|
||||
GAUGE_FLOWS_CACHED.update()
|
||||
if not plan.bindings and not self.allow_empty_flows:
|
||||
raise EmptyFlowException()
|
||||
return plan
|
||||
|
||||
@ -4,6 +4,9 @@ from django.db.models.signals import post_save, pre_delete
|
||||
from django.dispatch import receiver
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.flows.planner import GAUGE_FLOWS_CACHED
|
||||
from authentik.root.monitoring import monitoring_set
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
@ -14,6 +17,13 @@ def delete_cache_prefix(prefix: str) -> int:
|
||||
return len(keys)
|
||||
|
||||
|
||||
@receiver(monitoring_set)
|
||||
# pylint: disable=unused-argument
|
||||
def monitoring_set_flows(sender, **kwargs):
|
||||
"""set flow gauges"""
|
||||
GAUGE_FLOWS_CACHED.set(len(cache.keys("flow_*") or []))
|
||||
|
||||
|
||||
@receiver(post_save)
|
||||
@receiver(pre_delete)
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
@ -118,9 +118,12 @@ class ChallengeStageView(StageView):
|
||||
"""Allow usage of placeholder in flow title."""
|
||||
if not self.executor.plan:
|
||||
return self.executor.flow.title
|
||||
return self.executor.flow.title % {
|
||||
"app": self.executor.plan.context.get(PLAN_CONTEXT_APPLICATION, "")
|
||||
}
|
||||
try:
|
||||
return self.executor.flow.title % {
|
||||
"app": self.executor.plan.context.get(PLAN_CONTEXT_APPLICATION, "")
|
||||
}
|
||||
except ValueError:
|
||||
return self.executor.flow.title
|
||||
|
||||
def _get_challenge(self, *args, **kwargs) -> Challenge:
|
||||
with Hub.current.start_span(
|
||||
|
||||
@ -6,7 +6,7 @@ postgresql:
|
||||
port: 5432
|
||||
password: 'env://POSTGRES_PASSWORD'
|
||||
backup:
|
||||
enabled: true
|
||||
enabled: false
|
||||
s3_backup:
|
||||
access_key: ""
|
||||
secret_key: ""
|
||||
|
||||
@ -111,6 +111,7 @@ def before_send(event: dict, hint: dict) -> Optional[dict]:
|
||||
"django_redis.cache",
|
||||
"celery.backends.redis",
|
||||
"celery.worker",
|
||||
"paramiko.transport",
|
||||
]:
|
||||
return None
|
||||
LOGGER.debug("sending event to sentry", exc=exc_value, source_logger=event.get("logger", None))
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
"""http helpers"""
|
||||
from os import environ
|
||||
from typing import Any, Optional
|
||||
|
||||
from django.http import HttpRequest
|
||||
@ -7,7 +6,7 @@ from requests.sessions import Session
|
||||
from sentry_sdk.hub import Hub
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik import ENV_GIT_HASH_KEY, __version__
|
||||
from authentik import get_full_version
|
||||
|
||||
OUTPOST_REMOTE_IP_HEADER = "HTTP_X_AUTHENTIK_REMOTE_IP"
|
||||
OUTPOST_TOKEN_HEADER = "HTTP_X_AUTHENTIK_OUTPOST_TOKEN" # nosec
|
||||
@ -75,8 +74,7 @@ def get_client_ip(request: Optional[HttpRequest]) -> str:
|
||||
|
||||
def authentik_user_agent() -> str:
|
||||
"""Get a common user agent"""
|
||||
build = environ.get(ENV_GIT_HASH_KEY, "tagged")
|
||||
return f"authentik@{__version__} (build={build})"
|
||||
return f"authentik@{get_full_version()}"
|
||||
|
||||
|
||||
def get_http_session() -> Session:
|
||||
|
||||
@ -58,4 +58,6 @@ def get_env() -> str:
|
||||
return "compose"
|
||||
if CONFIG.y_bool("debug"):
|
||||
return "dev"
|
||||
if "AK_APPLIANCE" in os.environ:
|
||||
return os.environ["AK_APPLIANCE"]
|
||||
return "custom"
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
"""Outpost API Views"""
|
||||
from os import environ
|
||||
|
||||
from dacite.core import from_dict
|
||||
from dacite.exceptions import DaciteError
|
||||
from django_filters.filters import ModelMultipleChoiceFilter
|
||||
@ -14,7 +12,7 @@ from rest_framework.response import Response
|
||||
from rest_framework.serializers import JSONField, ModelSerializer, ValidationError
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik import ENV_GIT_HASH_KEY
|
||||
from authentik import get_build_hash
|
||||
from authentik.core.api.providers import ProviderSerializer
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.api.utils import PassiveSerializer, is_dict
|
||||
@ -154,7 +152,7 @@ class OutpostViewSet(UsedByMixin, ModelViewSet):
|
||||
"version_should": state.version_should,
|
||||
"version_outdated": state.version_outdated,
|
||||
"build_hash": state.build_hash,
|
||||
"build_hash_should": environ.get(ENV_GIT_HASH_KEY, ""),
|
||||
"build_hash_should": get_build_hash(),
|
||||
}
|
||||
)
|
||||
return Response(OutpostHealthSerializer(states, many=True).data)
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
"""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 ENV_GIT_HASH_KEY, __version__
|
||||
from authentik import __version__, get_build_hash
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.sentry import SentryIgnoredException
|
||||
from authentik.outposts.models import (
|
||||
@ -102,5 +101,5 @@ class BaseController:
|
||||
return image_name_template % {
|
||||
"type": self.outpost.type,
|
||||
"version": __version__,
|
||||
"build_hash": environ.get(ENV_GIT_HASH_KEY, ""),
|
||||
"build_hash": get_build_hash(),
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ from docker import DockerClient as UpstreamDockerClient
|
||||
from docker.errors import DockerException, NotFound
|
||||
from docker.models.containers import Container
|
||||
from docker.utils.utils import kwargs_from_env
|
||||
from paramiko.ssh_exception import SSHException
|
||||
from structlog.stdlib import get_logger
|
||||
from yaml import safe_dump
|
||||
|
||||
@ -49,10 +50,13 @@ class DockerClient(UpstreamDockerClient, BaseClient):
|
||||
authentication_kp=connection.tls_authentication,
|
||||
)
|
||||
tls_config = self.tls.write()
|
||||
super().__init__(
|
||||
base_url=connection.url,
|
||||
tls=tls_config,
|
||||
)
|
||||
try:
|
||||
super().__init__(
|
||||
base_url=connection.url,
|
||||
tls=tls_config,
|
||||
)
|
||||
except SSHException as exc:
|
||||
raise ServiceConnectionInvalid from exc
|
||||
self.logger = get_logger()
|
||||
# Ensure the client actually works
|
||||
self.containers.list()
|
||||
@ -102,9 +106,12 @@ class DockerController(BaseController):
|
||||
).lower()
|
||||
|
||||
def _get_labels(self) -> dict[str, str]:
|
||||
return {
|
||||
labels = {
|
||||
"io.goauthentik.outpost-uuid": self.outpost.pk.hex,
|
||||
}
|
||||
if self.outpost.config.docker_labels:
|
||||
labels.update(self.outpost.config.docker_labels)
|
||||
return labels
|
||||
|
||||
def _get_env(self) -> dict[str, str]:
|
||||
return {
|
||||
|
||||
@ -18,6 +18,7 @@ from kubernetes.client import (
|
||||
V1SecretKeySelector,
|
||||
)
|
||||
|
||||
from authentik import __version__, get_full_version
|
||||
from authentik.outposts.controllers.base import FIELD_MANAGER
|
||||
from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler
|
||||
from authentik.outposts.controllers.k8s.triggers import NeedsUpdate
|
||||
@ -52,15 +53,18 @@ class DeploymentReconciler(KubernetesObjectReconciler[V1Deployment]):
|
||||
raise NeedsUpdate()
|
||||
super().reconcile(current, reference)
|
||||
|
||||
def get_pod_meta(self) -> dict[str, str]:
|
||||
def get_pod_meta(self, **kwargs) -> dict[str, str]:
|
||||
"""Get common object metadata"""
|
||||
return {
|
||||
"app.kubernetes.io/name": "authentik-outpost",
|
||||
"app.kubernetes.io/managed-by": "goauthentik.io",
|
||||
"goauthentik.io/outpost-uuid": self.controller.outpost.uuid.hex,
|
||||
"goauthentik.io/outpost-name": slugify(self.controller.outpost.name),
|
||||
"goauthentik.io/outpost-type": str(self.controller.outpost.type),
|
||||
}
|
||||
kwargs.update(
|
||||
{
|
||||
"app.kubernetes.io/name": f"authentik-outpost-{self.outpost.type}",
|
||||
"app.kubernetes.io/managed-by": "goauthentik.io",
|
||||
"goauthentik.io/outpost-uuid": self.controller.outpost.uuid.hex,
|
||||
"goauthentik.io/outpost-name": slugify(self.controller.outpost.name),
|
||||
"goauthentik.io/outpost-type": str(self.controller.outpost.type),
|
||||
}
|
||||
)
|
||||
return kwargs
|
||||
|
||||
def get_reference_object(self) -> V1Deployment:
|
||||
"""Get deployment object for outpost"""
|
||||
@ -77,13 +81,24 @@ class DeploymentReconciler(KubernetesObjectReconciler[V1Deployment]):
|
||||
meta = self.get_object_meta(name=self.name)
|
||||
image_name = self.controller.get_container_image()
|
||||
image_pull_secrets = self.outpost.config.kubernetes_image_pull_secrets
|
||||
version = get_full_version()
|
||||
return V1Deployment(
|
||||
metadata=meta,
|
||||
spec=V1DeploymentSpec(
|
||||
replicas=self.outpost.config.kubernetes_replicas,
|
||||
selector=V1LabelSelector(match_labels=self.get_pod_meta()),
|
||||
template=V1PodTemplateSpec(
|
||||
metadata=V1ObjectMeta(labels=self.get_pod_meta()),
|
||||
metadata=V1ObjectMeta(
|
||||
labels=self.get_pod_meta(
|
||||
**{
|
||||
# Support istio-specific labels, but also use the standard k8s
|
||||
# recommendations
|
||||
"app.kubernetes.io/version": version,
|
||||
"app": "authentik-outpost",
|
||||
"version": version,
|
||||
}
|
||||
)
|
||||
),
|
||||
spec=V1PodSpec(
|
||||
image_pull_secrets=[
|
||||
V1ObjectReference(name=secret) for secret in image_pull_secrets
|
||||
|
||||
@ -6,6 +6,7 @@ from kubernetes.client import CoreV1Api, V1Service, V1ServicePort, V1ServiceSpec
|
||||
from authentik.outposts.controllers.base import FIELD_MANAGER
|
||||
from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler
|
||||
from authentik.outposts.controllers.k8s.deployment import DeploymentReconciler
|
||||
from authentik.outposts.controllers.k8s.triggers import NeedsUpdate
|
||||
from authentik.outposts.controllers.k8s.utils import compare_ports
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -25,6 +26,8 @@ class ServiceReconciler(KubernetesObjectReconciler[V1Service]):
|
||||
# after an authentik update. However the ports might have also changed during
|
||||
# the update, so this causes the service to be re-created with higher
|
||||
# priority than being updated.
|
||||
if current.spec.selector != reference.spec.selector:
|
||||
raise NeedsUpdate()
|
||||
super().reconcile(current, reference)
|
||||
|
||||
def get_reference_object(self) -> V1Service:
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
"""Outpost models"""
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from datetime import datetime
|
||||
from os import environ
|
||||
from typing import Iterable, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
@ -17,7 +16,7 @@ from model_utils.managers import InheritanceManager
|
||||
from packaging.version import LegacyVersion, Version, parse
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik import ENV_GIT_HASH_KEY, __version__
|
||||
from authentik import __version__, get_build_hash
|
||||
from authentik.core.models import (
|
||||
USER_ATTRIBUTE_CAN_OVERRIDE_IP,
|
||||
USER_ATTRIBUTE_SA,
|
||||
@ -61,6 +60,7 @@ class OutpostConfig:
|
||||
|
||||
docker_network: Optional[str] = field(default=None)
|
||||
docker_map_ports: bool = field(default=True)
|
||||
docker_labels: Optional[dict[str, str]] = field(default=None)
|
||||
|
||||
container_image: Optional[str] = field(default=None)
|
||||
|
||||
@ -414,7 +414,7 @@ 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, ""):
|
||||
if self.build_hash != get_build_hash():
|
||||
return False
|
||||
return parse(self.version) < OUR_VERSION
|
||||
|
||||
|
||||
@ -77,8 +77,12 @@ def outpost_service_connection_state(connection_pk: Any):
|
||||
cls = DockerClient
|
||||
if isinstance(connection, KubernetesServiceConnection):
|
||||
cls = KubernetesClient
|
||||
with cls(connection) as client:
|
||||
state = client.fetch_state()
|
||||
try:
|
||||
with cls(connection) as client:
|
||||
state = client.fetch_state()
|
||||
except ServiceConnectionInvalid as exc:
|
||||
LOGGER.warning("Failed to get client status", exc=exc)
|
||||
return
|
||||
cache.set(connection.state_key, state, timeout=None)
|
||||
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ from typing import Iterator, Optional
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.http import HttpRequest
|
||||
from prometheus_client import Histogram
|
||||
from prometheus_client import Gauge, Histogram
|
||||
from sentry_sdk.hub import Hub
|
||||
from sentry_sdk.tracing import Span
|
||||
from structlog.stdlib import BoundLogger, get_logger
|
||||
@ -14,13 +14,11 @@ from authentik.core.models import User
|
||||
from authentik.policies.models import Policy, PolicyBinding, PolicyBindingModel, PolicyEngineMode
|
||||
from authentik.policies.process import PolicyProcess, cache_key
|
||||
from authentik.policies.types import PolicyRequest, PolicyResult
|
||||
from authentik.root.monitoring import UpdatingGauge
|
||||
|
||||
CURRENT_PROCESS = current_process()
|
||||
GAUGE_POLICIES_CACHED = UpdatingGauge(
|
||||
GAUGE_POLICIES_CACHED = Gauge(
|
||||
"authentik_policies_cached",
|
||||
"Cached Policies",
|
||||
update_func=lambda: len(cache.keys("policy_*") or []),
|
||||
)
|
||||
HIST_POLICIES_BUILD_TIME = Histogram(
|
||||
"authentik_policies_build_time",
|
||||
|
||||
@ -45,7 +45,7 @@ class HaveIBeenPwendPolicy(Policy):
|
||||
fields=request.context.keys(),
|
||||
)
|
||||
return PolicyResult(False, _("Password not set in context"))
|
||||
password = request.context[self.password_field]
|
||||
password = str(request.context[self.password_field])
|
||||
|
||||
pw_hash = sha1(password.encode("utf-8")).hexdigest() # nosec
|
||||
url = f"https://api.pwnedpasswords.com/range/{pw_hash[:5]}"
|
||||
|
||||
@ -5,10 +5,19 @@ from django.dispatch import receiver
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.core.api.applications import user_app_cache_key
|
||||
from authentik.policies.engine import GAUGE_POLICIES_CACHED
|
||||
from authentik.root.monitoring import monitoring_set
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
@receiver(monitoring_set)
|
||||
# pylint: disable=unused-argument
|
||||
def monitoring_set_policies(sender, **kwargs):
|
||||
"""set policy gauges"""
|
||||
GAUGE_POLICIES_CACHED.set(len(cache.keys("policy_*") or []))
|
||||
|
||||
|
||||
@receiver(post_save)
|
||||
# pylint: disable=unused-argument
|
||||
def invalidate_policy_cache(sender, instance, **_):
|
||||
|
||||
@ -99,7 +99,7 @@ class OAuthAuthorizationParams:
|
||||
# and POST request.
|
||||
query_dict = request.POST if request.method == "POST" else request.GET
|
||||
state = query_dict.get("state")
|
||||
redirect_uri = query_dict.get("redirect_uri", "")
|
||||
redirect_uri = query_dict.get("redirect_uri", "").lower()
|
||||
|
||||
response_type = query_dict.get("response_type", "")
|
||||
grant_type = None
|
||||
@ -156,13 +156,20 @@ class OAuthAuthorizationParams:
|
||||
if not self.redirect_uri:
|
||||
LOGGER.warning("Missing redirect uri.")
|
||||
raise RedirectUriError("", allowed_redirect_urls)
|
||||
if len(allowed_redirect_urls) < 1:
|
||||
|
||||
if self.provider.redirect_uris == "":
|
||||
LOGGER.info("Setting redirect for blank redirect_uris", redirect=self.redirect_uri)
|
||||
self.provider.redirect_uris = self.redirect_uri
|
||||
self.provider.save()
|
||||
allowed_redirect_urls = self.provider.redirect_uris.split()
|
||||
|
||||
if self.provider.redirect_uris == "*":
|
||||
LOGGER.warning(
|
||||
"Provider has no allowed redirect_uri set, allowing all.",
|
||||
allow=self.redirect_uri.lower(),
|
||||
"Provider has wildcard allowed redirect_uri set, allowing all.",
|
||||
allow=self.redirect_uri,
|
||||
)
|
||||
return
|
||||
if self.redirect_uri.lower() not in [x.lower() for x in allowed_redirect_urls]:
|
||||
if self.redirect_uri not in [x.lower() for x in allowed_redirect_urls]:
|
||||
LOGGER.warning(
|
||||
"Invalid redirect uri",
|
||||
redirect_uri=self.redirect_uri,
|
||||
|
||||
@ -66,7 +66,7 @@ class TokenParams:
|
||||
provider=provider,
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
redirect_uri=request.POST.get("redirect_uri", ""),
|
||||
redirect_uri=request.POST.get("redirect_uri", "").lower(),
|
||||
grant_type=request.POST.get("grant_type", ""),
|
||||
state=request.POST.get("state", ""),
|
||||
scope=request.POST.get("scope", "").split(),
|
||||
@ -123,21 +123,23 @@ class TokenParams:
|
||||
LOGGER.warning("Invalid grant type", grant_type=self.grant_type)
|
||||
raise TokenError("unsupported_grant_type")
|
||||
|
||||
def __post_init_code(self, raw_code):
|
||||
def __post_init_code(self, raw_code: str):
|
||||
if not raw_code:
|
||||
LOGGER.warning("Missing authorization code")
|
||||
raise TokenError("invalid_grant")
|
||||
|
||||
allowed_redirect_urls = self.provider.redirect_uris.split()
|
||||
if len(allowed_redirect_urls) < 1:
|
||||
if self.provider.redirect_uris == "*":
|
||||
LOGGER.warning(
|
||||
"Provider has no allowed redirect_uri set, allowing all.",
|
||||
allow=self.redirect_uri.lower(),
|
||||
"Provider has wildcard allowed redirect_uri set, allowing all.",
|
||||
redirect=self.redirect_uri,
|
||||
)
|
||||
elif self.redirect_uri.lower() not in [x.lower() for x in allowed_redirect_urls]:
|
||||
# At this point, no provider should have a blank redirect_uri, in case they do
|
||||
# this will check an empty array and raise an error
|
||||
elif self.redirect_uri not in [x.lower() for x in allowed_redirect_urls]:
|
||||
LOGGER.warning(
|
||||
"Invalid redirect uri",
|
||||
uri=self.redirect_uri,
|
||||
redirect=self.redirect_uri,
|
||||
expected=self.provider.redirect_uris.split(),
|
||||
)
|
||||
raise TokenError("invalid_client")
|
||||
|
||||
@ -26,7 +26,9 @@ class ProxyDockerController(DockerController):
|
||||
traefik_name = f"ak-outpost-{self.outpost.pk.hex}"
|
||||
labels = super()._get_labels()
|
||||
labels["traefik.enable"] = "true"
|
||||
labels[f"traefik.http.routers.{traefik_name}-router.rule"] = f"Host({','.join(hosts)})"
|
||||
labels[
|
||||
f"traefik.http.routers.{traefik_name}-router.rule"
|
||||
] = f"Host({','.join(hosts)}) && PathPrefix('/akprox')"
|
||||
labels[f"traefik.http.routers.{traefik_name}-router.tls"] = "true"
|
||||
labels[f"traefik.http.routers.{traefik_name}-router.service"] = f"{traefik_name}-service"
|
||||
labels[
|
||||
|
||||
@ -121,13 +121,6 @@ class TraefikMiddlewareReconciler(KubernetesObjectReconciler[TraefikMiddleware])
|
||||
forwardAuth=TraefikMiddlewareSpecForwardAuth(
|
||||
address=f"http://{self.name}.{self.namespace}:9000/akprox/auth/traefik",
|
||||
authResponseHeaders=[
|
||||
# Legacy headers, remove after 2022.1
|
||||
"X-Auth-Username",
|
||||
"X-Auth-Groups",
|
||||
"X-Forwarded-Email",
|
||||
"X-Forwarded-Preferred-Username",
|
||||
"X-Forwarded-User",
|
||||
# New headers, unique prefix
|
||||
"X-authentik-username",
|
||||
"X-authentik-groups",
|
||||
"X-authentik-email",
|
||||
|
||||
@ -1,37 +1,17 @@
|
||||
"""Metrics view"""
|
||||
from base64 import b64encode
|
||||
from typing import Callable
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import connections
|
||||
from django.db.utils import OperationalError
|
||||
from django.dispatch import Signal
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.views import View
|
||||
from django_prometheus.exports import ExportToDjangoView
|
||||
from django_redis import get_redis_connection
|
||||
from prometheus_client import Gauge
|
||||
from redis.exceptions import RedisError
|
||||
|
||||
from authentik.admin.api.workers import GAUGE_WORKERS
|
||||
from authentik.events.monitored_tasks import TaskInfo
|
||||
from authentik.root.celery import CELERY_APP
|
||||
|
||||
|
||||
class UpdatingGauge(Gauge):
|
||||
"""Gauge which fetches its own value from an update function.
|
||||
|
||||
Update function is called on instantiate"""
|
||||
|
||||
def __init__(self, *args, update_func: Callable, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._update_func = update_func
|
||||
self.update()
|
||||
|
||||
def update(self):
|
||||
"""Set value from update function"""
|
||||
val = self._update_func()
|
||||
if val:
|
||||
self.set(val)
|
||||
monitoring_set = Signal()
|
||||
|
||||
|
||||
class MetricsView(View):
|
||||
@ -49,11 +29,7 @@ class MetricsView(View):
|
||||
response["WWW-Authenticate"] = 'Basic realm="authentik-monitoring"'
|
||||
return response
|
||||
|
||||
count = len(CELERY_APP.control.ping(timeout=0.5))
|
||||
GAUGE_WORKERS.set(count)
|
||||
|
||||
for task in TaskInfo.all().values():
|
||||
task.set_prom_metrics()
|
||||
monitoring_set.send_robust(self)
|
||||
|
||||
return ExportToDjangoView(request)
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ from sentry_sdk.integrations.django import DjangoIntegration
|
||||
from sentry_sdk.integrations.redis import RedisIntegration
|
||||
from sentry_sdk.integrations.threading import ThreadingIntegration
|
||||
|
||||
from authentik import ENV_GIT_HASH_KEY, __version__
|
||||
from authentik import ENV_GIT_HASH_KEY, __version__, get_build_hash, get_full_version
|
||||
from authentik.core.middleware import structlog_add_request_id
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.logging import add_process_id
|
||||
@ -75,6 +75,7 @@ AUTH_USER_MODEL = "authentik_core.User"
|
||||
|
||||
_cookie_suffix = "_debug" if DEBUG else ""
|
||||
CSRF_COOKIE_NAME = "authentik_csrf"
|
||||
CSRF_HEADER_NAME = "HTTP_X_AUTHENTIK_CSRF"
|
||||
LANGUAGE_COOKIE_NAME = f"authentik_language{_cookie_suffix}"
|
||||
SESSION_COOKIE_NAME = f"authentik_session{_cookie_suffix}"
|
||||
SESSION_COOKIE_DOMAIN = CONFIG.y("cookie_domain", None)
|
||||
@ -164,9 +165,6 @@ SPECTACULAR_SETTINGS = {
|
||||
{
|
||||
"url": "/api/v3/",
|
||||
},
|
||||
{
|
||||
"url": "/api/v2beta/",
|
||||
},
|
||||
],
|
||||
"CONTACT": {
|
||||
"email": "hello@beryju.org",
|
||||
@ -357,7 +355,7 @@ CELERY_BEAT_SCHEDULE = {
|
||||
},
|
||||
"db_backup": {
|
||||
"task": "authentik.core.tasks.backup_database",
|
||||
"schedule": crontab(hour="*/24"),
|
||||
"schedule": crontab(hour="*/24", minute=0),
|
||||
"options": {"queue": "authentik_scheduled"},
|
||||
},
|
||||
}
|
||||
@ -378,7 +376,7 @@ DBBACKUP_CONNECTOR_MAPPING = {
|
||||
"django_prometheus.db.backends.postgresql": "dbbackup.db.postgresql.PgDumpConnector",
|
||||
}
|
||||
DBBACKUP_TMP_DIR = gettempdir() if DEBUG else "/tmp" # nosec
|
||||
DBBACKUP_CLEANUP_KEEP = 30
|
||||
DBBACKUP_CLEANUP_KEEP = 10
|
||||
if CONFIG.y("postgresql.s3_backup.bucket", "") != "":
|
||||
DBBACKUP_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
|
||||
DBBACKUP_STORAGE_OPTIONS = {
|
||||
@ -398,10 +396,6 @@ if CONFIG.y("postgresql.s3_backup.bucket", "") != "":
|
||||
|
||||
# Sentry integration
|
||||
SENTRY_DSN = "https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8"
|
||||
# Default to empty string as that is what docker has
|
||||
build_hash = os.environ.get(ENV_GIT_HASH_KEY, "")
|
||||
if build_hash == "":
|
||||
build_hash = "tagged"
|
||||
|
||||
env = get_env()
|
||||
_ERROR_REPORTING = CONFIG.y_bool("error_reporting.enabled", False)
|
||||
@ -422,10 +416,10 @@ if _ERROR_REPORTING:
|
||||
environment=CONFIG.y("error_reporting.environment", "customer"),
|
||||
send_default_pii=CONFIG.y_bool("error_reporting.send_pii", False),
|
||||
)
|
||||
set_tag("authentik.build_hash", build_hash)
|
||||
set_tag("authentik.build_hash", get_build_hash("tagged"))
|
||||
set_tag("authentik.env", env)
|
||||
set_tag("authentik.component", "backend")
|
||||
set_tag("authentik.uuid", sha512(SECRET_KEY.encode("ascii")).hexdigest()[:16])
|
||||
set_tag("authentik.uuid", sha512(str(SECRET_KEY).encode("ascii")).hexdigest()[:16])
|
||||
j_print(
|
||||
"Error reporting is enabled",
|
||||
env=CONFIG.y("error_reporting.environment", "customer"),
|
||||
@ -439,11 +433,13 @@ if not CONFIG.y_bool("disable_startup_analytics", False):
|
||||
json={
|
||||
"domain": "authentik",
|
||||
"name": "pageview",
|
||||
"referrer": f"{__version__} ({build_hash})",
|
||||
"url": f"http://localhost/{env}?utm_source={__version__}&utm_medium={env}",
|
||||
"referrer": get_full_version(),
|
||||
"url": (
|
||||
f"http://localhost/{env}?utm_source={get_full_version()}&utm_medium={env}"
|
||||
),
|
||||
},
|
||||
headers={
|
||||
"User-Agent": sha512(SECRET_KEY.encode("ascii")).hexdigest()[:16],
|
||||
"User-Agent": sha512(str(SECRET_KEY).encode("ascii")).hexdigest()[:16],
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
timeout=5,
|
||||
|
||||
@ -18,7 +18,12 @@ class AuthenticateWebAuthnStageSerializer(StageSerializer):
|
||||
class Meta:
|
||||
|
||||
model = AuthenticateWebAuthnStage
|
||||
fields = StageSerializer.Meta.fields + ["configure_flow", "user_verification"]
|
||||
fields = StageSerializer.Meta.fields + [
|
||||
"configure_flow",
|
||||
"user_verification",
|
||||
"authenticator_attachment",
|
||||
"resident_key_requirement",
|
||||
]
|
||||
|
||||
|
||||
class AuthenticateWebAuthnStageViewSet(UsedByMixin, ModelViewSet):
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
# Generated by Django 4.0.1 on 2022-01-12 21:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
(
|
||||
"authentik_stages_authenticator_webauthn",
|
||||
"0005_authenticatewebauthnstage_user_verification",
|
||||
),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="authenticatewebauthnstage",
|
||||
name="authenticator_attachment",
|
||||
field=models.TextField(
|
||||
choices=[("platform", "Platform"), ("cross-platform", "Cross Platform")],
|
||||
default=None,
|
||||
null=True,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="authenticatewebauthnstage",
|
||||
name="resident_key_requirement",
|
||||
field=models.TextField(
|
||||
choices=[
|
||||
("discouraged", "Discouraged"),
|
||||
("preferred", "Preferred"),
|
||||
("required", "Required"),
|
||||
],
|
||||
default="preferred",
|
||||
),
|
||||
),
|
||||
]
|
||||
@ -31,6 +31,40 @@ class UserVerification(models.TextChoices):
|
||||
DISCOURAGED = "discouraged"
|
||||
|
||||
|
||||
class ResidentKeyRequirement(models.TextChoices):
|
||||
"""The Relying Party's preference for the authenticator to create a dedicated "client-side"
|
||||
credential for it. Requiring an authenticator to store a dedicated credential should not be
|
||||
done lightly due to the limited storage capacity of some types of authenticators.
|
||||
|
||||
Members:
|
||||
`DISCOURAGED`: The authenticator should not create a dedicated credential
|
||||
`PREFERRED`: The authenticator can create and store a dedicated credential, but if it
|
||||
doesn't that's alright too
|
||||
`REQUIRED`: The authenticator MUST create a dedicated credential. If it cannot, the RP
|
||||
is prepared for an error to occur.
|
||||
|
||||
https://www.w3.org/TR/webauthn-2/#enum-residentKeyRequirement
|
||||
"""
|
||||
|
||||
DISCOURAGED = "discouraged"
|
||||
PREFERRED = "preferred"
|
||||
REQUIRED = "required"
|
||||
|
||||
|
||||
class AuthenticatorAttachment(models.TextChoices):
|
||||
"""How an authenticator is connected to the client/browser.
|
||||
|
||||
Members:
|
||||
`PLATFORM`: A non-removable authenticator, like TouchID or Windows Hello
|
||||
`CROSS_PLATFORM`: A "roaming" authenticator, like a YubiKey
|
||||
|
||||
https://www.w3.org/TR/webauthn-2/#enumdef-authenticatorattachment
|
||||
"""
|
||||
|
||||
PLATFORM = "platform"
|
||||
CROSS_PLATFORM = "cross-platform"
|
||||
|
||||
|
||||
class AuthenticateWebAuthnStage(ConfigurableStage, Stage):
|
||||
"""WebAuthn stage"""
|
||||
|
||||
@ -38,6 +72,13 @@ class AuthenticateWebAuthnStage(ConfigurableStage, Stage):
|
||||
choices=UserVerification.choices,
|
||||
default=UserVerification.PREFERRED,
|
||||
)
|
||||
resident_key_requirement = models.TextField(
|
||||
choices=ResidentKeyRequirement.choices,
|
||||
default=ResidentKeyRequirement.PREFERRED,
|
||||
)
|
||||
authenticator_attachment = models.TextField(
|
||||
choices=AuthenticatorAttachment.choices, default=None, null=True
|
||||
)
|
||||
|
||||
@property
|
||||
def serializer(self) -> BaseSerializer:
|
||||
|
||||
@ -13,7 +13,6 @@ from webauthn.helpers.structs import (
|
||||
AuthenticatorSelectionCriteria,
|
||||
PublicKeyCredentialCreationOptions,
|
||||
RegistrationCredential,
|
||||
ResidentKeyRequirement,
|
||||
)
|
||||
from webauthn.registration.verify_registration_response import VerifiedRegistration
|
||||
|
||||
@ -85,6 +84,12 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
|
||||
stage: AuthenticateWebAuthnStage = self.executor.current_stage
|
||||
user = self.get_pending_user()
|
||||
|
||||
# library accepts none so we store null in the database, but if there is a value
|
||||
# set, cast it to string to ensure it's not a django class
|
||||
authenticator_attachment = stage.authenticator_attachment
|
||||
if authenticator_attachment:
|
||||
authenticator_attachment = str(authenticator_attachment)
|
||||
|
||||
registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(
|
||||
rp_id=get_rp_id(self.request),
|
||||
rp_name=self.request.tenant.branding_title,
|
||||
@ -92,8 +97,9 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
|
||||
user_name=user.username,
|
||||
user_display_name=user.name,
|
||||
authenticator_selection=AuthenticatorSelectionCriteria(
|
||||
resident_key=ResidentKeyRequirement.PREFERRED,
|
||||
resident_key=str(stage.resident_key_requirement),
|
||||
user_verification=str(stage.user_verification),
|
||||
authenticator_attachment=authenticator_attachment,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ services:
|
||||
image: redis:alpine
|
||||
restart: unless-stopped
|
||||
server:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.12.5}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.1.2}
|
||||
restart: unless-stopped
|
||||
command: server
|
||||
environment:
|
||||
@ -35,10 +35,10 @@ services:
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "0.0.0.0:9000:9000"
|
||||
- "0.0.0.0:9443:9443"
|
||||
- "0.0.0.0:${AUTHENTIK_PORT_HTTP:-9000}:9000"
|
||||
- "0.0.0.0:${AUTHENTIK_PORT_HTTPS:-9443}:9443"
|
||||
worker:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.12.5}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.1.2}
|
||||
restart: unless-stopped
|
||||
command: worker
|
||||
environment:
|
||||
|
||||
9
go.mod
9
go.mod
@ -9,10 +9,9 @@ require (
|
||||
github.com/garyburd/redigo v1.6.2 // indirect
|
||||
github.com/getsentry/sentry-go v0.12.0
|
||||
github.com/go-ldap/ldap/v3 v3.4.1
|
||||
github.com/go-openapi/runtime v0.21.0
|
||||
github.com/go-openapi/runtime v0.21.1
|
||||
github.com/go-openapi/strfmt v0.21.1
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
github.com/gorilla/mux v1.8.0
|
||||
@ -26,10 +25,10 @@ require (
|
||||
github.com/pires/go-proxyproto v0.6.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac // indirect
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/prometheus/client_golang v1.12.0
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
goauthentik.io/api v0.2021124.9
|
||||
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558
|
||||
goauthentik.io/api v0.2021125.1
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b
|
||||
|
||||
30
go.sum
30
go.sum
@ -70,8 +70,9 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@ -182,8 +183,8 @@ github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g
|
||||
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
|
||||
github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
|
||||
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
|
||||
github.com/go-openapi/runtime v0.21.0 h1:giZ8eT26R+/rx6RX2MkYjZPY8vPYVKDhP/mOazrQHzM=
|
||||
github.com/go-openapi/runtime v0.21.0/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs=
|
||||
github.com/go-openapi/runtime v0.21.1 h1:/KIG00BzA2x2HRStX2tnhbqbQdPcFlkgsYCiNY20FZs=
|
||||
github.com/go-openapi/runtime v0.21.1/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs=
|
||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
||||
@ -360,6 +361,7 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
@ -427,6 +429,7 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
@ -467,8 +470,9 @@ github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac/go.mod h1:hoL
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg=
|
||||
github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@ -476,13 +480,15 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
@ -562,8 +568,8 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
goauthentik.io/api v0.2021124.9 h1:l6kzTggi8lt+Vmm5js7oxp9U/bXoOEIl4565bUeepuM=
|
||||
goauthentik.io/api v0.2021124.9/go.mod h1:02nnD4FRd8lu8A1+ZuzqownBgvAhdCKzqkKX8v7JMTE=
|
||||
goauthentik.io/api v0.2021125.1 h1:Ja00N1D1wjqFiR90JV8nDayhmm39uLudzsJhwCjoQJ4=
|
||||
goauthentik.io/api v0.2021125.1/go.mod h1:02nnD4FRd8lu8A1+ZuzqownBgvAhdCKzqkKX8v7JMTE=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -655,6 +661,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f h1:1scJEYZBaF48BaG6tYbtxmLcXqwYGSfGcMoStTqkkIw=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -663,8 +670,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 h1:D7nTwh4J0i+5mW4Zjzn5omvlr6YBcWywE6KOcatyNxY=
|
||||
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -731,8 +738,9 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
@ -5,16 +5,24 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func BUILD() string {
|
||||
func BUILD(def string) string {
|
||||
build := os.Getenv("GIT_BUILD_HASH")
|
||||
if build == "" {
|
||||
return "tagged"
|
||||
return def
|
||||
}
|
||||
return build
|
||||
}
|
||||
|
||||
func OutpostUserAgent() string {
|
||||
return fmt.Sprintf("authentik-outpost@%s (build=%s)", VERSION, BUILD())
|
||||
func FullVersion() string {
|
||||
ver := VERSION
|
||||
if b := BUILD(""); b != "" {
|
||||
ver = fmt.Sprintf("%s.%s", ver, b)
|
||||
}
|
||||
return ver
|
||||
}
|
||||
|
||||
const VERSION = "2021.12.5"
|
||||
func OutpostUserAgent() string {
|
||||
return fmt.Sprintf("authentik-outpost@%s", FullVersion())
|
||||
}
|
||||
|
||||
const VERSION = "2022.1.2"
|
||||
|
||||
@ -171,7 +171,7 @@ func (a *APIController) StartBackgorundTasks() error {
|
||||
"outpost_type": a.Server.Type(),
|
||||
"uuid": a.instanceUUID.String(),
|
||||
"version": constants.VERSION,
|
||||
"build": constants.BUILD(),
|
||||
"build": constants.BUILD("tagged"),
|
||||
}).Set(1)
|
||||
go func() {
|
||||
a.logger.Debug("Starting WS Handler...")
|
||||
|
||||
@ -51,7 +51,7 @@ func (ac *APIController) initWS(akURL url.URL, outpostUUID string) error {
|
||||
Instruction: WebsocketInstructionHello,
|
||||
Args: map[string]interface{}{
|
||||
"version": constants.VERSION,
|
||||
"buildHash": constants.BUILD(),
|
||||
"buildHash": constants.BUILD("tagged"),
|
||||
"uuid": ac.instanceUUID.String(),
|
||||
},
|
||||
}
|
||||
@ -151,7 +151,7 @@ func (ac *APIController) startWSHandler() {
|
||||
"outpost_type": ac.Server.Type(),
|
||||
"uuid": ac.instanceUUID.String(),
|
||||
"version": constants.VERSION,
|
||||
"build": constants.BUILD(),
|
||||
"build": constants.BUILD("tagged"),
|
||||
}).SetToCurrentTime()
|
||||
}
|
||||
}
|
||||
@ -165,7 +165,7 @@ func (ac *APIController) startWSHealth() {
|
||||
Instruction: WebsocketInstructionHello,
|
||||
Args: map[string]interface{}{
|
||||
"version": constants.VERSION,
|
||||
"buildHash": constants.BUILD(),
|
||||
"buildHash": constants.BUILD("tagged"),
|
||||
"uuid": ac.instanceUUID.String(),
|
||||
},
|
||||
}
|
||||
@ -205,7 +205,7 @@ func (ac *APIController) startIntervalUpdater() {
|
||||
"outpost_type": ac.Server.Type(),
|
||||
"uuid": ac.instanceUUID.String(),
|
||||
"version": constants.VERSION,
|
||||
"build": constants.BUILD(),
|
||||
"build": constants.BUILD("tagged"),
|
||||
}).SetToCurrentTime()
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ func doGlobalSetup(outpost api.Outpost, globalConfig api.Config) {
|
||||
} else {
|
||||
l.Debug("Managed outpost, not setting global log level")
|
||||
}
|
||||
l.WithField("hash", constants.BUILD()).WithField("version", constants.VERSION).Info("Starting authentik outpost")
|
||||
l.WithField("hash", constants.BUILD("tagged")).WithField("version", constants.VERSION).Info("Starting authentik outpost")
|
||||
|
||||
if globalConfig.ErrorReporting.Enabled {
|
||||
dsn := "https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8"
|
||||
|
||||
@ -12,11 +12,7 @@ func (pi *ProviderInstance) UserEntry(u api.User) *ldap.Entry {
|
||||
attrs := utils.AKAttrsToLDAP(u.Attributes)
|
||||
|
||||
attrs = utils.EnsureAttributes(attrs, map[string][]string{
|
||||
"memberOf": pi.GroupsForUser(u),
|
||||
// Old fields for backwards compatibility
|
||||
"accountStatus": {utils.BoolToString(*u.IsActive)},
|
||||
"superuser": {utils.BoolToString(u.IsSuperuser)},
|
||||
// End old fields
|
||||
"memberOf": pi.GroupsForUser(u),
|
||||
"goauthentik.io/ldap/active": {utils.BoolToString(*u.IsActive)},
|
||||
"goauthentik.io/ldap/superuser": {utils.BoolToString(u.IsSuperuser)},
|
||||
"cn": {u.Username},
|
||||
|
||||
@ -124,7 +124,7 @@ func (pi *ProviderInstance) GetBaseEntry() *ldap.Entry {
|
||||
},
|
||||
{
|
||||
Name: "vendorVersion",
|
||||
Values: []string{fmt.Sprintf("authentik LDAP Outpost Version %s (build %s)", constants.VERSION, constants.BUILD())},
|
||||
Values: []string{fmt.Sprintf("authentik LDAP Outpost Version %s", constants.FullVersion())},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ func (ds *DirectSearcher) SearchBase(req *search.Request, authz bool) (ldap.Serv
|
||||
},
|
||||
{
|
||||
Name: "vendorVersion",
|
||||
Values: []string{fmt.Sprintf("authentik LDAP Outpost Version %s (build %s)", constants.VERSION, constants.BUILD())},
|
||||
Values: []string{fmt.Sprintf("authentik LDAP Outpost Version %s", constants.FullVersion())},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -139,7 +139,7 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult,
|
||||
// as a member.
|
||||
for _, u := range g.UsersObj {
|
||||
if flags.UserPk == u.Pk {
|
||||
// TODO: Is there a better way to clone this object?
|
||||
//TODO: Is there a better way to clone this object?
|
||||
fg := api.NewGroup(g.Pk, g.Name, g.Parent, g.ParentName, []int32{flags.UserPk}, []api.GroupMember{u})
|
||||
fg.SetAttributes(*g.Attributes)
|
||||
fg.SetIsSuperuser(*g.IsSuperuser)
|
||||
|
||||
@ -61,7 +61,7 @@ func parseFilterForGroupSingle(req api.ApiCoreGroupsListRequest, f *ber.Packet)
|
||||
}
|
||||
return req.MembersByUsername([]string{username}), false
|
||||
}
|
||||
// TODO: Support int
|
||||
//TODO: Support int
|
||||
default:
|
||||
return req, false
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ func parseFilterForUserSingle(req api.ApiCoreUsersListRequest, f *ber.Packet) (a
|
||||
}
|
||||
return req.GroupsByName([]string{name}), false
|
||||
}
|
||||
// TODO: Support int
|
||||
//TODO: Support int
|
||||
default:
|
||||
return req, false
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore
|
||||
mux := mux.NewRouter()
|
||||
a := &Application{
|
||||
Host: externalHost.Host,
|
||||
log: log.WithField("logger", "authentik.outpost.proxy.bundle").WithField("provider", p.Name),
|
||||
log: muxLogger,
|
||||
outpostName: ak.Outpost.Name,
|
||||
endpint: endpoint,
|
||||
oauthConfig: oauth2Config,
|
||||
@ -172,7 +172,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore
|
||||
for _, regex := range strings.Split(*p.SkipPathRegex, "\n") {
|
||||
re, err := regexp.Compile(regex)
|
||||
if err != nil {
|
||||
// TODO: maybe create event for this?
|
||||
//TODO: maybe create event for this?
|
||||
a.log.WithError(err).Warning("failed to compile SkipPathRegex")
|
||||
continue
|
||||
} else {
|
||||
@ -187,12 +187,16 @@ func (a *Application) Mode() api.ProxyMode {
|
||||
return *a.proxyConfig.Mode
|
||||
}
|
||||
|
||||
func (a *Application) ProxyConfig() api.ProxyOutpostConfig {
|
||||
return a.proxyConfig
|
||||
}
|
||||
|
||||
func (a *Application) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
a.mux.ServeHTTP(rw, r)
|
||||
}
|
||||
|
||||
func (a *Application) handleSignOut(rw http.ResponseWriter, r *http.Request) {
|
||||
// TODO: Token revocation
|
||||
//TODO: Token revocation
|
||||
s, err := a.sessions.Get(r, constants.SeesionName)
|
||||
if err != nil {
|
||||
http.Redirect(rw, r, a.endpint.EndSessionEndpoint, http.StatusFound)
|
||||
|
||||
@ -13,15 +13,18 @@ import (
|
||||
type OIDCEndpoint struct {
|
||||
oauth2.Endpoint
|
||||
EndSessionEndpoint string
|
||||
JwksUri string
|
||||
}
|
||||
|
||||
func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoint {
|
||||
authUrl := p.OidcConfiguration.AuthorizationEndpoint
|
||||
endUrl := p.OidcConfiguration.EndSessionEndpoint
|
||||
jwksUrl := p.OidcConfiguration.JwksUri
|
||||
if browserHost, found := os.LookupEnv("AUTHENTIK_HOST_BROWSER"); found && browserHost != "" {
|
||||
host := os.Getenv("AUTHENTIK_HOST")
|
||||
authUrl = strings.ReplaceAll(authUrl, host, browserHost)
|
||||
endUrl = strings.ReplaceAll(endUrl, host, browserHost)
|
||||
jwksUrl = strings.ReplaceAll(jwksUrl, host, browserHost)
|
||||
}
|
||||
ep := OIDCEndpoint{
|
||||
Endpoint: oauth2.Endpoint{
|
||||
@ -30,6 +33,7 @@ func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoin
|
||||
AuthStyle: oauth2.AuthStyleInParams,
|
||||
},
|
||||
EndSessionEndpoint: endUrl,
|
||||
JwksUri: jwksUrl,
|
||||
}
|
||||
authU, err := url.Parse(authUrl)
|
||||
if err != nil {
|
||||
@ -39,6 +43,10 @@ func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoin
|
||||
if err != nil {
|
||||
return ep
|
||||
}
|
||||
jwksU, err := url.Parse(jwksUrl)
|
||||
if err != nil {
|
||||
return ep
|
||||
}
|
||||
if authU.Host != "localhost:8000" {
|
||||
return ep
|
||||
}
|
||||
@ -54,7 +62,10 @@ func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoin
|
||||
authU.Scheme = aku.Scheme
|
||||
endU.Host = aku.Host
|
||||
endU.Scheme = aku.Scheme
|
||||
jwksU.Host = aku.Host
|
||||
jwksU.Scheme = aku.Scheme
|
||||
ep.AuthURL = authU.String()
|
||||
ep.EndSessionEndpoint = endU.String()
|
||||
ep.JwksUri = jwksU.String()
|
||||
return ep
|
||||
}
|
||||
|
||||
@ -14,14 +14,6 @@ import (
|
||||
func (a *Application) addHeaders(headers http.Header, c *Claims) {
|
||||
// https://goauthentik.io/docs/providers/proxy/proxy
|
||||
|
||||
// Legacy headers, remove after 2022.1
|
||||
headers.Set("X-Auth-Username", c.PreferredUsername)
|
||||
headers.Set("X-Auth-Groups", strings.Join(c.Groups, "|"))
|
||||
headers.Set("X-Forwarded-Email", c.Email)
|
||||
headers.Set("X-Forwarded-Preferred-Username", c.PreferredUsername)
|
||||
headers.Set("X-Forwarded-User", c.Sub)
|
||||
|
||||
// New headers, unique prefix
|
||||
headers.Set("X-authentik-username", c.PreferredUsername)
|
||||
headers.Set("X-authentik-groups", strings.Join(c.Groups, "|"))
|
||||
headers.Set("X-authentik-email", c.Email)
|
||||
@ -30,7 +22,7 @@ func (a *Application) addHeaders(headers http.Header, c *Claims) {
|
||||
headers.Set("X-authentik-jwt", c.RawToken)
|
||||
|
||||
// System headers
|
||||
headers.Set("X-authentik-meta-jwks", a.proxyConfig.OidcConfiguration.JwksUri)
|
||||
headers.Set("X-authentik-meta-jwks", a.endpint.JwksUri)
|
||||
headers.Set("X-authentik-meta-outpost", a.outpostName)
|
||||
headers.Set("X-authentik-meta-provider", a.proxyConfig.Name)
|
||||
headers.Set("X-authentik-meta-app", a.proxyConfig.AssignedApplicationSlug)
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"goauthentik.io/api"
|
||||
"goauthentik.io/internal/outpost/proxyv2/constants"
|
||||
@ -34,6 +35,10 @@ func (a *Application) forwardHandleTraefik(rw http.ResponseWriter, r *http.Reque
|
||||
a.log.Trace("path can be accessed without authentication")
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(r.Header.Get("X-Forwarded-Uri"), "/akprox") {
|
||||
a.log.WithField("url", r.URL.String()).Trace("path begins with /akprox, allowing access")
|
||||
return
|
||||
}
|
||||
host := ""
|
||||
s, _ := a.sessions.Get(r, constants.SeesionName)
|
||||
// Optional suffix, which is appended to the URL
|
||||
@ -49,14 +54,6 @@ func (a *Application) forwardHandleTraefik(rw http.ResponseWriter, r *http.Reque
|
||||
// see https://doc.traefik.io/traefik/middlewares/forwardauth/
|
||||
// X-Forwarded-Uri is only the path, so we need to build the entire URL
|
||||
s.Values[constants.SessionRedirect] = a.getTraefikForwardUrl(r).String()
|
||||
if r.Header.Get("X-Forwarded-Uri") == "/akprox/start" {
|
||||
a.log.Info("Detected potential redirect loop")
|
||||
if val, ok := s.Values[constants.SessionLoopDetection]; !ok {
|
||||
s.Values[constants.SessionLoopDetection] = 1
|
||||
} else {
|
||||
s.Values[constants.SessionLoopDetection] = val.(int) + 1
|
||||
}
|
||||
}
|
||||
err = s.Save(r, rw)
|
||||
if err != nil {
|
||||
a.log.WithError(err).Warning("failed to save session before redirect")
|
||||
@ -83,5 +80,12 @@ func (a *Application) forwardHandleNginx(rw http.ResponseWriter, r *http.Request
|
||||
a.log.Trace("path can be accessed without authentication")
|
||||
return
|
||||
}
|
||||
fwu := a.getTraefikForwardUrl(r)
|
||||
if fwu.String() != r.URL.String() {
|
||||
if strings.HasPrefix(fwu.Path, "/akprox") {
|
||||
a.log.WithField("url", r.URL.String()).Trace("path begins with /akprox, allowing access")
|
||||
return
|
||||
}
|
||||
}
|
||||
http.Error(rw, "unauthorized request", http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
@ -25,13 +25,6 @@ func (a *Application) handleRedirect(rw http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
a.log.WithError(err).Warning("failed to save session")
|
||||
}
|
||||
if loop, ok := s.Values[constants.SessionLoopDetection]; ok {
|
||||
if loop.(int) > 10 {
|
||||
rw.WriteHeader(http.StatusBadRequest)
|
||||
a.ErrorPage(rw, r, "Detected redirect loop, make sure /akprox is accessible without authentication.")
|
||||
return
|
||||
}
|
||||
}
|
||||
http.Redirect(rw, r, a.oauthConfig.AuthCodeURL(newState), http.StatusFound)
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ func (a *Application) getStore(p api.ProxyOutpostConfig) sessions.Store {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
rs.SetMaxLength(math.MaxInt64)
|
||||
rs.SetMaxLength(math.MaxInt)
|
||||
if p.TokenValidity.IsSet() {
|
||||
t := p.TokenValidity.Get()
|
||||
// Add one to the validity to ensure we don't have a session with indefinite length
|
||||
@ -39,7 +39,7 @@ func (a *Application) getStore(p api.ProxyOutpostConfig) sessions.Store {
|
||||
// when using OpenID Connect , since this can contain a large amount of extra information in the id_token
|
||||
|
||||
// Note, when using the FilesystemStore only the session.ID is written to a browser cookie, so this is explicit for the storage on disk
|
||||
cs.MaxLength(math.MaxInt64)
|
||||
cs.MaxLength(math.MaxInt)
|
||||
if p.TokenValidity.IsSet() {
|
||||
t := p.TokenValidity.Get()
|
||||
// Add one to the validity to ensure we don't have a session with indefinite length
|
||||
|
||||
@ -6,7 +6,9 @@ import (
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"goauthentik.io/api"
|
||||
"goauthentik.io/internal/outpost/proxyv2/constants"
|
||||
)
|
||||
|
||||
@ -20,6 +22,33 @@ func urlJoin(originalUrl string, newPath string) string {
|
||||
}
|
||||
|
||||
func (a *Application) redirectToStart(rw http.ResponseWriter, r *http.Request) {
|
||||
s, err := a.sessions.Get(r, constants.SeesionName)
|
||||
if err == nil {
|
||||
a.log.WithError(err).Warning("failed to decode session")
|
||||
}
|
||||
redirectUrl := r.URL.String()
|
||||
// simple way to copy the URL
|
||||
u, _ := url.Parse(redirectUrl)
|
||||
// In proxy and forward_single mode we only have one URL that we route on
|
||||
// if we somehow got here without that URL, make sure we're at least redirected back to it
|
||||
if a.Mode() == api.PROXYMODE_PROXY || a.Mode() == api.PROXYMODE_FORWARD_SINGLE {
|
||||
u.Host = a.proxyConfig.ExternalHost
|
||||
}
|
||||
if a.Mode() == api.PROXYMODE_FORWARD_DOMAIN {
|
||||
dom := strings.TrimPrefix(*a.proxyConfig.CookieDomain, ".")
|
||||
// In forward_domain we only check that the current URL's host
|
||||
// ends with the cookie domain (remove the leading period if set)
|
||||
if !strings.HasSuffix(r.URL.Hostname(), dom) {
|
||||
a.log.WithField("url", r.URL.String()).WithField("cd", dom).Warning("Invalid redirect found")
|
||||
redirectUrl = ""
|
||||
}
|
||||
}
|
||||
s.Values[constants.SessionRedirect] = redirectUrl
|
||||
err = s.Save(r, rw)
|
||||
if err != nil {
|
||||
a.log.WithError(err).Warning("failed to save session before redirect")
|
||||
}
|
||||
|
||||
authUrl := urlJoin(a.proxyConfig.ExternalHost, "/akprox/start")
|
||||
http.Redirect(rw, r, authUrl, http.StatusFound)
|
||||
}
|
||||
|
||||
@ -6,4 +6,3 @@ const SessionOAuthState = "oauth_state"
|
||||
const SessionClaims = "claims"
|
||||
|
||||
const SessionRedirect = "redirect"
|
||||
const SessionLoopDetection = "loop_detection"
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"goauthentik.io/internal/outpost/proxyv2/application"
|
||||
"goauthentik.io/internal/outpost/proxyv2/metrics"
|
||||
"goauthentik.io/internal/utils/web"
|
||||
staticWeb "goauthentik.io/web"
|
||||
@ -43,6 +44,42 @@ func (ps *ProxyServer) HandleStatic(rw http.ResponseWriter, r *http.Request) {
|
||||
}).Observe(float64(after))
|
||||
}
|
||||
|
||||
func (ps *ProxyServer) lookupApp(r *http.Request) (*application.Application, string) {
|
||||
host := web.GetHost(r)
|
||||
// Try to find application by directly looking up host first (proxy, forward_auth_single)
|
||||
a, ok := ps.apps[host]
|
||||
if ok {
|
||||
ps.log.WithField("host", host).WithField("app", a.ProxyConfig().Name).Debug("Found app based direct host match")
|
||||
return a, host
|
||||
}
|
||||
// For forward_auth_domain, we don't have a direct app to domain relationship
|
||||
// Check through all apps, and check how much of their cookie domain matches the host
|
||||
// Return the application that has the longest match
|
||||
var longestMatch *application.Application
|
||||
longestMatchLength := 0
|
||||
for _, app := range ps.apps {
|
||||
// Check if the cookie domain has a leading period for a wildcard
|
||||
// This will decrease the weight of a wildcard domain, but a request to example.com
|
||||
// with the cookie domain set to example.com will still be routed correctly.
|
||||
cd := strings.TrimPrefix(*app.ProxyConfig().CookieDomain, ".")
|
||||
if !strings.HasSuffix(host, cd) {
|
||||
continue
|
||||
}
|
||||
if len(cd) < longestMatchLength {
|
||||
continue
|
||||
}
|
||||
longestMatch = app
|
||||
longestMatchLength = len(cd)
|
||||
}
|
||||
// Check if our longes match is 0, in which case we didn't match, so we
|
||||
// manually return no app
|
||||
if longestMatchLength == 0 {
|
||||
return nil, host
|
||||
}
|
||||
ps.log.WithField("host", host).WithField("app", longestMatch.ProxyConfig().Name).Debug("Found app based on cookie domain")
|
||||
return longestMatch, host
|
||||
}
|
||||
|
||||
func (ps *ProxyServer) Handle(rw http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.Path, "/akprox/static") {
|
||||
ps.HandleStatic(rw, r)
|
||||
@ -52,9 +89,8 @@ func (ps *ProxyServer) Handle(rw http.ResponseWriter, r *http.Request) {
|
||||
ps.HandlePing(rw, r)
|
||||
return
|
||||
}
|
||||
host := web.GetHost(r)
|
||||
a, ok := ps.apps[host]
|
||||
if !ok {
|
||||
a, host := ps.lookupApp(r)
|
||||
if a == nil {
|
||||
// If we only have one handler, host name switching doesn't matter
|
||||
if len(ps.apps) == 1 {
|
||||
ps.log.WithField("host", host).Trace("passing to single app mux")
|
||||
|
||||
@ -70,11 +70,12 @@ func NewProxyServer(ac *ak.APIController, portOffset int) *ProxyServer {
|
||||
return s
|
||||
}
|
||||
|
||||
func (ps *ProxyServer) HandleHost(host string, rw http.ResponseWriter, r *http.Request) bool {
|
||||
if app, ok := ps.apps[host]; ok {
|
||||
if app.Mode() == api.PROXYMODE_PROXY {
|
||||
func (ps *ProxyServer) HandleHost(rw http.ResponseWriter, r *http.Request) bool {
|
||||
a, host := ps.lookupApp(r)
|
||||
if a != nil {
|
||||
if a.Mode() == api.PROXYMODE_PROXY {
|
||||
ps.log.WithField("host", host).Trace("routing to proxy outpost")
|
||||
app.ServeHTTP(rw, r)
|
||||
a.ServeHTTP(rw, r)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,10 +47,9 @@ func (ws *WebServer) configureProxy() {
|
||||
ws.proxyErrorHandler(rw, r, fmt.Errorf("authentik core not running yet"))
|
||||
return
|
||||
}
|
||||
host := web.GetHost(r)
|
||||
before := time.Now()
|
||||
if ws.ProxyServer != nil {
|
||||
if ws.ProxyServer.HandleHost(host, rw, r) {
|
||||
if ws.ProxyServer.HandleHost(rw, r) {
|
||||
Requests.With(prometheus.Labels{
|
||||
"dest": "embedded_outpost",
|
||||
}).Observe(float64(time.Since(before)))
|
||||
@ -60,7 +59,7 @@ func (ws *WebServer) configureProxy() {
|
||||
Requests.With(prometheus.Labels{
|
||||
"dest": "py",
|
||||
}).Observe(float64(time.Since(before)))
|
||||
ws.log.WithField("host", host).Trace("routing to application server")
|
||||
ws.log.WithField("host", web.GetHost(r)).Trace("routing to application server")
|
||||
rp.ServeHTTP(rw, r)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Stage 1: Build
|
||||
FROM docker.io/golang:1.17.5-bullseye AS builder
|
||||
FROM docker.io/golang:1.17.6-bullseye AS builder
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
|
||||
@ -61,8 +61,11 @@ MODE_FILE="/tmp/authentik-mode"
|
||||
if [[ "$1" == "server" ]]; then
|
||||
wait_for_db
|
||||
echo "server" > $MODE_FILE
|
||||
# We only set prometheus_multiproc_dir for serer, as with the worker it just fills up the disk
|
||||
export prometheus_multiproc_dir=/dev/shm/
|
||||
# We only set PROMETHEUS_MULTIPROC_DIR for serer, as with the worker it just fills up the disk
|
||||
# as one file is created per process
|
||||
#
|
||||
# Set to TMPDIR instead hardcoded path so this can be used outside docker too
|
||||
export PROMETHEUS_MULTIPROC_DIR=$TMPDIR
|
||||
python -m lifecycle.migrate
|
||||
/authentik-proxy
|
||||
elif [[ "$1" == "worker" ]]; then
|
||||
|
||||
@ -60,3 +60,10 @@ else:
|
||||
|
||||
workers = int(os.environ.get("WORKERS", default_workers))
|
||||
threads = int(os.environ.get("THREADS", 4))
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def worker_exit(server, worker):
|
||||
"""Remove pid dbs when worker is shutdown"""
|
||||
from prometheus_client import multiprocess
|
||||
|
||||
multiprocess.mark_process_dead(worker.pid)
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
"""This file needs to be run from the root of the project to correctly
|
||||
import authentik. This is done by the dockerfile."""
|
||||
from json import dumps
|
||||
from sys import exit as sysexit
|
||||
from sys import stderr
|
||||
from time import sleep, time
|
||||
|
||||
@ -25,6 +26,12 @@ def j_print(event: str, log_level: str = "info", **kwargs):
|
||||
print(dumps(data), file=stderr)
|
||||
|
||||
|
||||
# Sanity check, ensure SECRET_KEY is set before we even check for database connectivity
|
||||
if CONFIG.y("secret_key") is None or len(CONFIG.y("secret_key")) == 0:
|
||||
j_print("Secret key missing, check https://goauthentik.io/docs/installation/.")
|
||||
sysexit(1)
|
||||
|
||||
|
||||
while True:
|
||||
try:
|
||||
conn = connect(
|
||||
|
||||
574
poetry.lock
generated
574
poetry.lock
generated
@ -54,11 +54,11 @@ vine = "5.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "asgiref"
|
||||
version = "3.4.1"
|
||||
version = "3.5.0"
|
||||
description = "ASGI specs, helper code, and adapters"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"]
|
||||
@ -73,7 +73,7 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "astroid"
|
||||
version = "2.9.2"
|
||||
version = "2.9.3"
|
||||
description = "An abstract syntax tree for Python with inference support."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -227,14 +227,14 @@ uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "boto3"
|
||||
version = "1.20.29"
|
||||
version = "1.20.41"
|
||||
description = "The AWS SDK for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">= 3.6"
|
||||
|
||||
[package.dependencies]
|
||||
botocore = ">=1.23.29,<1.24.0"
|
||||
botocore = ">=1.23.41,<1.24.0"
|
||||
jmespath = ">=0.7.1,<1.0.0"
|
||||
s3transfer = ">=0.5.0,<0.6.0"
|
||||
|
||||
@ -243,7 +243,7 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
|
||||
|
||||
[[package]]
|
||||
name = "botocore"
|
||||
version = "1.23.29"
|
||||
version = "1.23.41"
|
||||
description = "Low-level, data-driven core of boto 3."
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -267,11 +267,11 @@ python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "cachetools"
|
||||
version = "4.2.4"
|
||||
version = "5.0.0"
|
||||
description = "Extensible memoizing collections and decorators"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "~=3.5"
|
||||
python-versions = "~=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "cattrs"
|
||||
@ -800,11 +800,11 @@ tornado = ">=5.0.0,<7.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "frozenlist"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
description = "A list-like structure which implements collections.abc.MutableSequence"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "geoip2"
|
||||
@ -833,7 +833,7 @@ smmap = ">=3.0.1,<6"
|
||||
|
||||
[[package]]
|
||||
name = "gitpython"
|
||||
version = "3.1.24"
|
||||
version = "3.1.26"
|
||||
description = "GitPython is a python library used to interact with Git repositories"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -844,14 +844,14 @@ gitdb = ">=4.0.1,<5"
|
||||
|
||||
[[package]]
|
||||
name = "google-auth"
|
||||
version = "2.3.3"
|
||||
version = "2.4.0"
|
||||
description = "Google Authentication Library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
|
||||
|
||||
[package.dependencies]
|
||||
cachetools = ">=2.0.0,<5.0"
|
||||
cachetools = ">=2.0.0,<6.0"
|
||||
pyasn1-modules = ">=0.2.1"
|
||||
rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""}
|
||||
six = ">=1.9.0"
|
||||
@ -877,7 +877,7 @@ tornado = ["tornado (>=0.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.12.0"
|
||||
version = "0.13.0"
|
||||
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -934,7 +934,7 @@ python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "importlib-metadata"
|
||||
version = "4.10.0"
|
||||
version = "4.10.1"
|
||||
description = "Read metadata from Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -999,7 +999,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "jsonschema"
|
||||
version = "4.3.3"
|
||||
version = "4.4.0"
|
||||
description = "An implementation of JSON Schema validation for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -1122,11 +1122,11 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "multidict"
|
||||
version = "5.2.0"
|
||||
version = "6.0.1"
|
||||
description = "multidict implementation"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
@ -1173,7 +1173,7 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
|
||||
|
||||
[[package]]
|
||||
name = "paramiko"
|
||||
version = "2.9.1"
|
||||
version = "2.9.2"
|
||||
description = "SSH2 protocol library"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -1297,7 +1297,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pycryptodome"
|
||||
version = "3.12.0"
|
||||
version = "3.13.0"
|
||||
description = "Cryptographic library for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -1362,15 +1362,14 @@ pylint = ">=1.7"
|
||||
|
||||
[[package]]
|
||||
name = "pynacl"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
description = "Python binding to the Networking and Cryptography (NaCl) library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
cffi = ">=1.4.1"
|
||||
six = "*"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"]
|
||||
@ -1394,7 +1393,7 @@ test = ["flaky", "pretend", "pytest (>=3.0.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "3.0.6"
|
||||
version = "3.0.7"
|
||||
description = "Python parsing module"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -1405,11 +1404,11 @@ diagrams = ["jinja2", "railroad-diagrams"]
|
||||
|
||||
[[package]]
|
||||
name = "pyrsistent"
|
||||
version = "0.18.0"
|
||||
version = "0.18.1"
|
||||
description = "Persistent/Functional/Immutable data structures"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
@ -1449,11 +1448,11 @@ testing = ["django", "django-configurations (>=2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-randomly"
|
||||
version = "3.10.3"
|
||||
version = "3.11.0"
|
||||
description = "Pytest plugin to randomly order tests and control random.seed."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
pytest = "*"
|
||||
@ -1506,7 +1505,7 @@ python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "4.1.0"
|
||||
version = "4.1.1"
|
||||
description = "Python client for Redis database and key-value store"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -1514,11 +1513,11 @@ python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
deprecated = ">=1.2.3"
|
||||
packaging = ">=21.3"
|
||||
packaging = ">=20.4"
|
||||
|
||||
[package.extras]
|
||||
cryptography = ["cryptography (>=36.0.1)", "requests (>=2.26.0)"]
|
||||
hiredis = ["hiredis (>=1.0.0)"]
|
||||
ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
@ -1609,39 +1608,33 @@ urllib3 = {version = ">=1.26,<2.0", extras = ["secure"]}
|
||||
|
||||
[[package]]
|
||||
name = "sentry-sdk"
|
||||
version = "1.5.0"
|
||||
description = ""
|
||||
version = "1.5.3"
|
||||
description = "Python client for Sentry (https://sentry.io)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
develop = false
|
||||
|
||||
[package.dependencies]
|
||||
certifi = "*"
|
||||
urllib3 = ">=1.10.0"
|
||||
|
||||
[package.extras]
|
||||
flask = ["flask (>=0.11)", "blinker (>=1.1)"]
|
||||
bottle = ["bottle (>=0.12.13)"]
|
||||
falcon = ["falcon (>=1.4)"]
|
||||
django = ["django (>=1.8)"]
|
||||
sanic = ["sanic (>=0.8)"]
|
||||
celery = ["celery (>=3)"]
|
||||
beam = ["apache-beam (>=2.12)"]
|
||||
rq = ["rq (>=0.6)"]
|
||||
aiohttp = ["aiohttp (>=3.5)"]
|
||||
tornado = ["tornado (>=5)"]
|
||||
sqlalchemy = ["sqlalchemy (>=1.2)"]
|
||||
pyspark = ["pyspark (>=2.4.4)"]
|
||||
pure_eval = ["pure-eval", "executing", "asttokens"]
|
||||
beam = ["apache-beam (>=2.12)"]
|
||||
bottle = ["bottle (>=0.12.13)"]
|
||||
celery = ["celery (>=3)"]
|
||||
chalice = ["chalice (>=1.16.0)"]
|
||||
django = ["django (>=1.8)"]
|
||||
falcon = ["falcon (>=1.4)"]
|
||||
flask = ["flask (>=0.11)", "blinker (>=1.1)"]
|
||||
httpx = ["httpx (>=0.16.0)"]
|
||||
|
||||
[package.source]
|
||||
type = "git"
|
||||
url = 'https://github.com/beryju/sentry-python.git'
|
||||
reference = '379aee28b15d3b87b381317746c4efd24b3d7bc3'
|
||||
resolved_reference = "379aee28b15d3b87b381317746c4efd24b3d7bc3"
|
||||
pure_eval = ["pure-eval", "executing", "asttokens"]
|
||||
pyspark = ["pyspark (>=2.4.4)"]
|
||||
quart = ["quart (>=0.16.1)", "blinker (>=1.1)"]
|
||||
rq = ["rq (>=0.6)"]
|
||||
sanic = ["sanic (>=0.8)"]
|
||||
sqlalchemy = ["sqlalchemy (>=1.2)"]
|
||||
tornado = ["tornado (>=5)"]
|
||||
|
||||
[[package]]
|
||||
name = "service-identity"
|
||||
@ -1886,7 +1879,7 @@ python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "1.26.7"
|
||||
version = "1.26.8"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -1905,7 +1898,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
description = "The lightning-fast ASGI server."
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -1921,10 +1914,10 @@ python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"stan
|
||||
PyYAML = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
|
||||
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
|
||||
watchgod = {version = ">=0.6", optional = true, markers = "extra == \"standard\""}
|
||||
websockets = {version = ">=10.0", optional = true, markers = "python_version >= \"3.7\" and extra == \"standard\""}
|
||||
websockets = {version = ">=10.0", optional = true, markers = "extra == \"standard\""}
|
||||
|
||||
[package.extras]
|
||||
standard = ["httptools (>=0.2.0,<0.4.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "websockets (>=9.1)", "websockets (>=10.0)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"]
|
||||
standard = ["websockets (>=10.0)", "httptools (>=0.2.0,<0.4.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"]
|
||||
|
||||
[[package]]
|
||||
name = "uvloop"
|
||||
@ -1965,7 +1958,7 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "webauthn"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
description = "Pythonic WebAuthn"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -2070,7 +2063,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "b943f64c1111790d5534be74e941ce6880efb75cdf562993a66f138c082cd80f"
|
||||
content-hash = "d3061d973ae4fd3ddea0bff63f1dbd615322546024b75dc6015ef5faf01d6368"
|
||||
|
||||
[metadata.files]
|
||||
aiohttp = [
|
||||
@ -2160,16 +2153,16 @@ amqp = [
|
||||
{file = "amqp-5.0.9.tar.gz", hash = "sha256:1e5f707424e544078ca196e72ae6a14887ce74e02bd126be54b7c03c971bef18"},
|
||||
]
|
||||
asgiref = [
|
||||
{file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"},
|
||||
{file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"},
|
||||
{file = "asgiref-3.5.0-py3-none-any.whl", hash = "sha256:88d59c13d634dcffe0510be048210188edd79aeccb6a6c9028cdad6f31d730a9"},
|
||||
{file = "asgiref-3.5.0.tar.gz", hash = "sha256:2f8abc20f7248433085eda803936d98992f1343ddb022065779f37c5da0181d0"},
|
||||
]
|
||||
asn1crypto = [
|
||||
{file = "asn1crypto-1.4.0-py2.py3-none-any.whl", hash = "sha256:4bcdf33c861c7d40bdcd74d8e4dd7661aac320fcdf40b9a3f95b4ee12fde2fa8"},
|
||||
{file = "asn1crypto-1.4.0.tar.gz", hash = "sha256:f4f6e119474e58e04a2b1af817eb585b4fd72bdd89b998624712b5c99be7641c"},
|
||||
]
|
||||
astroid = [
|
||||
{file = "astroid-2.9.2-py3-none-any.whl", hash = "sha256:aa296702f1a5c3102c860de49473aaa90a7f6d221555d5cf2678940a9be32a4e"},
|
||||
{file = "astroid-2.9.2.tar.gz", hash = "sha256:72ace9c3333e274e9248168fc4f3e300da8545af1c303bd69197027f49e2bfff"},
|
||||
{file = "astroid-2.9.3-py3-none-any.whl", hash = "sha256:506daabe5edffb7e696ad82483ad0228245a9742ed7d2d8c9cdb31537decf9f6"},
|
||||
{file = "astroid-2.9.3.tar.gz", hash = "sha256:1efdf4e867d4d8ba4a9f6cf9ce07cd182c4c41de77f23814feb27ca93ca9d877"},
|
||||
]
|
||||
async-generator = [
|
||||
{file = "async_generator-1.10-py3-none-any.whl", hash = "sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b"},
|
||||
@ -2216,20 +2209,20 @@ black = [
|
||||
{file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"},
|
||||
]
|
||||
boto3 = [
|
||||
{file = "boto3-1.20.29-py3-none-any.whl", hash = "sha256:1955ec05e4a2cf8d503af72f5bb26e3a5526438c89ee875d77a2e8d082277589"},
|
||||
{file = "boto3-1.20.29.tar.gz", hash = "sha256:ab0ca0d0dbb90a05b010bbcc038850f0b71979182b44bd88313eafb6ae8a26a3"},
|
||||
{file = "boto3-1.20.41-py3-none-any.whl", hash = "sha256:aaddf6cf93568b734ad62fd96991775bccc7f016e93ff4e98dc1aa4f7586440c"},
|
||||
{file = "boto3-1.20.41.tar.gz", hash = "sha256:fb02467a6e8109c7db994ba77fa2e8381ed129ce312988d8ef23edf6e3a3c7f1"},
|
||||
]
|
||||
botocore = [
|
||||
{file = "botocore-1.23.29-py3-none-any.whl", hash = "sha256:d6706a8e72df56c5b25291cf5175b790bf1c71c740bdf8cb57f258b97ed39e2c"},
|
||||
{file = "botocore-1.23.29.tar.gz", hash = "sha256:6ba08e8738b38b1c3cb11cd4d4ee1b4aa557511271071bdd7a9c41bc0b212eeb"},
|
||||
{file = "botocore-1.23.41-py3-none-any.whl", hash = "sha256:41104e1c976c9c410387b3c7d265466b314f287a1c13fd4b543768135301058a"},
|
||||
{file = "botocore-1.23.41.tar.gz", hash = "sha256:9137c59c4eb1dee60ae3c710e94f56119a1b33b0b17ff3ad878fc2f4ce77843a"},
|
||||
]
|
||||
bump2version = [
|
||||
{file = "bump2version-1.0.1-py2.py3-none-any.whl", hash = "sha256:37f927ea17cde7ae2d7baf832f8e80ce3777624554a653006c9144f8017fe410"},
|
||||
{file = "bump2version-1.0.1.tar.gz", hash = "sha256:762cb2bfad61f4ec8e2bdf452c7c267416f8c70dd9ecb1653fd0bbb01fa936e6"},
|
||||
]
|
||||
cachetools = [
|
||||
{file = "cachetools-4.2.4-py3-none-any.whl", hash = "sha256:92971d3cb7d2a97efff7c7bb1657f21a8f5fb309a37530537c71b1774189f2d1"},
|
||||
{file = "cachetools-4.2.4.tar.gz", hash = "sha256:89ea6f1b638d5a73a4f9226be57ac5e4f399d22770b92355f92dcb0f7f001693"},
|
||||
{file = "cachetools-5.0.0-py3-none-any.whl", hash = "sha256:8fecd4203a38af17928be7b90689d8083603073622229ca7077b72d8e5a976e4"},
|
||||
{file = "cachetools-5.0.0.tar.gz", hash = "sha256:486471dfa8799eb7ec503a8059e263db000cdda20075ce5e48903087f79d5fd6"},
|
||||
]
|
||||
cattrs = [
|
||||
{file = "cattrs-1.10.0-py3-none-any.whl", hash = "sha256:35dd9063244263e63bd0bd24ea61e3015b00272cead084b2c40d788b0f857c46"},
|
||||
@ -2506,78 +2499,65 @@ flower = [
|
||||
{file = "flower-1.0.0.tar.gz", hash = "sha256:2e17c4fb55c569508f3bfee7fe41f44b8362d30dbdf77b604a9d9f4740fe8cbd"},
|
||||
]
|
||||
frozenlist = [
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:977a1438d0e0d96573fd679d291a1542097ea9f4918a8b6494b06610dfeefbf9"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8d86547a5e98d9edd47c432f7a14b0c5592624b496ae9880fb6332f34af1edc"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:181754275d5d32487431a0a29add4f897968b7157204bc1eaaf0a0ce80c5ba7d"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5df31bb2b974f379d230a25943d9bf0d3bc666b4b0807394b131a28fca2b0e5f"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4766632cd8a68e4f10f156a12c9acd7b1609941525569dd3636d859d79279ed3"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16eef427c51cb1203a7c0ab59d1b8abccaba9a4f58c4bfca6ed278fc896dc193"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:01d79515ed5aa3d699b05f6bdcf1fe9087d61d6b53882aa599a10853f0479c6c"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:28e164722ea0df0cf6d48c4d5bdf3d19e87aaa6dfb39b0ba91153f224b912020"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e63ad0beef6ece06475d29f47d1f2f29727805376e09850ebf64f90777962792"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41de4db9b9501679cf7cddc16d07ac0f10ef7eb58c525a1c8cbff43022bddca4"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c6a9d84ee6427b65a81fc24e6ef589cb794009f5ca4150151251c062773e7ed2"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:f5f3b2942c3b8b9bfe76b408bbaba3d3bb305ee3693e8b1d631fe0a0d4f93673"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c98d3c04701773ad60d9545cd96df94d955329efc7743fdb96422c4b669c633b"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-win32.whl", hash = "sha256:72cfbeab7a920ea9e74b19aa0afe3b4ad9c89471e3badc985d08756efa9b813b"},
|
||||
{file = "frozenlist-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:11ff401951b5ac8c0701a804f503d72c048173208490c54ebb8d7bb7c07a6d00"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b46f997d5ed6d222a863b02cdc9c299101ee27974d9bbb2fd1b3c8441311c408"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:351686ca020d1bcd238596b1fa5c8efcbc21bffda9d0efe237aaa60348421e2a"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfbaa08cf1452acad9cb1c1d7b89394a41e712f88df522cea1a0f296b57782a0"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ae2f5e9fa10805fb1c9adbfefaaecedd9e31849434be462c3960a0139ed729"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6790b8d96bbb74b7a6f4594b6f131bd23056c25f2aa5d816bd177d95245a30e3"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:41f62468af1bd4e4b42b5508a3fe8cc46a693f0cdd0ca2f443f51f207893d837"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:ec6cf345771cdb00791d271af9a0a6fbfc2b6dd44cb753f1eeaa256e21622adb"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:14a5cef795ae3e28fb504b73e797c1800e9249f950e1c964bb6bdc8d77871161"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8b54cdd2fda15467b9b0bfa78cee2ddf6dbb4585ef23a16e14926f4b076dfae4"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f025f1d6825725b09c0038775acab9ae94264453a696cc797ce20c0769a7b367"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:84e97f59211b5b9083a2e7a45abf91cfb441369e8bb6d1f5287382c1c526def3"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-win32.whl", hash = "sha256:c5328ed53fdb0a73c8a50105306a3bc013e5ca36cca714ec4f7bd31d38d8a97f"},
|
||||
{file = "frozenlist-1.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9ade70aea559ca98f4b1b1e5650c45678052e76a8ab2f76d90f2ac64180215a2"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0d3ffa8772464441b52489b985d46001e2853a3b082c655ec5fad9fb6a3d618"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3457f8cf86deb6ce1ba67e120f1b0128fcba1332a180722756597253c465fc1d"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a72eecf37eface331636951249d878750db84034927c997d47f7f78a573b72b"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:acc4614e8d1feb9f46dd829a8e771b8f5c4b1051365d02efb27a3229048ade8a"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:87521e32e18a2223311afc2492ef2d99946337da0779ddcda77b82ee7319df59"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b4c7665a17c3a5430edb663e4ad4e1ad457614d1b2f2b7f87052e2ef4fa45ca"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ed58803563a8c87cf4c0771366cf0ad1aa265b6b0ae54cbbb53013480c7ad74d"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa44c4740b4e23fcfa259e9dd52315d2b1770064cde9507457e4c4a65a04c397"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:2de5b931701257d50771a032bba4e448ff958076380b049fd36ed8738fdb375b"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6e105013fa84623c057a4381dc8ea0361f4d682c11f3816cc80f49a1f3bc17c6"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:705c184b77565955a99dc360f359e8249580c6b7eaa4dc0227caa861ef46b27a"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:a37594ad6356e50073fe4f60aa4187b97d15329f2138124d252a5a19c8553ea4"},
|
||||
{file = "frozenlist-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:25b358aaa7dba5891b05968dd539f5856d69f522b6de0bf34e61f133e077c1a4"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af2a51c8a381d76eabb76f228f565ed4c3701441ecec101dd18be70ebd483cfd"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:82d22f6e6f2916e837c91c860140ef9947e31194c82aaeda843d6551cec92f19"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cfe6fef507f8bac40f009c85c7eddfed88c1c0d38c75e72fe10476cef94e10f"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f602e380a5132880fa245c92030abb0fc6ff34e0c5500600366cedc6adb06a"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ad065b2ebd09f32511ff2be35c5dfafee6192978b5a1e9d279a5c6e121e3b03"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc93f5f62df3bdc1f677066327fc81f92b83644852a31c6aa9b32c2dde86ea7d"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:89fdfc84c6bf0bff2ff3170bb34ecba8a6911b260d318d377171429c4be18c73"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:47b2848e464883d0bbdcd9493c67443e5e695a84694efff0476f9059b4cb6257"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4f52d0732e56906f8ddea4bd856192984650282424049c956857fed43697ea43"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:16ef7dd5b7d17495404a2e7a49bac1bc13d6d20c16d11f4133c757dd94c4144c"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1cf63243bc5f5c19762943b0aa9e0d3fb3723d0c514d820a18a9b9a5ef864315"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:54a1e09ab7a69f843cd28fefd2bcaf23edb9e3a8d7680032c8968b8ac934587d"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:954b154a4533ef28bd3e83ffdf4eadf39deeda9e38fb8feaf066d6069885e034"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-win32.whl", hash = "sha256:cb3957c39668d10e2b486acc85f94153520a23263b6401e8f59422ef65b9520d"},
|
||||
{file = "frozenlist-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0a7c7cce70e41bc13d7d50f0e5dd175f14a4f1837a8549b0936ed0cbe6170bf9"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4c457220468d734e3077580a3642b7f682f5fd9507f17ddf1029452450912cdc"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e74f8b4d8677ebb4015ac01fcaf05f34e8a1f22775db1f304f497f2f88fdc697"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fbd4844ff111449f3bbe20ba24fbb906b5b1c2384d0f3287c9f7da2354ce6d23"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0081a623c886197ff8de9e635528fd7e6a387dccef432149e25c13946cb0cd0"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9b6e21e5770df2dea06cb7b6323fbc008b13c4a4e3b52cb54685276479ee7676"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:406aeb340613b4b559db78d86864485f68919b7141dec82aba24d1477fd2976f"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:878ebe074839d649a1cdb03a61077d05760624f36d196884a5cafb12290e187b"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1fef737fd1388f9b93bba8808c5f63058113c10f4e3c0763ced68431773f72f9"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4a495c3d513573b0b3f935bfa887a85d9ae09f0627cf47cad17d0cc9b9ba5c38"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e7d0dd3e727c70c2680f5f09a0775525229809f1a35d8552b92ff10b2b14f2c2"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:66a518731a21a55b7d3e087b430f1956a36793acc15912e2878431c7aec54210"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:94728f97ddf603d23c8c3dd5cae2644fa12d33116e69f49b1644a71bb77b89ae"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c1e8e9033d34c2c9e186e58279879d78c94dd365068a3607af33f2bc99357a53"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-win32.whl", hash = "sha256:83334e84a290a158c0c4cc4d22e8c7cfe0bba5b76d37f1c2509dabd22acafe15"},
|
||||
{file = "frozenlist-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:735f386ec522e384f511614c01d2ef9cf799f051353876b4c6fb93ef67a6d1ee"},
|
||||
{file = "frozenlist-1.2.0.tar.gz", hash = "sha256:68201be60ac56aff972dc18085800b6ee07973c49103a8aba669dee3d71079de"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:45334234ec30fc4ea677f43171b18a27505bfb2dba9aca4398a62692c0ea8868"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47be22dc27ed933d55ee55845d34a3e4e9f6fee93039e7f8ebadb0c2f60d403f"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03a7dd1bfce30216a3f51a84e6dd0e4a573d23ca50f0346634916ff105ba6e6b"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:691ddf6dc50480ce49f68441f1d16a4c3325887453837036e0fb94736eae1e58"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bde99812f237f79eaf3f04ebffd74f6718bbd216101b35ac7955c2d47c17da02"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a202458d1298ced3768f5a7d44301e7c86defac162ace0ab7434c2e961166e8"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9e3e9e365991f8cc5f5edc1fd65b58b41d0514a6a7ad95ef5c7f34eb49b3d3e"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:04cb491c4b1c051734d41ea2552fde292f5f3a9c911363f74f39c23659c4af78"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:436496321dad302b8b27ca955364a439ed1f0999311c393dccb243e451ff66aa"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:754728d65f1acc61e0f4df784456106e35afb7bf39cfe37227ab00436fb38676"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6eb275c6385dd72594758cbe96c07cdb9bd6becf84235f4a594bdf21e3596c9d"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-win32.whl", hash = "sha256:e30b2f9683812eb30cf3f0a8e9f79f8d590a7999f731cf39f9105a7c4a39489d"},
|
||||
{file = "frozenlist-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f7353ba3367473d1d616ee727945f439e027f0bb16ac1a750219a8344d1d5d3c"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88aafd445a233dbbf8a65a62bc3249a0acd0d81ab18f6feb461cc5a938610d24"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4406cfabef8f07b3b3af0f50f70938ec06d9f0fc26cbdeaab431cbc3ca3caeaa"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cf829bd2e2956066dd4de43fd8ec881d87842a06708c035b37ef632930505a2"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:603b9091bd70fae7be28bdb8aa5c9990f4241aa33abb673390a7f7329296695f"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25af28b560e0c76fa41f550eacb389905633e7ac02d6eb3c09017fa1c8cdfde1"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c7a8a9fc9383b52c410a2ec952521906d355d18fccc927fca52ab575ee8b93"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:65bc6e2fece04e2145ab6e3c47428d1bbc05aede61ae365b2c1bddd94906e478"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3f7c935c7b58b0d78c0beea0c7358e165f95f1fd8a7e98baa40d22a05b4a8141"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd89acd1b8bb4f31b47072615d72e7f53a948d302b7c1d1455e42622de180eae"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6983a31698490825171be44ffbafeaa930ddf590d3f051e397143a5045513b01"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:adac9700675cf99e3615eb6a0eb5e9f5a4143c7d42c05cea2e7f71c27a3d0846"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-win32.whl", hash = "sha256:0c36e78b9509e97042ef869c0e1e6ef6429e55817c12d78245eb915e1cca7468"},
|
||||
{file = "frozenlist-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:57f4d3f03a18facacb2a6bcd21bccd011e3b75d463dc49f838fd699d074fabd1"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8c905a5186d77111f02144fab5b849ab524f1e876a1e75205cd1386a9be4b00a"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5009062d78a8c6890d50b4e53b0ddda31841b3935c1937e2ed8c1bda1c7fb9d"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2fdc3cd845e5a1f71a0c3518528bfdbfe2efaf9886d6f49eacc5ee4fd9a10953"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92e650bd09b5dda929523b9f8e7f99b24deac61240ecc1a32aeba487afcd970f"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:40dff8962b8eba91fd3848d857203f0bd704b5f1fa2b3fc9af64901a190bba08"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:768efd082074bb203c934e83a61654ed4931ef02412c2fbdecea0cff7ecd0274"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:006d3595e7d4108a12025ddf415ae0f6c9e736e726a5db0183326fd191b14c5e"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:871d42623ae15eb0b0e9df65baeee6976b2e161d0ba93155411d58ff27483ad8"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aff388be97ef2677ae185e72dc500d19ecaf31b698986800d3fc4f399a5e30a5"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f892d6a94ec5c7b785e548e42722e6f3a52f5f32a8461e82ac3e67a3bd073f1"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:e982878792c971cbd60ee510c4ee5bf089a8246226dea1f2138aa0bb67aff148"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c6c321dd013e8fc20735b92cb4892c115f5cdb82c817b1e5b07f6b95d952b2f0"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:30530930410855c451bea83f7b272fb1c495ed9d5cc72895ac29e91279401db3"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-win32.whl", hash = "sha256:40ec383bc194accba825fbb7d0ef3dda5736ceab2375462f1d8672d9f6b68d07"},
|
||||
{file = "frozenlist-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:f20baa05eaa2bcd5404c445ec51aed1c268d62600362dc6cfe04fae34a424bd9"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0437fe763fb5d4adad1756050cbf855bbb2bf0d9385c7bb13d7a10b0dd550486"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b684c68077b84522b5c7eafc1dc735bfa5b341fb011d5552ebe0968e22ed641c"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93641a51f89473837333b2f8100f3f89795295b858cd4c7d4a1f18e299dc0a4f"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6d32ff213aef0fd0bcf803bffe15cfa2d4fde237d1d4838e62aec242a8362fa"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31977f84828b5bb856ca1eb07bf7e3a34f33a5cddce981d880240ba06639b94d"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c62964192a1c0c30b49f403495911298810bada64e4f03249ca35a33ca0417a"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4eda49bea3602812518765810af732229b4291d2695ed24a0a20e098c45a707b"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acb267b09a509c1df5a4ca04140da96016f40d2ed183cdc356d237286c971b51"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e1e26ac0a253a2907d654a37e390904426d5ae5483150ce3adedb35c8c06614a"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f96293d6f982c58ebebb428c50163d010c2f05de0cde99fd681bfdc18d4b2dc2"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e84cb61b0ac40a0c3e0e8b79c575161c5300d1d89e13c0e02f76193982f066ed"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:ff9310f05b9d9c5c4dd472983dc956901ee6cb2c3ec1ab116ecdde25f3ce4951"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d26b650b71fdc88065b7a21f8ace70175bcf3b5bdba5ea22df4bfd893e795a3b"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-win32.whl", hash = "sha256:01a73627448b1f2145bddb6e6c2259988bb8aee0fb361776ff8604b99616cd08"},
|
||||
{file = "frozenlist-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:772965f773757a6026dea111a15e6e2678fbd6216180f82a48a40b27de1ee2ab"},
|
||||
{file = "frozenlist-1.3.0.tar.gz", hash = "sha256:ce6f2ba0edb7b0c1d8976565298ad2deba6f8064d2bebb6ffce2ca896eb35b0b"},
|
||||
]
|
||||
geoip2 = [
|
||||
{file = "geoip2-4.5.0-py2.py3-none-any.whl", hash = "sha256:2aed03b45f8037b9e16f02567bcf3623801d6d20689c5fc5676d7c08ed067334"},
|
||||
@ -2588,20 +2568,20 @@ gitdb = [
|
||||
{file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"},
|
||||
]
|
||||
gitpython = [
|
||||
{file = "GitPython-3.1.24-py3-none-any.whl", hash = "sha256:dc0a7f2f697657acc8d7f89033e8b1ea94dd90356b2983bca89dc8d2ab3cc647"},
|
||||
{file = "GitPython-3.1.24.tar.gz", hash = "sha256:df83fdf5e684fef7c6ee2c02fc68a5ceb7e7e759d08b694088d0cacb4eba59e5"},
|
||||
{file = "GitPython-3.1.26-py3-none-any.whl", hash = "sha256:26ac35c212d1f7b16036361ca5cff3ec66e11753a0d677fb6c48fa4e1a9dd8d6"},
|
||||
{file = "GitPython-3.1.26.tar.gz", hash = "sha256:fc8868f63a2e6d268fb25f481995ba185a85a66fcad126f039323ff6635669ee"},
|
||||
]
|
||||
google-auth = [
|
||||
{file = "google-auth-2.3.3.tar.gz", hash = "sha256:d83570a664c10b97a1dc6f8df87e5fdfff012f48f62be131e449c20dfc32630e"},
|
||||
{file = "google_auth-2.3.3-py2.py3-none-any.whl", hash = "sha256:a348a50b027679cb7dae98043ac8dbcc1d7951f06d8387496071a1e05a2465c0"},
|
||||
{file = "google-auth-2.4.0.tar.gz", hash = "sha256:ef6f4827f6a3f9c5ff884616e2ba779acb5d690486fb70ca5e3091ed85ad932a"},
|
||||
{file = "google_auth-2.4.0-py2.py3-none-any.whl", hash = "sha256:d1fad279d9d97e7d6b4a09a53e851ab2ee6d36d5c19547354a3f47a8a6ae41b9"},
|
||||
]
|
||||
gunicorn = [
|
||||
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
|
||||
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
|
||||
]
|
||||
h11 = [
|
||||
{file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"},
|
||||
{file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"},
|
||||
{file = "h11-0.13.0-py3-none-any.whl", hash = "sha256:8ddd78563b633ca55346c8cd41ec0af27d3c79931828beffb46ce70a379e7442"},
|
||||
{file = "h11-0.13.0.tar.gz", hash = "sha256:70813c1135087a248a4d38cc0e1a0181ffab2188141a93eaf567940c3957ff06"},
|
||||
]
|
||||
hiredis = [
|
||||
{file = "hiredis-2.0.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b4c8b0bc5841e578d5fb32a16e0c305359b987b850a06964bd5a62739d688048"},
|
||||
@ -2685,8 +2665,8 @@ idna = [
|
||||
{file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
|
||||
]
|
||||
importlib-metadata = [
|
||||
{file = "importlib_metadata-4.10.0-py3-none-any.whl", hash = "sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4"},
|
||||
{file = "importlib_metadata-4.10.0.tar.gz", hash = "sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6"},
|
||||
{file = "importlib_metadata-4.10.1-py3-none-any.whl", hash = "sha256:899e2a40a8c4a1aec681feef45733de8a6c58f3f6a0dbed2eb6574b4387a77b6"},
|
||||
{file = "importlib_metadata-4.10.1.tar.gz", hash = "sha256:951f0d8a5b7260e9db5e41d429285b5f451e928479f19d80818878527d36e95e"},
|
||||
]
|
||||
incremental = [
|
||||
{file = "incremental-21.3.0-py2.py3-none-any.whl", hash = "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321"},
|
||||
@ -2709,8 +2689,8 @@ jmespath = [
|
||||
{file = "jmespath-0.10.0.tar.gz", hash = "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9"},
|
||||
]
|
||||
jsonschema = [
|
||||
{file = "jsonschema-4.3.3-py3-none-any.whl", hash = "sha256:eb7a69801beb7325653aa8fd373abbf9ff8f85b536ab2812e5e8287b522fb6a2"},
|
||||
{file = "jsonschema-4.3.3.tar.gz", hash = "sha256:f210d4ce095ed1e8af635d15c8ee79b586f656ab54399ba87b8ab87e5bff0ade"},
|
||||
{file = "jsonschema-4.4.0-py3-none-any.whl", hash = "sha256:77281a1f71684953ee8b3d488371b162419767973789272434bbc3f29d9c8823"},
|
||||
{file = "jsonschema-4.4.0.tar.gz", hash = "sha256:636694eb41b3535ed608fe04129f26542b59ed99808b4f688aa32dcf55317a83"},
|
||||
]
|
||||
kombu = [
|
||||
{file = "kombu-5.2.3-py3-none-any.whl", hash = "sha256:eeaeb8024f3a5cfc71c9250e45cddb8493f269d74ada2f74909a93c59c4b4179"},
|
||||
@ -2872,78 +2852,65 @@ msgpack = [
|
||||
{file = "msgpack-1.0.3.tar.gz", hash = "sha256:51fdc7fb93615286428ee7758cecc2f374d5ff363bdd884c7ea622a7a327a81e"},
|
||||
]
|
||||
multidict = [
|
||||
{file = "multidict-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3822c5894c72e3b35aae9909bef66ec83e44522faf767c0ad39e0e2de11d3b55"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:28e6d883acd8674887d7edc896b91751dc2d8e87fbdca8359591a13872799e4e"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b61f85101ef08cbbc37846ac0e43f027f7844f3fade9b7f6dd087178caedeee7"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9b668c065968c5979fe6b6fa6760bb6ab9aeb94b75b73c0a9c1acf6393ac3bf"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517d75522b7b18a3385726b54a081afd425d4f41144a5399e5abd97ccafdf36b"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1b4ac3ba7a97b35a5ccf34f41b5a8642a01d1e55454b699e5e8e7a99b5a3acf5"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:df23c83398715b26ab09574217ca21e14694917a0c857e356fd39e1c64f8283f"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e58a9b5cc96e014ddf93c2227cbdeca94b56a7eb77300205d6e4001805391747"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f76440e480c3b2ca7f843ff8a48dc82446b86ed4930552d736c0bac507498a52"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cfde464ca4af42a629648c0b0d79b8f295cf5b695412451716531d6916461628"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0fed465af2e0eb6357ba95795d003ac0bdb546305cc2366b1fc8f0ad67cc3fda"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:b70913cbf2e14275013be98a06ef4b412329fe7b4f83d64eb70dce8269ed1e1a"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5635bcf1b75f0f6ef3c8a1ad07b500104a971e38d3683167b9454cb6465ac86"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-win32.whl", hash = "sha256:77f0fb7200cc7dedda7a60912f2059086e29ff67cefbc58d2506638c1a9132d7"},
|
||||
{file = "multidict-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:9416cf11bcd73c861267e88aea71e9fcc35302b3943e45e1dbb4317f91a4b34f"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fd77c8f3cba815aa69cb97ee2b2ef385c7c12ada9c734b0f3b32e26bb88bbf1d"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98ec9aea6223adf46999f22e2c0ab6cf33f5914be604a404f658386a8f1fba37"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5283c0a00f48e8cafcecadebfa0ed1dac8b39e295c7248c44c665c16dc1138b"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f79c19c6420962eb17c7e48878a03053b7ccd7b69f389d5831c0a4a7f1ac0a1"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e4a67f1080123de76e4e97a18d10350df6a7182e243312426d508712e99988d4"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:94b117e27efd8e08b4046c57461d5a114d26b40824995a2eb58372b94f9fca02"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2e77282fd1d677c313ffcaddfec236bf23f273c4fba7cdf198108f5940ae10f5"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:116347c63ba049c1ea56e157fa8aa6edaf5e92925c9b64f3da7769bdfa012858"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:dc3a866cf6c13d59a01878cd806f219340f3e82eed514485e094321f24900677"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ac42181292099d91217a82e3fa3ce0e0ddf3a74fd891b7c2b347a7f5aa0edded"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:f0bb0973f42ffcb5e3537548e0767079420aefd94ba990b61cf7bb8d47f4916d"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-win32.whl", hash = "sha256:ea21d4d5104b4f840b91d9dc8cbc832aba9612121eaba503e54eaab1ad140eb9"},
|
||||
{file = "multidict-5.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:e6453f3cbeb78440747096f239d282cc57a2997a16b5197c9bc839099e1633d0"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3def943bfd5f1c47d51fd324df1e806d8da1f8e105cc7f1c76a1daf0f7e17b0"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35591729668a303a02b06e8dba0eb8140c4a1bfd4c4b3209a436a02a5ac1de11"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8cacda0b679ebc25624d5de66c705bc53dcc7c6f02a7fb0f3ca5e227d80422"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:baf1856fab8212bf35230c019cde7c641887e3fc08cadd39d32a421a30151ea3"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a43616aec0f0d53c411582c451f5d3e1123a68cc7b3475d6f7d97a626f8ff90d"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25cbd39a9029b409167aa0a20d8a17f502d43f2efebfe9e3ac019fe6796c59ac"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a2cbcfbea6dc776782a444db819c8b78afe4db597211298dd8b2222f73e9cd0"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d2d7d1fff8e09d99354c04c3fd5b560fb04639fd45926b34e27cfdec678a704"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a37e9a68349f6abe24130846e2f1d2e38f7ddab30b81b754e5a1fde32f782b23"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:637c1896497ff19e1ee27c1c2c2ddaa9f2d134bbb5e0c52254361ea20486418d"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9815765f9dcda04921ba467957be543423e5ec6a1136135d84f2ae092c50d87b"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-win32.whl", hash = "sha256:8b911d74acdc1fe2941e59b4f1a278a330e9c34c6c8ca1ee21264c51ec9b67ef"},
|
||||
{file = "multidict-5.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:380b868f55f63d048a25931a1632818f90e4be71d2081c2338fcf656d299949a"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e7d81ce5744757d2f05fc41896e3b2ae0458464b14b5a2c1e87a6a9d69aefaa8"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d1d55cdf706ddc62822d394d1df53573d32a7a07d4f099470d3cb9323b721b6"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4771d0d0ac9d9fe9e24e33bed482a13dfc1256d008d101485fe460359476065"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da7d57ea65744d249427793c042094c4016789eb2562576fb831870f9c878d9e"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdd68778f96216596218b4e8882944d24a634d984ee1a5a049b300377878fa7c"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ecc99bce8ee42dcad15848c7885197d26841cb24fa2ee6e89d23b8993c871c64"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:067150fad08e6f2dd91a650c7a49ba65085303fcc3decbd64a57dc13a2733031"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:78c106b2b506b4d895ddc801ff509f941119394b89c9115580014127414e6c2d"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e6c4fa1ec16e01e292315ba76eb1d012c025b99d22896bd14a66628b245e3e01"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b227345e4186809d31f22087d0265655114af7cda442ecaf72246275865bebe4"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:06560fbdcf22c9387100979e65b26fba0816c162b888cb65b845d3def7a54c9b"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7878b61c867fb2df7a95e44b316f88d5a3742390c99dfba6c557a21b30180cac"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:246145bff76cc4b19310f0ad28bd0769b940c2a49fc601b86bfd150cbd72bb22"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-win32.whl", hash = "sha256:c30ac9f562106cd9e8071c23949a067b10211917fdcb75b4718cf5775356a940"},
|
||||
{file = "multidict-5.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:f19001e790013ed580abfde2a4465388950728861b52f0da73e8e8a9418533c0"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c1ff762e2ee126e6f1258650ac641e2b8e1f3d927a925aafcfde943b77a36d24"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd6c9c50bf2ad3f0448edaa1a3b55b2e6866ef8feca5d8dbec10ec7c94371d21"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc66d4016f6e50ed36fb39cd287a3878ffcebfa90008535c62e0e90a7ab713ae"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9acb76d5f3dd9421874923da2ed1e76041cb51b9337fd7f507edde1d86535d6"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dfc924a7e946dd3c6360e50e8f750d51e3ef5395c95dc054bc9eab0f70df4f9c"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32fdba7333eb2351fee2596b756d730d62b5827d5e1ab2f84e6cbb287cc67fe0"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b9aad49466b8d828b96b9e3630006234879c8d3e2b0a9d99219b3121bc5cdb17"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:93de39267c4c676c9ebb2057e98a8138bade0d806aad4d864322eee0803140a0"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f9bef5cff994ca3026fcc90680e326d1a19df9841c5e3d224076407cc21471a1"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5f841c4f14331fd1e36cbf3336ed7be2cb2a8f110ce40ea253e5573387db7621"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:38ba256ee9b310da6a1a0f013ef4e422fca30a685bcbec86a969bd520504e341"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3bc3b1621b979621cee9f7b09f024ec76ec03cc365e638126a056317470bde1b"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6ee908c070020d682e9b42c8f621e8bb10c767d04416e2ebe44e37d0f44d9ad5"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-win32.whl", hash = "sha256:1c7976cd1c157fa7ba5456ae5d31ccdf1479680dc9b8d8aa28afabc370df42b8"},
|
||||
{file = "multidict-5.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:c9631c642e08b9fff1c6255487e62971d8b8e821808ddd013d8ac058087591ac"},
|
||||
{file = "multidict-5.2.0.tar.gz", hash = "sha256:0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05c3cca447fd39b566615d7cf918f0e83cd92f0549f8182a6cab6e4729c02566"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b487ad10f594e78e0e61662ff7643e1adc610919ea8a95dd976126bffc0256f"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d65b5bd50a5e1f4c6427ebcabb5acc62540301de733f81fd549cf7633826fccd"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a542ceca143e19c08715defe133475961d43d7bfb48dbdc3ac506548ec168f18"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af441cfeb3003d96de8acdeb402187bc6a34f96e125618b8275bacfd29a6fad7"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f97f03d7dbc33e20a73428be93974e82762b393579d59053da1257c35bad13b"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c74c7a058a16b7dd24d030f0e8fe846f7d63f41cfeea89a804969cb129182a8"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5210e5eca8f0fc0213da31cbc29587d15195b21f40ffd53ff513126c39be0e2"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:af1fdc8d25eb9e9998854e996bc982ae3be733590a9e8d6b179b28fd212ddf71"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf0aaaef2f8a4cf1973ebe17162b0c3016859eb706d55b328993b8fd8c3515c"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:1354127c9687d0abbaadfb26e35db247ef1c35f0271e8052afa98b34a9140445"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2e82ac157bc0719b9802578964d4387e0d7dd530d1fd8949f3cef1c97f2e9d8a"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2f90eb274732fe0958f2d9d4cc7a608bf218e63dd554a690ccafa30f9d9d1b2d"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-win32.whl", hash = "sha256:593586d7ac76ab7a9f229c49d81136b8c1a78119d948ba2a672f4fa681ad54ce"},
|
||||
{file = "multidict-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:f24b3d4405271d6d1b920261437f3acb7dd1c329b0ac782b8b4e0ee7ad187e5b"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9050a2487f9dee9b0abde090b2620a3ba57190d7fe1dc2932b32b9866f90df9e"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff8004ecfb2cc00cd4f063c5e8b3cfd7e544bf774f17c2a861067444532e4fbc"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b944477c1e7be8bea2ef819157fb01b79493af1a6dba83d315be63db2957af6"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70a5fff576fe9039550f8d6aacaa98ce26c41df97edc577688c563eb25bcbe83"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e545e5922a4ae99e680a96ed88d03007bd4208fc2599ff273eb2086051d3ef74"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502c1610c7737697108ba4717274cca01130ce3e23227034b1601fb9fa0a8aa"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:caa9f2874519e0fbb19b90380532e59ef9e07d8ed22d8f0e2e69af796bae2c78"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7c9213754993e0dcf70a4fffebef502daf9323fa8d56f0485f724bd4c2991667"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:0a9857789fd76e0394a5373598820bb2ea3dd113e2c0fb9a92248e3dadd81c5c"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:92ba0e4745937efef33399348f62a2dc98505dde4d0764061a34123a55fe02e9"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3424df56debab711f29c965cadb835dc3c702930265eae26f15ac784feb1dddd"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:d13af99bf380567ede69927d3188cfaccfde76e78e336151e42e60fe03ca5c00"},
|
||||
{file = "multidict-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:37228376057f37fb013130e83e7ad0921598760fb75bd8f0da17403390241d20"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1b469534be490ded141d74d7a158db284055b0d04991c2634a9d26d906e063dd"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6ee83096d27dfe52075385f5067d2a54fb227b41666b207e6a64f98ce9048266"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19c9c56ddca200f7ffbf376cf2d1a370e8f2e306ec16510a4d90b78a1a0be62"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a6da1575300e24011352c7c620d19b072a2c9498429d1f587e5090621e6f568"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48e0919ed5cc5e58c68f40b6516e3f1b0837580a7a8d51d9f99bf0f415d0b73a"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7c10ab3a1ad3188d9a4be01a10c0ddb67d6feaaea538781e73d6ba69fcafbbd"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17289c1ad70e1104ea25f560f6e2941718112d59616482589646aa01fcf4d0d1"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a701e9ad52e47b740b5b9aba627ac8fc4ee9e68682f0228fb4a7c4562631ffac"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:798dd2d825ce6c0699ce261fda90020562236480192604cfc5be4a315f806810"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:564ff7d88b4965cb5211ebf785bca409abbaac8dcca62b0fabe39d56a5ee7283"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:39d5424379505110d6ca64e927f8b2772c57b05a3d240e66805244ecc4402311"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:efeba14caaacb4a202d977aca63866069e8a57e632282caf971ce8ff472a49cd"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:241071469989c87da1835f3ccc4143a207b99a2ca27c19b7130a5edecc41a39e"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-win32.whl", hash = "sha256:7184dae6d519a8e629ef10e0e215dde022ee38d55254bea381ca0e61b8b197ea"},
|
||||
{file = "multidict-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:666f78daccf8133ebfacb77e81f4077570b03641b49555ebb5e75797b72770e1"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5a4fcf74d50a65fe99a68531d09f10ceef911992e0e64c1b2cf212effa075f8b"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4a98ee92e96157a3c787c5aa156968ceffb6fb4548c5f74ff879884fed2f9752"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b6bfb0a4df79bd78907fff46c34ed47284d5eb459b096d2de896b0b1c31f3fa7"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbda7f3be5a75ee87a2649382e47f419374420ef244b372312e662637931399f"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f74a680ba9d6c543c1cdd8bcef464d58b933bed29edb89a0b3c0b33cc553181a"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:389a689aa3b657b87cb21f78468caa4dfccd758639ff4b37b6e2dceef7c5b12f"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36195396f2a76dd23a67ca2bdeb8589b6eaaef7e84c97cf90da3ede69f189baa"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02847aa3602e21c04ac6fdef6f7c6dc916de8cce49a9eb59aeffedd3365f196c"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bd21540c9cc9b90373b5a6aaed8f8d53815529e89210453e0566d00389034b82"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e037782357ddf6741023df1a84f17a3a1bb62abba52e41efa4014199f6338143"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ea08fb7383422148bcfc066c3d2dae03fcdb8bd06e7ce713badd86bc26c25179"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:b85354b2d2fe38a3ab90348f8c9778a437d376252f62115cabea1106332bd1b6"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9c863a506466d64871c70e4204cecdcaf2c0c92d157683bb5d5b3e7b5aaea05a"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-win32.whl", hash = "sha256:d2cc15d2507b0d5f09726fd97bb9ffaa6bb47487fe77a208262cb6187fd9dcf3"},
|
||||
{file = "multidict-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:38ada537db7f9089560cf16dc5b8b280096213bc5260970929aca43675682739"},
|
||||
{file = "multidict-6.0.1.tar.gz", hash = "sha256:d40616f3f9326a18e1f2fa7c7e8e0e04a7e5228bfa2bd62c1e0d68fbc259b09b"},
|
||||
]
|
||||
mypy-extensions = [
|
||||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||
@ -2962,8 +2929,8 @@ packaging = [
|
||||
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
|
||||
]
|
||||
paramiko = [
|
||||
{file = "paramiko-2.9.1-py2.py3-none-any.whl", hash = "sha256:db5d3f19607941b1c90233588d60213c874392c4961c6297037da989c24f8070"},
|
||||
{file = "paramiko-2.9.1.tar.gz", hash = "sha256:a1fdded3b55f61d23389e4fe52d9ae428960ac958d2edf50373faa5d8926edd0"},
|
||||
{file = "paramiko-2.9.2-py2.py3-none-any.whl", hash = "sha256:04097dbd96871691cdb34c13db1883066b8a13a0df2afd4cb0a92221f51c2603"},
|
||||
{file = "paramiko-2.9.2.tar.gz", hash = "sha256:944a9e5dbdd413ab6c7951ea46b0ab40713235a9c4c5ca81cfe45c6f14fa677b"},
|
||||
]
|
||||
pathspec = [
|
||||
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
|
||||
@ -3086,36 +3053,36 @@ pycparser = [
|
||||
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||
]
|
||||
pycryptodome = [
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:90ad3381ccdc6a24cc2841e295706a168f32abefe64c679695712acac71fd5da"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e80f7469b0b3ea0f694230477d8501dc5a30a717e94fddd4821e6721f3053eae"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:b91404611767a7485837a6f1fd20cf9a5ae0ad362040a022cd65827ecb1b0d00"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:db66ccda65d5d20c17b00768e462a86f6f540f9aea8419a7f76cc7d9effd82cd"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:dc88355c4b261ed259268e65705b28b44d99570337694d593f06e3b1698eaaf3"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:6f8f5b7b53516da7511951910ab458e799173722c91fea54e2ba2f56d102e4aa"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27m-win32.whl", hash = "sha256:93acad54a72d81253242eb0a15064be559ec9d989e5173286dc21cad19f01765"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27m-win_amd64.whl", hash = "sha256:5a8c24d39d4a237dbfe181ea6593792bf9b5582c7fcfa7b8e0e12fda5eec07af"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:32d15da81959faea6cbed95df2bb44f7f796211c110cf90b5ad3b2aeeb97fc8e"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:aed7eb4b64c600fbc5e6d4238991ad1b4179a558401f203d1fcbd24883748982"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:341c6bbf932c406b4f3ee2372e8589b67ac0cf4e99e7dc081440f43a3cde9f0f"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:de0b711d673904dd6c65307ead36cb76622365a393569bf880895cba21195b7a"},
|
||||
{file = "pycryptodome-3.12.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:3558616f45d8584aee3eba27559bc6fd0ba9be6c076610ed3cc62bd5229ffdc3"},
|
||||
{file = "pycryptodome-3.12.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a78e4324e566b5fbc2b51e9240950d82fa9e1c7eb77acdf27f58712f65622c1d"},
|
||||
{file = "pycryptodome-3.12.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:3f2f3dd596c6128d91314e60a6bcf4344610ef0e97f4ae4dd1770f86dd0748d8"},
|
||||
{file = "pycryptodome-3.12.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:e05f994f30f1cda3cbe57441f41220d16731cf99d868bb02a8f6484c454c206b"},
|
||||
{file = "pycryptodome-3.12.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:4cded12e13785bbdf4ba1ff5fb9d261cd98162145f869e4fbc4a4b9083392f0b"},
|
||||
{file = "pycryptodome-3.12.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:1181c90d1a6aee68a84826825548d0db1b58d8541101f908d779d601d1690586"},
|
||||
{file = "pycryptodome-3.12.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:6bb0d340c93bcb674ea8899e2f6408ec64c6c21731a59481332b4b2a8143cc60"},
|
||||
{file = "pycryptodome-3.12.0-cp35-abi3-win32.whl", hash = "sha256:39da5807aa1ff820799c928f745f89432908bf6624b9e981d2d7f9e55d91b860"},
|
||||
{file = "pycryptodome-3.12.0-cp35-abi3-win_amd64.whl", hash = "sha256:212c7f7fe11cad9275fbcff50ca977f1c6643f13560d081e7b0f70596df447b8"},
|
||||
{file = "pycryptodome-3.12.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:b07a4238465eb8c65dd5df2ab8ba6df127e412293c0ed7656c003336f557a100"},
|
||||
{file = "pycryptodome-3.12.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:a6e1bcd9d5855f1a3c0f8d585f44c81b08f39a02754007f374fb8db9605ba29c"},
|
||||
{file = "pycryptodome-3.12.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:aceb1d217c3a025fb963849071446cf3aca1353282fe1c3cb7bd7339a4d47947"},
|
||||
{file = "pycryptodome-3.12.0-pp27-pypy_73-win32.whl", hash = "sha256:f699360ae285fcae9c8f53ca6acf33796025a82bb0ccd7c1c551b04c1726def3"},
|
||||
{file = "pycryptodome-3.12.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d845c587ceb82ac7cbac7d0bf8c62a1a0fe7190b028b322da5ca65f6e5a18b9e"},
|
||||
{file = "pycryptodome-3.12.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:d8083de50f6dec56c3c6f270fb193590999583a1b27c9c75bc0b5cac22d438cc"},
|
||||
{file = "pycryptodome-3.12.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:9ea2f6674c803602a7c0437fccdc2ea036707e60456974fe26ca263bd501ec45"},
|
||||
{file = "pycryptodome-3.12.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:5d4264039a2087977f50072aaff2346d1c1c101cb359f9444cf92e3d1f42b4cd"},
|
||||
{file = "pycryptodome-3.12.0.zip", hash = "sha256:12c7343aec5a3b3df5c47265281b12b611f26ec9367b6129199d67da54b768c1"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e468724173df02f9d83f3fea830bf0d04aa291b5add22b4a78e01c97aab04873"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1fb7a6f222072412f320b9e48d3ce981920efbfce37b06d028ec9bd94093b37f"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4f1b594d0cf35bd12ec4244df1155a7f565bf6e6245976ac36174c1564688c90"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9ea70f6c3f6566159e3798e4593a4a8016994a0080ac29a45200615b45091a1b"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f7aad304575d075faf2806977b726b67da7ba294adc97d878f92a062e357a56a"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:702446a012fd9337b9327d168bb0c7dc714eb93ad361f6f61af9ca8305a301f1"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27m-win32.whl", hash = "sha256:681ac47c538c64305d710eaed2bb49532f62b3f4c93aa7c423c520df981392e5"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27m-win_amd64.whl", hash = "sha256:7b3478a187d897f003b2aa1793bcc59463e8d57a42e2aafbcbbe9cd47ec46863"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:eec02d9199af4b1ccfe1f9c587691a07a1fa39d949d2c1dc69d079ab9af8212f"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9c8e0e6c5e982699801b20fa74f43c19aa080d2b53a39f3c132d35958e153bd4"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f5457e44d3f26d9946091e92b28f3e970a56538b96c87b4b155a84e32a40b7b5"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:88d6d54e83cf9bbd665ce1e7b9079983ee2d97a05f42e0569ff00a70f1dd8b1e"},
|
||||
{file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:72de8c4d71e6b11d54528bb924447fa4fdabcbb3d76cc0e7f61d3b6075def6b3"},
|
||||
{file = "pycryptodome-3.13.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:008ef2c631f112cd5a58736e0b29f4a28b4bb853e68878689f8b476fd56e0691"},
|
||||
{file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:51ebe9624ad0a0b4da1aaaa2d43aabadf8537737fd494cee0ffa37cd6326de02"},
|
||||
{file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:deede160bdf87ddb71f0a1314ad5a267b1a960be314ea7dc6b7ad86da6da89a3"},
|
||||
{file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:857c16bffd938254e3a834cd6b2a755ed24e1a953b1a86e33da136d3e4c16a6f"},
|
||||
{file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:ca6db61335d07220de0b665bfee7b8e9615b2dfc67a54016db4826dac34c2dd2"},
|
||||
{file = "pycryptodome-3.13.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:073dedf0f9c490ae22ca081b86357646ac9b76f3e2bd89119d137fc697a9e3b6"},
|
||||
{file = "pycryptodome-3.13.0-cp35-abi3-win32.whl", hash = "sha256:e3affa03c49cce7b0a9501cc7f608d4f8e61fb2522b276d599ac049b5955576d"},
|
||||
{file = "pycryptodome-3.13.0-cp35-abi3-win_amd64.whl", hash = "sha256:e5d72be02b17e6bd7919555811264403468d1d052fa67c946e402257c3c29a27"},
|
||||
{file = "pycryptodome-3.13.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:0896d5d15ffe584d46cb9b69a75cf14a2bc8f6daf635b7bf16c1b041342a44b1"},
|
||||
{file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:e420cdfca73f80fe15f79bb34756959945231a052440813e5fce531e6e96331a"},
|
||||
{file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:720fafdf3e5c5de93039d8308f765cc60b8e9e7e852ad7135aa65dd89238191f"},
|
||||
{file = "pycryptodome-3.13.0-pp27-pypy_73-win32.whl", hash = "sha256:7a8b0e526ff239b4f4c61dd6898e2474d609843ffc437267f3a27ddff626e6f6"},
|
||||
{file = "pycryptodome-3.13.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d92a5eddffb0ad39f582f07c1de26e9daf6880e3e782a94bb7ebaf939567f8bf"},
|
||||
{file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:cb9453c981554984c6f5c5ce7682d7286e65e2173d7416114c3593a977a01bf5"},
|
||||
{file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:765b8b16bc1fd699e183dde642c7f2653b8f3c9c1a50051139908e9683f97732"},
|
||||
{file = "pycryptodome-3.13.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:b3af53dddf848afb38b3ac2bae7159ddad1feb9bac14aa3acec6ef1797b82f8d"},
|
||||
{file = "pycryptodome-3.13.0.tar.gz", hash = "sha256:95bacf9ff7d1b90bba537d3f5f6c834efe6bfbb1a0195cb3573f29e6716ef08d"},
|
||||
]
|
||||
pyjwt = [
|
||||
{file = "PyJWT-2.3.0-py3-none-any.whl", hash = "sha256:e0c4bb8d9f0af0c7f5b1ec4c5036309617d03d56932877f2f7a0beeb5318322f"},
|
||||
@ -3134,55 +3101,47 @@ pylint-plugin-utils = [
|
||||
{file = "pylint_plugin_utils-0.7-py3-none-any.whl", hash = "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535"},
|
||||
]
|
||||
pynacl = [
|
||||
{file = "PyNaCl-1.4.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff"},
|
||||
{file = "PyNaCl-1.4.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514"},
|
||||
{file = "PyNaCl-1.4.0-cp27-cp27m-win32.whl", hash = "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574"},
|
||||
{file = "PyNaCl-1.4.0-cp27-cp27m-win_amd64.whl", hash = "sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80"},
|
||||
{file = "PyNaCl-1.4.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7"},
|
||||
{file = "PyNaCl-1.4.0-cp35-abi3-macosx_10_10_x86_64.whl", hash = "sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122"},
|
||||
{file = "PyNaCl-1.4.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d"},
|
||||
{file = "PyNaCl-1.4.0-cp35-abi3-win32.whl", hash = "sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634"},
|
||||
{file = "PyNaCl-1.4.0-cp35-abi3-win_amd64.whl", hash = "sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6"},
|
||||
{file = "PyNaCl-1.4.0-cp35-cp35m-win32.whl", hash = "sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4"},
|
||||
{file = "PyNaCl-1.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25"},
|
||||
{file = "PyNaCl-1.4.0-cp36-cp36m-win32.whl", hash = "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4"},
|
||||
{file = "PyNaCl-1.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6"},
|
||||
{file = "PyNaCl-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f"},
|
||||
{file = "PyNaCl-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f"},
|
||||
{file = "PyNaCl-1.4.0-cp38-cp38-win32.whl", hash = "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96"},
|
||||
{file = "PyNaCl-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420"},
|
||||
{file = "PyNaCl-1.4.0.tar.gz", hash = "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"},
|
||||
{file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"},
|
||||
{file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"},
|
||||
]
|
||||
pyopenssl = [
|
||||
{file = "pyOpenSSL-21.0.0-py2.py3-none-any.whl", hash = "sha256:8935bd4920ab9abfebb07c41a4f58296407ed77f04bd1a92914044b848ba1ed6"},
|
||||
{file = "pyOpenSSL-21.0.0.tar.gz", hash = "sha256:5e2d8c5e46d0d865ae933bef5230090bdaf5506281e9eec60fa250ee80600cb3"},
|
||||
]
|
||||
pyparsing = [
|
||||
{file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"},
|
||||
{file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"},
|
||||
{file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"},
|
||||
{file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"},
|
||||
]
|
||||
pyrsistent = [
|
||||
{file = "pyrsistent-0.18.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f4c8cabb46ff8e5d61f56a037974228e978f26bfefce4f61a4b1ac0ba7a2ab72"},
|
||||
{file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:da6e5e818d18459fa46fac0a4a4e543507fe1110e808101277c5a2b5bab0cd2d"},
|
||||
{file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5e4395bbf841693eaebaa5bb5c8f5cdbb1d139e07c975c682ec4e4f8126e03d2"},
|
||||
{file = "pyrsistent-0.18.0-cp36-cp36m-win32.whl", hash = "sha256:527be2bfa8dc80f6f8ddd65242ba476a6c4fb4e3aedbf281dfbac1b1ed4165b1"},
|
||||
{file = "pyrsistent-0.18.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2aaf19dc8ce517a8653746d98e962ef480ff34b6bc563fc067be6401ffb457c7"},
|
||||
{file = "pyrsistent-0.18.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58a70d93fb79dc585b21f9d72487b929a6fe58da0754fa4cb9f279bb92369396"},
|
||||
{file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4916c10896721e472ee12c95cdc2891ce5890898d2f9907b1b4ae0f53588b710"},
|
||||
{file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:73ff61b1411e3fb0ba144b8f08d6749749775fe89688093e1efef9839d2dcc35"},
|
||||
{file = "pyrsistent-0.18.0-cp37-cp37m-win32.whl", hash = "sha256:b29b869cf58412ca5738d23691e96d8aff535e17390128a1a52717c9a109da4f"},
|
||||
{file = "pyrsistent-0.18.0-cp37-cp37m-win_amd64.whl", hash = "sha256:097b96f129dd36a8c9e33594e7ebb151b1515eb52cceb08474c10a5479e799f2"},
|
||||
{file = "pyrsistent-0.18.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:772e94c2c6864f2cd2ffbe58bb3bdefbe2a32afa0acb1a77e472aac831f83427"},
|
||||
{file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c1a9ff320fa699337e05edcaae79ef8c2880b52720bc031b219e5b5008ebbdef"},
|
||||
{file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cd3caef37a415fd0dae6148a1b6957a8c5f275a62cca02e18474608cb263640c"},
|
||||
{file = "pyrsistent-0.18.0-cp38-cp38-win32.whl", hash = "sha256:e79d94ca58fcafef6395f6352383fa1a76922268fa02caa2272fff501c2fdc78"},
|
||||
{file = "pyrsistent-0.18.0-cp38-cp38-win_amd64.whl", hash = "sha256:a0c772d791c38bbc77be659af29bb14c38ced151433592e326361610250c605b"},
|
||||
{file = "pyrsistent-0.18.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d5ec194c9c573aafaceebf05fc400656722793dac57f254cd4741f3c27ae57b4"},
|
||||
{file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:6b5eed00e597b5b5773b4ca30bd48a5774ef1e96f2a45d105db5b4ebb4bca680"},
|
||||
{file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:48578680353f41dca1ca3dc48629fb77dfc745128b56fc01096b2530c13fd426"},
|
||||
{file = "pyrsistent-0.18.0-cp39-cp39-win32.whl", hash = "sha256:f3ef98d7b76da5eb19c37fda834d50262ff9167c65658d1d8f974d2e4d90676b"},
|
||||
{file = "pyrsistent-0.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:404e1f1d254d314d55adb8d87f4f465c8693d6f902f67eb6ef5b4526dc58e6ea"},
|
||||
{file = "pyrsistent-0.18.0.tar.gz", hash = "sha256:773c781216f8c2900b42a7b638d5b517bb134ae1acbebe4d1e8f1f41ea60eb4b"},
|
||||
{file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"},
|
||||
{file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"},
|
||||
{file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"},
|
||||
{file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"},
|
||||
{file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"},
|
||||
{file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"},
|
||||
{file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"},
|
||||
{file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"},
|
||||
{file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"},
|
||||
{file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"},
|
||||
{file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"},
|
||||
{file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"},
|
||||
{file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"},
|
||||
{file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"},
|
||||
{file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"},
|
||||
{file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"},
|
||||
{file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"},
|
||||
{file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"},
|
||||
{file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"},
|
||||
{file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"},
|
||||
{file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"},
|
||||
]
|
||||
pytest = [
|
||||
{file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
|
||||
@ -3193,8 +3152,8 @@ pytest-django = [
|
||||
{file = "pytest_django-4.5.2-py3-none-any.whl", hash = "sha256:c60834861933773109334fe5a53e83d1ef4828f2203a1d6a0fa9972f4f75ab3e"},
|
||||
]
|
||||
pytest-randomly = [
|
||||
{file = "pytest-randomly-3.10.3.tar.gz", hash = "sha256:22154cdcff7ba44e0599596490e6b75278ca973a33812ea6a54bf14d0b042ef1"},
|
||||
{file = "pytest_randomly-3.10.3-py3-none-any.whl", hash = "sha256:b05a7a45f54cae2b5095752c6a10cb559df84448421b0420ae492dd2fb1727ef"},
|
||||
{file = "pytest-randomly-3.11.0.tar.gz", hash = "sha256:9f013b8c1923130f3d0a286fde56e1fc52cfb3547b8eedf2765c460cee979c7f"},
|
||||
{file = "pytest_randomly-3.11.0-py3-none-any.whl", hash = "sha256:a3c680d2b8150cf766311a80a1f92da64c3dd819045cda834fbf1b0ac4891610"},
|
||||
]
|
||||
python-dateutil = [
|
||||
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
||||
@ -3258,8 +3217,8 @@ pyyaml = [
|
||||
{file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
|
||||
]
|
||||
redis = [
|
||||
{file = "redis-4.1.0-py3-none-any.whl", hash = "sha256:e13fad67c098a33141bacde872786960e86a5c97a4255009bcd43c795fa1cc77"},
|
||||
{file = "redis-4.1.0.tar.gz", hash = "sha256:21f0a23bce707909076e6ba2ce076cba59bff60d2ab22972e0647fdf620ffe47"},
|
||||
{file = "redis-4.1.1-py3-none-any.whl", hash = "sha256:bc97d18938ca18d66737d0ef88584a2073069589e4026813cfba9ad6df9a9f40"},
|
||||
{file = "redis-4.1.1.tar.gz", hash = "sha256:07420a3fbedd8e012c31d4fadac943fb81568946da202c5a5bc237774e5280a0"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
|
||||
@ -3285,7 +3244,10 @@ s3transfer = [
|
||||
selenium = [
|
||||
{file = "selenium-4.1.0-py3-none-any.whl", hash = "sha256:27e7b64df961d609f3d57237caa0df123abbbe22d038f2ec9e332fb90ec1a939"},
|
||||
]
|
||||
sentry-sdk = []
|
||||
sentry-sdk = [
|
||||
{file = "sentry-sdk-1.5.3.tar.gz", hash = "sha256:141da032f0fa4c56f9af6b361fda57360af1789576285bd1944561f9c274f9c0"},
|
||||
{file = "sentry_sdk-1.5.3-py2.py3-none-any.whl", hash = "sha256:9aeff2a47f4038460296b920bf4d269284e8454e1c67547ee002ccafd9c2442b"},
|
||||
]
|
||||
service-identity = [
|
||||
{file = "service-identity-21.1.0.tar.gz", hash = "sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34"},
|
||||
{file = "service_identity-21.1.0-py2.py3-none-any.whl", hash = "sha256:f0b0caac3d40627c3c04d7a51b6e06721857a0e10a8775f2d1d7e72901b3a7db"},
|
||||
@ -3420,12 +3382,12 @@ uritemplate = [
|
||||
{file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"},
|
||||
]
|
||||
urllib3 = [
|
||||
{file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"},
|
||||
{file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"},
|
||||
{file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"},
|
||||
{file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"},
|
||||
]
|
||||
uvicorn = [
|
||||
{file = "uvicorn-0.16.0-py3-none-any.whl", hash = "sha256:d8c839231f270adaa6d338d525e2652a0b4a5f4c2430b5c4ef6ae4d11776b0d2"},
|
||||
{file = "uvicorn-0.16.0.tar.gz", hash = "sha256:eacb66afa65e0648fcbce5e746b135d09722231ffffc61883d4fac2b62fbea8d"},
|
||||
{file = "uvicorn-0.17.0-py3-none-any.whl", hash = "sha256:0b89c91bb8fe84c4bded9996af13c4b8c0de799d29bffeaa0c8ad298f2be0934"},
|
||||
{file = "uvicorn-0.17.0.tar.gz", hash = "sha256:192c2422b056a3beb512c6c260bf77a7a884204a4ae41856719c1913ead63bbb"},
|
||||
]
|
||||
uvloop = [
|
||||
{file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"},
|
||||
@ -3458,8 +3420,8 @@ wcwidth = [
|
||||
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
|
||||
]
|
||||
webauthn = [
|
||||
{file = "webauthn-1.2.0-py3-none-any.whl", hash = "sha256:ecae0f99a6dc1a6d53e72f4be323cf58b418c02fe66dffae752eedc1d2ee6a70"},
|
||||
{file = "webauthn-1.2.0.tar.gz", hash = "sha256:681b71d803c085d0911e29f2e2bbb0e49feda1ecdaa3982bae3d63b3377efdda"},
|
||||
{file = "webauthn-1.2.1-py3-none-any.whl", hash = "sha256:024d0c54d1a11a1d95587745a0fea721cdb39ddc591ad0973bf93f55a123eb74"},
|
||||
{file = "webauthn-1.2.1.tar.gz", hash = "sha256:3a9565e4587d6322a2c69c92faa89f40e211893f41b5993a410cdef7bc43d06b"},
|
||||
]
|
||||
websocket-client = [
|
||||
{file = "websocket-client-1.2.3.tar.gz", hash = "sha256:1315816c0acc508997eb3ae03b9d3ff619c9d12d544c9a9b553704b1cc4f6af5"},
|
||||
|
||||
@ -7,7 +7,7 @@ ENV NODE_ENV=production
|
||||
RUN cd /static && npm i && npm run build-proxy
|
||||
|
||||
# Stage 2: Build
|
||||
FROM docker.io/golang:1.17.5-bullseye AS builder
|
||||
FROM docker.io/golang:1.17.6-bullseye AS builder
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
|
||||
@ -92,7 +92,7 @@ addopts = "-p no:celery --junitxml=unittest.xml"
|
||||
|
||||
[tool.poetry]
|
||||
name = "authentik"
|
||||
version = "2021.12.5"
|
||||
version = "2022.1.2"
|
||||
description = ""
|
||||
authors = ["Jens Langhammer <jens.langhammer@beryju.org>"]
|
||||
|
||||
@ -135,7 +135,7 @@ pyjwt = "*"
|
||||
python = "^3.10"
|
||||
pyyaml = "*"
|
||||
requests-oauthlib = "*"
|
||||
sentry-sdk = { git = 'https://github.com/beryju/sentry-python.git', rev = '379aee28b15d3b87b381317746c4efd24b3d7bc3' }
|
||||
sentry-sdk = "*"
|
||||
service_identity = "*"
|
||||
structlog = "*"
|
||||
swagger-spec-validator = "*"
|
||||
|
||||
48
schema.yml
48
schema.yml
@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: authentik
|
||||
version: 2021.12.5
|
||||
version: 2022.1.2
|
||||
description: Making authentication simple.
|
||||
contact:
|
||||
email: hello@beryju.org
|
||||
@ -15270,6 +15270,14 @@ paths:
|
||||
operationId: stages_authenticator_webauthn_list
|
||||
description: AuthenticateWebAuthnStage Viewset
|
||||
parameters:
|
||||
- in: query
|
||||
name: authenticator_attachment
|
||||
schema:
|
||||
type: string
|
||||
nullable: true
|
||||
enum:
|
||||
- cross-platform
|
||||
- platform
|
||||
- in: query
|
||||
name: configure_flow
|
||||
schema:
|
||||
@ -15297,6 +15305,14 @@ paths:
|
||||
description: Number of results to return per page.
|
||||
schema:
|
||||
type: integer
|
||||
- in: query
|
||||
name: resident_key_requirement
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- discouraged
|
||||
- preferred
|
||||
- required
|
||||
- name: search
|
||||
required: false
|
||||
in: query
|
||||
@ -19174,6 +19190,12 @@ components:
|
||||
If empty, user will not be able to configure this stage.
|
||||
user_verification:
|
||||
$ref: '#/components/schemas/UserVerificationEnum'
|
||||
authenticator_attachment:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AuthenticatorAttachmentEnum'
|
||||
nullable: true
|
||||
resident_key_requirement:
|
||||
$ref: '#/components/schemas/ResidentKeyRequirementEnum'
|
||||
required:
|
||||
- component
|
||||
- meta_model_name
|
||||
@ -19200,6 +19222,12 @@ components:
|
||||
If empty, user will not be able to configure this stage.
|
||||
user_verification:
|
||||
$ref: '#/components/schemas/UserVerificationEnum'
|
||||
authenticator_attachment:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AuthenticatorAttachmentEnum'
|
||||
nullable: true
|
||||
resident_key_requirement:
|
||||
$ref: '#/components/schemas/ResidentKeyRequirementEnum'
|
||||
required:
|
||||
- name
|
||||
AuthenticatedSession:
|
||||
@ -19288,6 +19316,11 @@ components:
|
||||
- last_used
|
||||
- user
|
||||
- user_agent
|
||||
AuthenticatorAttachmentEnum:
|
||||
enum:
|
||||
- platform
|
||||
- cross-platform
|
||||
type: string
|
||||
AuthenticatorDuoChallenge:
|
||||
type: object
|
||||
description: Duo Challenge
|
||||
@ -26519,6 +26552,12 @@ components:
|
||||
If empty, user will not be able to configure this stage.
|
||||
user_verification:
|
||||
$ref: '#/components/schemas/UserVerificationEnum'
|
||||
authenticator_attachment:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AuthenticatorAttachmentEnum'
|
||||
nullable: true
|
||||
resident_key_requirement:
|
||||
$ref: '#/components/schemas/ResidentKeyRequirementEnum'
|
||||
PatchedAuthenticatorDuoStageRequest:
|
||||
type: object
|
||||
description: AuthenticatorDuoStage Serializer
|
||||
@ -29376,6 +29415,12 @@ components:
|
||||
type: integer
|
||||
maximum: 2147483647
|
||||
minimum: -2147483648
|
||||
ResidentKeyRequirementEnum:
|
||||
enum:
|
||||
- discouraged
|
||||
- preferred
|
||||
- required
|
||||
type: string
|
||||
SAMLMetadata:
|
||||
type: object
|
||||
description: SAML Provider Metadata serializer
|
||||
@ -31331,4 +31376,3 @@ components:
|
||||
name: Authorization
|
||||
servers:
|
||||
- url: /api/v3/
|
||||
- url: /api/v2beta/
|
||||
|
||||
@ -24,7 +24,7 @@ export const DEFAULT_CONFIG = new Configuration({
|
||||
// Required for POST/PUT/DELETE requests
|
||||
// getCookie function must return the cookie's contents
|
||||
headers: {
|
||||
"X-CSRFToken": getCookie("authentik_csrf"),
|
||||
"X-authentik-CSRF": getCookie("authentik_csrf"),
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@ -215,8 +215,6 @@ class TestProviderLDAP(SeleniumTestCase):
|
||||
"uidNumber": [str(2000 + o_user.pk)],
|
||||
"gidNumber": [str(2000 + o_user.pk)],
|
||||
"memberOf": [],
|
||||
"accountStatus": ["true"],
|
||||
"superuser": ["false"],
|
||||
"goauthentik.io/ldap/active": ["true"],
|
||||
"goauthentik.io/ldap/superuser": ["false"],
|
||||
"goauthentik.io/user/override-ips": ["true"],
|
||||
@ -242,8 +240,6 @@ class TestProviderLDAP(SeleniumTestCase):
|
||||
"uidNumber": [str(2000 + embedded_account.pk)],
|
||||
"gidNumber": [str(2000 + embedded_account.pk)],
|
||||
"memberOf": [],
|
||||
"accountStatus": ["true"],
|
||||
"superuser": ["false"],
|
||||
"goauthentik.io/ldap/active": ["true"],
|
||||
"goauthentik.io/ldap/superuser": ["false"],
|
||||
"goauthentik.io/user/override-ips": ["true"],
|
||||
@ -272,8 +268,6 @@ class TestProviderLDAP(SeleniumTestCase):
|
||||
f"cn={group.name},ou=groups,dc=ldap,dc=goauthentik,dc=io"
|
||||
for group in self.user.ak_groups.all()
|
||||
],
|
||||
"accountStatus": ["true"],
|
||||
"superuser": ["true"],
|
||||
"goauthentik.io/ldap/active": ["true"],
|
||||
"goauthentik.io/ldap/superuser": ["true"],
|
||||
"extraAttribute": ["bar"],
|
||||
|
||||
1363
web/package-lock.json
generated
1363
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -46,18 +46,19 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.16.7",
|
||||
"@babel/core": "^7.16.12",
|
||||
"@babel/plugin-proposal-decorators": "^7.16.7",
|
||||
"@babel/plugin-transform-runtime": "^7.16.7",
|
||||
"@babel/preset-env": "^7.16.7",
|
||||
"@babel/plugin-transform-runtime": "^7.16.10",
|
||||
"@babel/preset-env": "^7.16.11",
|
||||
"@babel/preset-typescript": "^7.16.7",
|
||||
"@formatjs/intl-listformat": "^6.5.0",
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@goauthentik/api": "^2021.12.4-1641413678",
|
||||
"@goauthentik/api": "^2022.1.1-1642874681",
|
||||
"@jackfranklin/rollup-plugin-markdown": "^0.3.0",
|
||||
"@lingui/cli": "^3.13.0",
|
||||
"@lingui/core": "^3.13.0",
|
||||
"@lingui/detect-locale": "^3.13.0",
|
||||
"@lingui/macro": "^3.13.0",
|
||||
"@lingui/cli": "^3.13.1",
|
||||
"@lingui/core": "^3.13.1",
|
||||
"@lingui/detect-locale": "^3.13.1",
|
||||
"@lingui/macro": "^3.13.1",
|
||||
"@patternfly/patternfly": "^4.164.2",
|
||||
"@polymer/iron-form": "^3.0.1",
|
||||
"@polymer/paper-input": "^3.2.1",
|
||||
@ -73,27 +74,27 @@
|
||||
"@types/chart.js": "^2.9.35",
|
||||
"@types/codemirror": "5.60.5",
|
||||
"@types/grecaptcha": "^3.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.9.0",
|
||||
"@typescript-eslint/parser": "^5.9.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||
"@typescript-eslint/parser": "^5.10.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.6.0",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^3.7.0",
|
||||
"chartjs-adapter-moment": "^1.0.0",
|
||||
"codemirror": "^5.65.0",
|
||||
"codemirror": "^5.65.1",
|
||||
"construct-style-sheets-polyfill": "^3.0.5",
|
||||
"country-flag-icons": "^1.4.19",
|
||||
"eslint": "^8.6.0",
|
||||
"eslint": "^8.7.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-plugin-custom-elements": "0.0.4",
|
||||
"eslint-plugin-lit": "^1.6.1",
|
||||
"flowchart.js": "^1.17.0",
|
||||
"fuse.js": "^6.5.3",
|
||||
"lit": "^2.1.0",
|
||||
"lit": "^2.1.1",
|
||||
"moment": "^2.29.1",
|
||||
"prettier": "^2.5.1",
|
||||
"rapidoc": "^9.1.3",
|
||||
"rollup": "^2.63.0",
|
||||
"rapidoc": "^9.1.4",
|
||||
"rollup": "^2.66.0",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
"rollup-plugin-cssimport": "^1.0.2",
|
||||
"rollup-plugin-minify-html-literals": "^1.2.6",
|
||||
@ -101,7 +102,7 @@
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"ts-lit-plugin": "^1.2.1",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.5.4",
|
||||
"typescript": "^4.5.5",
|
||||
"webcomponent-qr-code": "^1.0.5",
|
||||
"yaml": "^1.10.2"
|
||||
}
|
||||
|
||||
@ -3,3 +3,6 @@ window["polymerSkipLoadingFontRoboto"] = true;
|
||||
import "construct-style-sheets-polyfill";
|
||||
import "@webcomponents/webcomponentsjs";
|
||||
import "lit/polyfill-support.js";
|
||||
|
||||
import "@formatjs/intl-listformat/polyfill.js";
|
||||
import "@formatjs/intl-listformat/locale-data/en.js";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Config, Configuration, CoreApi, CurrentTenant, Middleware, ResponseContext, RootApi } from "@goauthentik/api";
|
||||
import { Config, Configuration, CoreApi, CurrentTenant, FetchParams, Middleware, RequestContext, ResponseContext, RootApi } from "@goauthentik/api";
|
||||
import { getCookie } from "../utils";
|
||||
import { APIMiddleware } from "../elements/notifications/APIDrawer";
|
||||
import { MessageMiddleware } from "../elements/messages/Middleware";
|
||||
@ -50,13 +50,21 @@ export function tenant(): Promise<CurrentTenant> {
|
||||
return globalTenantPromise;
|
||||
}
|
||||
|
||||
export class CSRFMiddleware implements Middleware {
|
||||
pre?(context: RequestContext): Promise<FetchParams | void> {
|
||||
// @ts-ignore
|
||||
context.init.headers["X-authentik-CSRF"] = getCookie("authentik_csrf");
|
||||
return Promise.resolve(context);
|
||||
}
|
||||
}
|
||||
|
||||
export const DEFAULT_CONFIG = new Configuration({
|
||||
basePath: process.env.AK_API_BASE_PATH + "/api/v3",
|
||||
headers: {
|
||||
"X-CSRFToken": getCookie("authentik_csrf"),
|
||||
"sentry-trace": getMetaContent("sentry-trace") || "",
|
||||
},
|
||||
middleware: [
|
||||
new CSRFMiddleware(),
|
||||
new APIMiddleware(),
|
||||
new MessageMiddleware(),
|
||||
new LoggingMiddleware(),
|
||||
|
||||
@ -20,6 +20,8 @@ export function configureSentry(canDoPpi: boolean = false): Promise<Config> {
|
||||
// Error on edge on ios,
|
||||
// https://stackoverflow.com/questions/69261499/what-is-instantsearchsdkjsbridgeclearhighlight
|
||||
/instantSearchSDKJSBridgeClearHighlight/ig,
|
||||
// Seems to be an issue in Safari and Firefox
|
||||
/MutationObserver.observe/ig,
|
||||
],
|
||||
release: `authentik@${VERSION}`,
|
||||
tunnel: "/api/v3/sentry/",
|
||||
|
||||
@ -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.12.5";
|
||||
export const VERSION = "2022.1.2";
|
||||
export const TITLE_DEFAULT = "authentik";
|
||||
export const ROUTE_SEPARATOR = ";";
|
||||
|
||||
|
||||
@ -107,7 +107,7 @@ export class CodeMirrorTextarea extends LitElement {
|
||||
this.editor = CodeMirror.fromTextArea(textarea, {
|
||||
mode: this.mode,
|
||||
theme: "monokai",
|
||||
lineNumbers: true,
|
||||
lineNumbers: false, // Line Numbers seem to be broken on firefox?
|
||||
readOnly: this.readOnly,
|
||||
autoRefresh: true,
|
||||
lineWrapping: true,
|
||||
|
||||
@ -150,7 +150,7 @@ export class IdentificationStage extends BaseStage<
|
||||
|
||||
cleanup(): void {
|
||||
if (this.form) {
|
||||
document.documentElement.removeChild(this.form);
|
||||
this.form.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -62,6 +62,10 @@ msgstr "6 digits, widely compatible"
|
||||
msgid "8 digits, not compatible with apps like Google Authenticator"
|
||||
msgstr "8 digits, not compatible with apps like Google Authenticator"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "A \"roaming\" authenticator, like a YubiKey"
|
||||
msgstr "A \"roaming\" authenticator, like a YubiKey"
|
||||
|
||||
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "A code has been sent to you via SMS."
|
||||
msgstr "A code has been sent to you via SMS."
|
||||
@ -70,6 +74,10 @@ msgstr "A code has been sent to you via SMS."
|
||||
msgid "A newer version of the frontend is available."
|
||||
msgstr "A newer version of the frontend is available."
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "A non-removable authenticator, like TouchID or Windows Hello"
|
||||
msgstr "A non-removable authenticator, like TouchID or Windows Hello"
|
||||
|
||||
#: src/pages/policies/dummy/DummyPolicyForm.ts
|
||||
msgid "A policy used for testing. Always returns the same result as specified below after waiting a random duration."
|
||||
msgstr "A policy used for testing. Always returns the same result as specified below after waiting a random duration."
|
||||
@ -488,6 +496,10 @@ msgstr "Authentication flow"
|
||||
msgid "Authenticator"
|
||||
msgstr "Authenticator"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Authenticator Attachment"
|
||||
msgstr "Authenticator Attachment"
|
||||
|
||||
#: src/pages/flows/utils.ts
|
||||
msgid "Authorization"
|
||||
msgstr "Authorization"
|
||||
@ -930,6 +942,7 @@ msgstr "Configuration error"
|
||||
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
msgid "Configuration flow"
|
||||
msgstr "Configuration flow"
|
||||
@ -2064,6 +2077,7 @@ msgstr "Flow used by an authenticated user to configure their password. If empty
|
||||
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
msgstr "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
|
||||
@ -2380,8 +2394,12 @@ msgid "If multiple providers share an outpost, a self-signed certificate is used
|
||||
msgstr "If multiple providers share an outpost, a self-signed certificate is used."
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
msgstr "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
#~ msgid "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
#~ msgstr "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "If no explicit redirect URIs are specified, the first successfully used redirect URI will be saved."
|
||||
msgstr "If no explicit redirect URIs are specified, the first successfully used redirect URI will be saved."
|
||||
|
||||
#: src/pages/tenants/TenantForm.ts
|
||||
msgid "If set, users are able to unenroll themselves using this flow. If no flow is set, option is not shown."
|
||||
@ -2739,6 +2757,7 @@ msgstr "Loading"
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
@ -3140,6 +3159,10 @@ msgstr "No objects found."
|
||||
msgid "No policies are currently bound to this object."
|
||||
msgstr "No policies are currently bound to this object."
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "No preference is sent"
|
||||
msgstr "No preference is sent"
|
||||
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "No recovery flow is configured."
|
||||
msgstr "No recovery flow is configured."
|
||||
@ -3227,8 +3250,12 @@ msgid "Notification rule(s)"
|
||||
msgstr "Notification rule(s)"
|
||||
|
||||
#: src/pages/events/TransportListPage.ts
|
||||
msgid "Notification transports(s)"
|
||||
msgstr "Notification transports(s)"
|
||||
msgid "Notification transport(s)"
|
||||
msgstr "Notification transport(s)"
|
||||
|
||||
#: src/pages/events/TransportListPage.ts
|
||||
#~ msgid "Notification transports(s)"
|
||||
#~ msgstr "Notification transports(s)"
|
||||
|
||||
#: src/elements/notifications/NotificationDrawer.ts
|
||||
msgid "Notifications"
|
||||
@ -3929,6 +3956,10 @@ msgstr "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
|
||||
msgid "Reset Password"
|
||||
msgstr "Reset Password"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Resident key requirement"
|
||||
msgstr "Resident key requirement"
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#~ msgid "Resources"
|
||||
#~ msgstr "Resources"
|
||||
@ -5034,6 +5065,18 @@ msgstr "The Host IP of the docker host"
|
||||
msgid "The URL \"{0}\" was not found."
|
||||
msgstr "The URL \"{0}\" was not found."
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator MUST create a dedicated credential. If it cannot, the RP is prepared for an error to occur"
|
||||
msgstr "The authenticator MUST create a dedicated credential. If it cannot, the RP is prepared for an error to occur"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator can create and store a dedicated credential, but if it doesn't that's alright too"
|
||||
msgstr "The authenticator can create and store a dedicated credential, but if it doesn't that's alright too"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator should not create a dedicated credential"
|
||||
msgstr "The authenticator should not create a dedicated credential"
|
||||
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "The external URL you'll access the application at. Include any non-standard port."
|
||||
@ -5180,6 +5223,10 @@ msgstr "Title"
|
||||
msgid "To"
|
||||
msgstr "To"
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "To allow any redirect URI, set this value to \"*\". Be aware of the possible security implications this can have."
|
||||
msgstr "To allow any redirect URI, set this value to \"*\". Be aware of the possible security implications this can have."
|
||||
|
||||
#: src/pages/users/UserViewPage.ts
|
||||
msgid "To create a recovery link, the current tenant needs to have a recovery flow configured."
|
||||
msgstr "To create a recovery link, the current tenant needs to have a recovery flow configured."
|
||||
|
||||
@ -68,6 +68,10 @@ msgstr "6 chiffres, compatibilité large"
|
||||
msgid "8 digits, not compatible with apps like Google Authenticator"
|
||||
msgstr "8 chiffres, incompatible avec certaines applications telles que Google Authenticator"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "A \"roaming\" authenticator, like a YubiKey"
|
||||
msgstr ""
|
||||
|
||||
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "A code has been sent to you via SMS."
|
||||
msgstr ""
|
||||
@ -76,6 +80,10 @@ msgstr ""
|
||||
msgid "A newer version of the frontend is available."
|
||||
msgstr "Une nouvelle version de l'interface est disponible."
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "A non-removable authenticator, like TouchID or Windows Hello"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/policies/dummy/DummyPolicyForm.ts
|
||||
msgid "A policy used for testing. Always returns the same result as specified below after waiting a random duration."
|
||||
msgstr "Une politique utilisée pour les tests. Retourne toujours la même valeur telle qu'indiquée ci-dessous après une attente aléatoire."
|
||||
@ -493,6 +501,10 @@ msgstr "Flux d'authentification"
|
||||
msgid "Authenticator"
|
||||
msgstr "Authentificateur"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Authenticator Attachment"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/flows/utils.ts
|
||||
msgid "Authorization"
|
||||
msgstr "Authorisation"
|
||||
@ -932,6 +944,7 @@ msgstr "Erreur de configuration"
|
||||
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
msgid "Configuration flow"
|
||||
msgstr "Flux de configuration"
|
||||
@ -2050,6 +2063,7 @@ msgstr "Flux utilisé par un utilisateur authentifié pour configurer son mot de
|
||||
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
msgstr "Flux utilisé par un utilisateur authentifié pour configurer cette étape. S'il est vide, l'utilisateur ne sera pas en mesure de le configurer."
|
||||
|
||||
@ -2364,8 +2378,12 @@ msgid "If multiple providers share an outpost, a self-signed certificate is used
|
||||
msgstr "Si plusieurs fournisseurs partagent un avant-poste, un certificat auto-signé est utilisé."
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
msgstr "Si aucune URL de redirection explicite n'est spécifié, toute URL de redirection est autorisé."
|
||||
#~ msgid "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
#~ msgstr "Si aucune URL de redirection explicite n'est spécifié, toute URL de redirection est autorisé."
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "If no explicit redirect URIs are specified, the first successfully used redirect URI will be saved."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/tenants/TenantForm.ts
|
||||
msgid "If set, users are able to unenroll themselves using this flow. If no flow is set, option is not shown."
|
||||
@ -2719,6 +2737,7 @@ msgstr "Chargement en cours"
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
@ -3119,6 +3138,10 @@ msgstr "Aucun objet trouvé."
|
||||
msgid "No policies are currently bound to this object."
|
||||
msgstr "Aucune politique n'est actuellement lié à cet objet."
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "No preference is sent"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "No recovery flow is configured."
|
||||
msgstr "Aucun flux de récupération n'est configuré."
|
||||
@ -3205,8 +3228,12 @@ msgid "Notification rule(s)"
|
||||
msgstr "Règle(s) de notification"
|
||||
|
||||
#: src/pages/events/TransportListPage.ts
|
||||
msgid "Notification transports(s)"
|
||||
msgstr "Transport(s) de notification"
|
||||
msgid "Notification transport(s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/events/TransportListPage.ts
|
||||
#~ msgid "Notification transports(s)"
|
||||
#~ msgstr "Transport(s) de notification"
|
||||
|
||||
#: src/elements/notifications/NotificationDrawer.ts
|
||||
msgid "Notifications"
|
||||
@ -3901,6 +3928,10 @@ msgstr "Obligatoire. 150 caractères ou moins. Lettres, chiffres et @/./+/-/_ un
|
||||
msgid "Reset Password"
|
||||
msgstr "Réinitialiser le mot de passe"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Resident key requirement"
|
||||
msgstr ""
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#~ msgid "Resources"
|
||||
#~ msgstr "Ressources"
|
||||
@ -4989,6 +5020,18 @@ msgstr ""
|
||||
msgid "The URL \"{0}\" was not found."
|
||||
msgstr "L'URL \"{0}\" est introuvable."
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator MUST create a dedicated credential. If it cannot, the RP is prepared for an error to occur"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator can create and store a dedicated credential, but if it doesn't that's alright too"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator should not create a dedicated credential"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "The external URL you'll access the application at. Include any non-standard port."
|
||||
@ -5124,6 +5167,10 @@ msgstr "Titre"
|
||||
msgid "To"
|
||||
msgstr "À"
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "To allow any redirect URI, set this value to \"*\". Be aware of the possible security implications this can have."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserViewPage.ts
|
||||
msgid "To create a recovery link, the current tenant needs to have a recovery flow configured."
|
||||
msgstr "Pour créer un lien de récupération, le locataire actuel doit avoir un flux de récupération configuré."
|
||||
|
||||
@ -62,6 +62,10 @@ msgstr ""
|
||||
msgid "8 digits, not compatible with apps like Google Authenticator"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "A \"roaming\" authenticator, like a YubiKey"
|
||||
msgstr ""
|
||||
|
||||
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "A code has been sent to you via SMS."
|
||||
msgstr ""
|
||||
@ -70,6 +74,10 @@ msgstr ""
|
||||
msgid "A newer version of the frontend is available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "A non-removable authenticator, like TouchID or Windows Hello"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/policies/dummy/DummyPolicyForm.ts
|
||||
msgid "A policy used for testing. Always returns the same result as specified below after waiting a random duration."
|
||||
msgstr ""
|
||||
@ -484,6 +492,10 @@ msgstr ""
|
||||
msgid "Authenticator"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Authenticator Attachment"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/flows/utils.ts
|
||||
msgid "Authorization"
|
||||
msgstr ""
|
||||
@ -924,6 +936,7 @@ msgstr ""
|
||||
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
msgid "Configuration flow"
|
||||
msgstr ""
|
||||
@ -2056,6 +2069,7 @@ msgstr ""
|
||||
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
msgstr ""
|
||||
|
||||
@ -2372,7 +2386,11 @@ msgid "If multiple providers share an outpost, a self-signed certificate is used
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
#~ msgid "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "If no explicit redirect URIs are specified, the first successfully used redirect URI will be saved."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/tenants/TenantForm.ts
|
||||
@ -2729,6 +2747,7 @@ msgstr ""
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
@ -3130,6 +3149,10 @@ msgstr ""
|
||||
msgid "No policies are currently bound to this object."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "No preference is sent"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "No recovery flow is configured."
|
||||
msgstr ""
|
||||
@ -3217,9 +3240,13 @@ msgid "Notification rule(s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/events/TransportListPage.ts
|
||||
msgid "Notification transports(s)"
|
||||
msgid "Notification transport(s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/events/TransportListPage.ts
|
||||
#~ msgid "Notification transports(s)"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/elements/notifications/NotificationDrawer.ts
|
||||
msgid "Notifications"
|
||||
msgstr ""
|
||||
@ -3919,6 +3946,10 @@ msgstr ""
|
||||
msgid "Reset Password"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Resident key requirement"
|
||||
msgstr ""
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#~ msgid "Resources"
|
||||
#~ msgstr ""
|
||||
@ -5024,6 +5055,18 @@ msgstr ""
|
||||
msgid "The URL \"{0}\" was not found."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator MUST create a dedicated credential. If it cannot, the RP is prepared for an error to occur"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator can create and store a dedicated credential, but if it doesn't that's alright too"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator should not create a dedicated credential"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "The external URL you'll access the application at. Include any non-standard port."
|
||||
@ -5160,6 +5203,10 @@ msgstr ""
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "To allow any redirect URI, set this value to \"*\". Be aware of the possible security implications this can have."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserViewPage.ts
|
||||
msgid "To create a recovery link, the current tenant needs to have a recovery flow configured."
|
||||
msgstr ""
|
||||
|
||||
@ -65,6 +65,10 @@ msgstr "6 basamaklı, yaygın olarak uyumlu"
|
||||
msgid "8 digits, not compatible with apps like Google Authenticator"
|
||||
msgstr "Google Authenticator gibi uygulamalarla uyumlu olmayan 8 haneli"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "A \"roaming\" authenticator, like a YubiKey"
|
||||
msgstr ""
|
||||
|
||||
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
|
||||
msgid "A code has been sent to you via SMS."
|
||||
msgstr "SMS ile size bir kod gönderildi."
|
||||
@ -73,6 +77,10 @@ msgstr "SMS ile size bir kod gönderildi."
|
||||
msgid "A newer version of the frontend is available."
|
||||
msgstr "Ön yüzün daha yeni bir sürümü mevcuttur."
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "A non-removable authenticator, like TouchID or Windows Hello"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/policies/dummy/DummyPolicyForm.ts
|
||||
msgid "A policy used for testing. Always returns the same result as specified below after waiting a random duration."
|
||||
msgstr "Test için kullanılan bir ilke. Her zaman rastgele bir süre bekledikten sonra aşağıda belirtilen sonucu döndürür."
|
||||
@ -487,6 +495,10 @@ msgstr "Kimlik doğrulama akışı"
|
||||
msgid "Authenticator"
|
||||
msgstr "Kimlik Doğrulayıcı"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Authenticator Attachment"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/flows/utils.ts
|
||||
msgid "Authorization"
|
||||
msgstr "Yetkilendirme"
|
||||
@ -924,6 +936,7 @@ msgstr "Yapılandırma hatası"
|
||||
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
msgid "Configuration flow"
|
||||
msgstr "Yapılandırma akışı"
|
||||
@ -2025,6 +2038,7 @@ msgstr "Kimliği doğrulanmış bir kullanıcı tarafından parolasını yapıla
|
||||
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
msgstr "Bu Aşama'yı yapılandırmak için kimliği doğrulanmış bir kullanıcı tarafından kullanılan akış. Boşsa, kullanıcı bu aşamayı yapılandıramaz."
|
||||
|
||||
@ -2292,8 +2306,6 @@ msgstr "Kimlik Belirteci"
|
||||
msgid "IP"
|
||||
msgstr "İP"
|
||||
|
||||
#: src/pages/policies/reputation/IPReputationListPage.ts
|
||||
#: src/pages/policies/reputation/IPReputationListPage.ts
|
||||
#~ msgid "IP Reputation"
|
||||
#~ msgstr "IP İtibar"
|
||||
|
||||
@ -2337,8 +2349,12 @@ msgid "If multiple providers share an outpost, a self-signed certificate is used
|
||||
msgstr "Birden çok sağlayıcı bir üssü paylaşıyorsa, otomatik olarak imzalanan bir sertifika kullanılır."
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
msgstr "Açık bir yeniden yönlendirme URI'leri belirtilmezse, herhangi bir yeniden yönlendirme URI'sine izin verilir."
|
||||
#~ msgid "If no explicit redirect URIs are specified, any redirect URI is allowed."
|
||||
#~ msgstr "Açık bir yeniden yönlendirme URI'leri belirtilmezse, herhangi bir yeniden yönlendirme URI'sine izin verilir."
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "If no explicit redirect URIs are specified, the first successfully used redirect URI will be saved."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/tenants/TenantForm.ts
|
||||
msgid "If set, users are able to unenroll themselves using this flow. If no flow is set, option is not shown."
|
||||
@ -2573,7 +2589,7 @@ msgstr "Son senkronizasyon: {0}"
|
||||
#: src/pages/applications/ApplicationViewPage.ts
|
||||
#: src/pages/applications/ApplicationViewPage.ts
|
||||
msgid "Launch"
|
||||
msgstr "Lansman"
|
||||
msgstr "Eriş"
|
||||
|
||||
#: src/pages/applications/ApplicationForm.ts
|
||||
msgid "Launch URL"
|
||||
@ -2691,6 +2707,7 @@ msgstr "Yükleniyor"
|
||||
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
|
||||
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
|
||||
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
@ -2721,7 +2738,7 @@ msgstr "Yerel"
|
||||
|
||||
#: src/user/user-settings/details/UserDetailsForm.ts
|
||||
msgid "Locale"
|
||||
msgstr "Yerel"
|
||||
msgstr "Yerelleştirme"
|
||||
|
||||
#: src/pages/stages/user_login/UserLoginStageForm.ts
|
||||
msgid "Log the currently pending user in."
|
||||
@ -3091,6 +3108,10 @@ msgstr "Nesne bulunamadı."
|
||||
msgid "No policies are currently bound to this object."
|
||||
msgstr "Hiçbir ilke şu anda bu nesneye bağlı değildir."
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "No preference is sent"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "No recovery flow is configured."
|
||||
msgstr "Kurtarma akışı yapılandırılmamış."
|
||||
@ -3175,8 +3196,12 @@ msgid "Notification rule(s)"
|
||||
msgstr "Bildirim kuralları"
|
||||
|
||||
#: src/pages/events/TransportListPage.ts
|
||||
msgid "Notification transports(s)"
|
||||
msgstr "Bildirim aktarıcıları"
|
||||
msgid "Notification transport(s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/events/TransportListPage.ts
|
||||
#~ msgid "Notification transports(s)"
|
||||
#~ msgstr "Bildirim aktarıcıları"
|
||||
|
||||
#: src/elements/notifications/NotificationDrawer.ts
|
||||
msgid "Notifications"
|
||||
@ -3804,32 +3829,28 @@ msgstr "Kullanıcıyı geçerli oturumdan kaldırın."
|
||||
|
||||
#: src/pages/policies/reputation/ReputationListPage.ts
|
||||
msgid "Reputation"
|
||||
msgstr ""
|
||||
msgstr "İtibar"
|
||||
|
||||
#: src/pages/policies/reputation/ReputationListPage.ts
|
||||
msgid "Reputation for IP and user identifiers. Scores are decreased for each failed login and increased for each successful login."
|
||||
msgstr ""
|
||||
msgstr "IP ve kullanıcı tanımlayıcıları için itibar. Başarısız olan her giriş için puan azaltılır ve her başarılı oturum açma için artırılır."
|
||||
|
||||
#: src/pages/policies/reputation/IPReputationListPage.ts
|
||||
#~ msgid "Reputation for IPs. Scores are decreased for each failed login and increased for each successful login."
|
||||
#~ msgstr "IP'lerin itibarı. Başarısız olan her giriş için puanlar azaltılır ve her başarılı oturum açma için artırılır."
|
||||
|
||||
#: src/pages/policies/reputation/UserReputationListPage.ts
|
||||
#~ msgid "Reputation for usernames. Scores are decreased for each failed login and increased for each successful login."
|
||||
#~ msgstr "Kullanıcı adları için itibar. Başarısız olan her giriş için puanlar azaltılır ve her başarılı oturum açma için artırılır."
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#~ msgid "Reputation policy - IPs"
|
||||
#~ msgstr "İtibar ilkesi - IP'ler"
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#~ msgid "Reputation policy - Users"
|
||||
#~ msgstr "İtibar ilkesi- Kullanıcılar"
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#: src/pages/policies/reputation/ReputationListPage.ts
|
||||
msgid "Reputation scores"
|
||||
msgstr ""
|
||||
msgstr "İtibar puanları"
|
||||
|
||||
#: src/pages/events/EventInfo.ts
|
||||
#: src/pages/events/EventInfo.ts
|
||||
@ -3862,6 +3883,10 @@ msgstr "Gerekli. 150 karakter veya daha az. Harfler, rakamlar ve yalnızca @/./+
|
||||
msgid "Reset Password"
|
||||
msgstr "Parolayı Sıfırla"
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "Resident key requirement"
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Resources"
|
||||
#~ msgstr "Kaynaklar"
|
||||
|
||||
@ -4933,6 +4958,18 @@ msgstr "Docker ana bilgisayarının Ana Bilgisayar IP'si"
|
||||
msgid "The URL \"{0}\" was not found."
|
||||
msgstr "“{0}” URL'si bulunamadı."
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator MUST create a dedicated credential. If it cannot, the RP is prepared for an error to occur"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator can create and store a dedicated credential, but if it doesn't that's alright too"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
|
||||
msgid "The authenticator should not create a dedicated credential"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "The external URL you'll access the application at. Include any non-standard port."
|
||||
@ -5075,6 +5112,10 @@ msgstr "Başlık"
|
||||
msgid "To"
|
||||
msgstr "Kime"
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
msgid "To allow any redirect URI, set this value to \"*\". Be aware of the possible security implications this can have."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserViewPage.ts
|
||||
msgid "To create a recovery link, the current tenant needs to have a recovery flow configured."
|
||||
msgstr "Kurtarma bağlantısı oluşturmak için geçerli sakinin yapılandırılmış bir kurtarma akışı olması gerekir."
|
||||
@ -5464,7 +5505,7 @@ msgstr "Güncelleme {0}"
|
||||
|
||||
#: src/pages/policies/reputation/ReputationListPage.ts
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
msgstr "Güncellendi"
|
||||
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Upstream host that the requests are forwarded to."
|
||||
@ -5545,8 +5586,6 @@ msgstr "Kullanıcı Bilgileri"
|
||||
msgid "User Property Mappings"
|
||||
msgstr "Kullanıcı Özellik Eşlemeleri"
|
||||
|
||||
#: src/pages/policies/reputation/UserReputationListPage.ts
|
||||
#: src/pages/policies/reputation/UserReputationListPage.ts
|
||||
#~ msgid "User Reputation"
|
||||
#~ msgstr "Kullanıcı İtibar"
|
||||
|
||||
|
||||
@ -17,8 +17,10 @@ export class SystemStatusCard extends AdminStatusCard<System> {
|
||||
async getPrimaryValue(): Promise<System> {
|
||||
this.now = new Date();
|
||||
let status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
|
||||
if (status.embeddedOutpostHost === "") {
|
||||
if (status.embeddedOutpostHost === "" || !status.embeddedOutpostHost.includes("http")) {
|
||||
// First install, ensure the embedded outpost host is set
|
||||
// also run when outpost host does not contain http
|
||||
// (yes it's called host and requires a URL, i know)
|
||||
await this.setOutpostHost();
|
||||
status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ export class TransportListPage extends TablePage<NotificationTransport> {
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
const disabled = this.selectedElements.length < 1;
|
||||
return html`<ak-forms-delete-bulk
|
||||
objectLabel=${t`Notification transports(s)`}
|
||||
objectLabel=${t`Notification transport(s)`}
|
||||
.objects=${this.selectedElements}
|
||||
.usedBy=${(item: NotificationTransport) => {
|
||||
return new EventsApi(DEFAULT_CONFIG).eventsTransportsUsedByList({
|
||||
|
||||
@ -171,7 +171,10 @@ ${this.instance?.redirectUris}</textarea
|
||||
${t`Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows.`}
|
||||
</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${t`If no explicit redirect URIs are specified, any redirect URI is allowed.`}
|
||||
${t`If no explicit redirect URIs are specified, the first successfully used redirect URI will be saved.`}
|
||||
</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${t`To allow any redirect URI, set this value to "*". Be aware of the possible security implications this can have.`}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${t`Signing Key`} name="signingKey">
|
||||
|
||||
@ -5,8 +5,16 @@ import { t } from "@lingui/macro";
|
||||
import { TemplateResult, html } from "lit";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
import { until } from "lit/directives/until.js";
|
||||
|
||||
import { AuthenticateWebAuthnStage, StagesApi } from "@goauthentik/api";
|
||||
import {
|
||||
AuthenticateWebAuthnStage,
|
||||
AuthenticatorAttachmentEnum,
|
||||
FlowsApi,
|
||||
FlowsInstancesListDesignationEnum,
|
||||
ResidentKeyRequirementEnum,
|
||||
StagesApi,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import "../../../elements/forms/HorizontalFormElement";
|
||||
@ -29,6 +37,9 @@ export class AuthenticateWebAuthnStageForm extends ModelForm<AuthenticateWebAuth
|
||||
}
|
||||
|
||||
send = (data: AuthenticateWebAuthnStage): Promise<AuthenticateWebAuthnStage> => {
|
||||
if (data.authenticatorAttachment?.toString() === "") {
|
||||
data.authenticatorAttachment = null;
|
||||
}
|
||||
if (this.instance) {
|
||||
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorWebauthnUpdate({
|
||||
stageUuid: this.instance.pk || "",
|
||||
@ -62,7 +73,7 @@ export class AuthenticateWebAuthnStageForm extends ModelForm<AuthenticateWebAuth
|
||||
?required=${true}
|
||||
name="userVerification"
|
||||
>
|
||||
<select name="users" class="pf-c-form-control">
|
||||
<select class="pf-c-form-control">
|
||||
<option
|
||||
value="${UserVerificationEnum.Required}"
|
||||
?selected=${this.instance?.userVerification ===
|
||||
@ -86,6 +97,103 @@ export class AuthenticateWebAuthnStageForm extends ModelForm<AuthenticateWebAuth
|
||||
</option>
|
||||
</select>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${t`Resident key requirement`}
|
||||
?required=${true}
|
||||
name="residentKeyRequirement"
|
||||
>
|
||||
<select class="pf-c-form-control">
|
||||
<option
|
||||
value="${ResidentKeyRequirementEnum.Discouraged}"
|
||||
?selected=${this.instance?.residentKeyRequirement ===
|
||||
ResidentKeyRequirementEnum.Discouraged}
|
||||
>
|
||||
${t`The authenticator should not create a dedicated credential`}
|
||||
</option>
|
||||
<option
|
||||
value="${ResidentKeyRequirementEnum.Preferred}"
|
||||
?selected=${this.instance?.residentKeyRequirement ===
|
||||
ResidentKeyRequirementEnum.Preferred}
|
||||
>
|
||||
${t`The authenticator can create and store a dedicated credential, but if it doesn't that's alright too`}
|
||||
</option>
|
||||
<option
|
||||
value="${ResidentKeyRequirementEnum.Required}"
|
||||
?selected=${this.instance?.residentKeyRequirement ===
|
||||
ResidentKeyRequirementEnum.Required}
|
||||
>
|
||||
${t`The authenticator MUST create a dedicated credential. If it cannot, the RP is prepared for an error to occur`}
|
||||
</option>
|
||||
</select>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${t`Authenticator Attachment`}
|
||||
?required=${true}
|
||||
name="authenticatorAttachment"
|
||||
>
|
||||
<select class="pf-c-form-control">
|
||||
<option
|
||||
value=""
|
||||
?selected=${this.instance?.authenticatorAttachment === null}
|
||||
>
|
||||
${t`No preference is sent`}
|
||||
</option>
|
||||
<option
|
||||
value="${AuthenticatorAttachmentEnum.Platform}"
|
||||
?selected=${this.instance?.authenticatorAttachment ===
|
||||
AuthenticatorAttachmentEnum.Platform}
|
||||
>
|
||||
${t`A non-removable authenticator, like TouchID or Windows Hello`}
|
||||
</option>
|
||||
<option
|
||||
value="${AuthenticatorAttachmentEnum.CrossPlatform}"
|
||||
?selected=${this.instance?.authenticatorAttachment ===
|
||||
AuthenticatorAttachmentEnum.CrossPlatform}
|
||||
>
|
||||
${t`A "roaming" authenticator, like a YubiKey`}
|
||||
</option>
|
||||
</select>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${t`Configuration flow`} name="configureFlow">
|
||||
<select class="pf-c-form-control">
|
||||
<option
|
||||
value=""
|
||||
?selected=${this.instance?.configureFlow === undefined}
|
||||
>
|
||||
---------
|
||||
</option>
|
||||
${until(
|
||||
new FlowsApi(DEFAULT_CONFIG)
|
||||
.flowsInstancesList({
|
||||
ordering: "slug",
|
||||
designation:
|
||||
FlowsInstancesListDesignationEnum.StageConfiguration,
|
||||
})
|
||||
.then((flows) => {
|
||||
return flows.results.map((flow) => {
|
||||
let selected = this.instance?.configureFlow === flow.pk;
|
||||
if (
|
||||
!this.instance?.pk &&
|
||||
!this.instance?.configureFlow &&
|
||||
flow.slug === "default-otp-time-configure"
|
||||
) {
|
||||
selected = true;
|
||||
}
|
||||
return html`<option
|
||||
value=${ifDefined(flow.pk)}
|
||||
?selected=${selected}
|
||||
>
|
||||
${flow.name} (${flow.slug})
|
||||
</option>`;
|
||||
});
|
||||
}),
|
||||
html`<option>${t`Loading...`}</option>`,
|
||||
)}
|
||||
</select>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${t`Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage.`}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
</div>
|
||||
</ak-form-group>
|
||||
</form>`;
|
||||
|
||||
33
website/docs/flow/inspector.md
Normal file
33
website/docs/flow/inspector.md
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
title: Inspector
|
||||
---
|
||||
|
||||
The flow inspector, introduced in 2021.10, allows administrators to easily figure out how custom flows work, inspect the current context and debug issues.
|
||||
|
||||
:::info
|
||||
When running a flow with the inspector enabled, the flow is still executed normally. This means that for example, a `user_write` stage will _actually_ write user data.
|
||||
:::
|
||||
|
||||

|
||||
|
||||
The following infos are shown in the inspector
|
||||
|
||||
## Next stage
|
||||
|
||||
This is the currently planned next stage. If you have stage bindings configured to evaluate on plan (default), then you will see the result here. If you however have them configured to re-evaluate, then this will not show up here, since the results will vary based on your input.
|
||||
|
||||
Shown is the name and kind of the stage, as well as the unique ID.
|
||||
|
||||
## Plan history
|
||||
|
||||
Here you can see an overview of which stages have run, which is currently active, and which is planned to come next. Same caveats as above apply.
|
||||
|
||||
## Current plan context
|
||||
|
||||
This shows you the current context. This will contain fields depending on the same, after an identification stage for example you would see "pending_user" be set.
|
||||
|
||||
This data is not cleaned, so if your flow involves inputting a password, it will be shown here too.
|
||||
|
||||
## Session ID
|
||||
|
||||
The unique ID for the currently used session. This can be used to debug issues with flows restarting/losing state.
|
||||
BIN
website/docs/flow/inspector.png
Normal file
BIN
website/docs/flow/inspector.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
@ -25,7 +25,11 @@ All of these variables can be set to values, but you can also use a URI-like for
|
||||
|
||||
### PostgreSQL Backup Settings
|
||||
|
||||
- `AUTHENTIK_POSTGRESQL__BACKUP__ENABLED`: Controls if the inbuilt backup-mechanism is enabled, defaults to true (new in 2021.10).
|
||||
:::info
|
||||
The integrated backup is deprecated in 2022.1 and will be removed in a future version.
|
||||
:::
|
||||
|
||||
- `AUTHENTIK_POSTGRESQL__BACKUP__ENABLED`: Controls if the inbuilt backup-mechanism is enabled, defaults to false (new in 2021.10).
|
||||
|
||||
Optionally enable automated database backups to S3 or S3-compatible storages.
|
||||
|
||||
|
||||
@ -67,20 +67,15 @@ The GeoIP database will automatically be updated every 8 hours.
|
||||
|
||||
## Running on Port 80/443
|
||||
|
||||
By default, authentik listens on port 9000 for HTTP and 9443 for HTTPS. To change this, you can use a [docker-compose override file](https://docs.docker.com/compose/extends/#adding-and-overriding-configuration).
|
||||
By default, authentik listens on port 9000 for HTTP and 9443 for HTTPS. To change this, you can set the following variables in `.env`:
|
||||
|
||||
Create a file called `docker-compose.override.yml` with the following contents:
|
||||
|
||||
```yaml
|
||||
version: '3.2'
|
||||
|
||||
services:
|
||||
server:
|
||||
ports:
|
||||
- "0.0.0.0:80:9000"
|
||||
- "0.0.0.0:443:9443"
|
||||
```shell
|
||||
AUTHENTIK_PORT_HTTP=80
|
||||
AUTHENTIK_PORT_HTTPS=443
|
||||
```
|
||||
|
||||
Afterwards, make sure to run `docker-compose up -d`.
|
||||
|
||||
## Startup
|
||||
|
||||
Afterwards, run these commands to finish
|
||||
|
||||
@ -2,6 +2,10 @@
|
||||
title: Backup and restore
|
||||
---
|
||||
|
||||
:::error
|
||||
Integrated backups are deprecated and will be removed in a future authentik release.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
Local backups are only supported for docker-compose installs. If you want to backup a Kubernetes instance locally, use an S3-compatible server such as [minio](https://min.io/)
|
||||
:::
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user