Compare commits
6 Commits
events/imp
...
files-in-d
Author | SHA1 | Date | |
---|---|---|---|
d410083cfc | |||
6045f96a05 | |||
c50df0f843 | |||
c8ebd9f74b | |||
b3f441f2cd | |||
647f054be3 |
32
authentik/core/api/files.py
Normal file
32
authentik/core/api/files.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
|
from authentik.core.api.utils import ModelSerializer
|
||||||
|
from authentik.core.models import File
|
||||||
|
|
||||||
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
|
class FileSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = File
|
||||||
|
fields = (
|
||||||
|
"pk",
|
||||||
|
"name",
|
||||||
|
"content",
|
||||||
|
"location",
|
||||||
|
"private",
|
||||||
|
"url",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class FileViewSet(UsedByMixin, ModelViewSet):
|
||||||
|
queryset = File.objects.all()
|
||||||
|
serializer_class = FileSerializer
|
||||||
|
filterset_fields = ("private",)
|
||||||
|
ordering = ("name",)
|
||||||
|
search_fields = (
|
||||||
|
"name",
|
||||||
|
"location",
|
||||||
|
)
|
@ -0,0 +1,44 @@
|
|||||||
|
# Generated by Django 5.1.11 on 2025-06-13 15:12
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("authentik_core", "0048_delete_oldauthenticatedsession_content_type"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="File",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.UUIDField(
|
||||||
|
default=uuid.uuid4, editable=False, primary_key=True, serialize=False
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.TextField()),
|
||||||
|
("content", models.BinaryField()),
|
||||||
|
("public", models.BooleanField(default=False)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"verbose_name": "Files",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name="application",
|
||||||
|
old_name="meta_icon",
|
||||||
|
new_name="meta_old_icon",
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="application",
|
||||||
|
name="meta_icon",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
null=True, on_delete=django.db.models.deletion.SET_NULL, to="authentik_core.file"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,32 @@
|
|||||||
|
# Generated by Django 5.1.11 on 2025-06-13 15:29
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("authentik_core", "0049_file_rename_meta_icon_application_meta_old_icon"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="file",
|
||||||
|
name="location",
|
||||||
|
field=models.TextField(null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="file",
|
||||||
|
name="content",
|
||||||
|
field=models.BinaryField(null=True),
|
||||||
|
),
|
||||||
|
migrations.AddConstraint(
|
||||||
|
model_name="file",
|
||||||
|
constraint=models.CheckConstraint(
|
||||||
|
condition=models.Q(
|
||||||
|
("content__isnull", False), ("location__isnull", False), _connector="OR"
|
||||||
|
),
|
||||||
|
name="one_of_content_location_is_defined",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
@ -29,6 +29,7 @@ from authentik.blueprints.models import ManagedModel
|
|||||||
from authentik.core.expression.exceptions import PropertyMappingExpressionException
|
from authentik.core.expression.exceptions import PropertyMappingExpressionException
|
||||||
from authentik.core.types import UILoginButton, UserSettingSerializer
|
from authentik.core.types import UILoginButton, UserSettingSerializer
|
||||||
from authentik.lib.avatars import get_avatar
|
from authentik.lib.avatars import get_avatar
|
||||||
|
from authentik.lib.config import CONFIG
|
||||||
from authentik.lib.expression.exceptions import ControlFlowException
|
from authentik.lib.expression.exceptions import ControlFlowException
|
||||||
from authentik.lib.generators import generate_id
|
from authentik.lib.generators import generate_id
|
||||||
from authentik.lib.merge import MERGE_LIST_UNIQUE
|
from authentik.lib.merge import MERGE_LIST_UNIQUE
|
||||||
@ -533,12 +534,13 @@ class Application(SerializerModel, PolicyBindingModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# For template applications, this can be set to /static/authentik/applications/*
|
# For template applications, this can be set to /static/authentik/applications/*
|
||||||
meta_icon = models.FileField(
|
meta_old_icon = models.FileField(
|
||||||
upload_to="application-icons/",
|
upload_to="application-icons/",
|
||||||
default=None,
|
default=None,
|
||||||
null=True,
|
null=True,
|
||||||
max_length=500,
|
max_length=500,
|
||||||
)
|
)
|
||||||
|
meta_icon = models.ForeignKey("File", null=True, on_delete=models.SET_NULL)
|
||||||
meta_description = models.TextField(default="", blank=True)
|
meta_description = models.TextField(default="", blank=True)
|
||||||
meta_publisher = models.TextField(default="", blank=True)
|
meta_publisher = models.TextField(default="", blank=True)
|
||||||
|
|
||||||
@ -1100,3 +1102,44 @@ class AuthenticatedSession(SerializerModel):
|
|||||||
session=Session.objects.filter(session_key=request.session.session_key).first(),
|
session=Session.objects.filter(session_key=request.session.session_key).first(),
|
||||||
user=user,
|
user=user,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class File(SerializerModel):
|
||||||
|
id = models.UUIDField(primary_key=True, editable=False, default=uuid4)
|
||||||
|
|
||||||
|
name = models.TextField()
|
||||||
|
content = models.BinaryField(null=True)
|
||||||
|
location = models.TextField(null=True)
|
||||||
|
public = models.BooleanField(default=False)
|
||||||
|
delete_on_delete = models.BooleanField(default=False)
|
||||||
|
expiry = models.DateTimeField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("File")
|
||||||
|
verbose_name = _("Files")
|
||||||
|
constraints = (
|
||||||
|
models.CheckConstraint(
|
||||||
|
condition=Q(content__isnull=False) | Q(location__isnull=False),
|
||||||
|
name="one_of_content_location_is_defined",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def serializer(self) -> type[Serializer]:
|
||||||
|
from authentik.core.api.files import FileSerializer
|
||||||
|
|
||||||
|
return FileSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self) -> str:
|
||||||
|
if self.content:
|
||||||
|
return (
|
||||||
|
CONFIG.get("web.path", "/")[:-1]
|
||||||
|
+ f"/files/{'public' if self.public else 'private'}/{self.pk}"
|
||||||
|
)
|
||||||
|
elif self.location.startswith("/static"):
|
||||||
|
return CONFIG.get("web.path", "/")[:-1] + self.location
|
||||||
|
return self.location
|
||||||
|
@ -8,6 +8,7 @@ from authentik.core.api.application_entitlements import ApplicationEntitlementVi
|
|||||||
from authentik.core.api.applications import ApplicationViewSet
|
from authentik.core.api.applications import ApplicationViewSet
|
||||||
from authentik.core.api.authenticated_sessions import AuthenticatedSessionViewSet
|
from authentik.core.api.authenticated_sessions import AuthenticatedSessionViewSet
|
||||||
from authentik.core.api.devices import AdminDeviceViewSet, DeviceViewSet
|
from authentik.core.api.devices import AdminDeviceViewSet, DeviceViewSet
|
||||||
|
from authentik.core.api.files import FileViewSet
|
||||||
from authentik.core.api.groups import GroupViewSet
|
from authentik.core.api.groups import GroupViewSet
|
||||||
from authentik.core.api.property_mappings import PropertyMappingViewSet
|
from authentik.core.api.property_mappings import PropertyMappingViewSet
|
||||||
from authentik.core.api.providers import ProviderViewSet
|
from authentik.core.api.providers import ProviderViewSet
|
||||||
@ -78,6 +79,7 @@ api_urlpatterns = [
|
|||||||
TransactionalApplicationView.as_view(),
|
TransactionalApplicationView.as_view(),
|
||||||
name="core-transactional-application",
|
name="core-transactional-application",
|
||||||
),
|
),
|
||||||
|
("core/files", FileViewSet),
|
||||||
("core/groups", GroupViewSet),
|
("core/groups", GroupViewSet),
|
||||||
("core/users", UserViewSet),
|
("core/users", UserViewSet),
|
||||||
("core/tokens", TokenViewSet),
|
("core/tokens", TokenViewSet),
|
||||||
|
14
go.mod
14
go.mod
@ -62,6 +62,12 @@ require (
|
|||||||
github.com/go-openapi/validate v0.24.0 // indirect
|
github.com/go-openapi/validate v0.24.0 // indirect
|
||||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
|
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
|
github.com/jackc/pgx/v5 v5.7.5 // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/klauspost/compress v1.18.0 // indirect
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
@ -77,9 +83,11 @@ require (
|
|||||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.36.0 // indirect
|
golang.org/x/crypto v0.39.0 // indirect
|
||||||
golang.org/x/sys v0.31.0 // indirect
|
golang.org/x/sys v0.33.0 // indirect
|
||||||
golang.org/x/text v0.24.0 // indirect
|
golang.org/x/text v0.26.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.5 // indirect
|
google.golang.org/protobuf v1.36.5 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
gorm.io/driver/postgres v1.6.0 // indirect
|
||||||
|
gorm.io/gorm v1.30.0 // indirect
|
||||||
)
|
)
|
||||||
|
22
go.sum
22
go.sum
@ -191,6 +191,14 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
|
github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
|
||||||
|
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||||
@ -205,6 +213,10 @@ github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZ
|
|||||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||||
github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc=
|
github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc=
|
||||||
github.com/jellydator/ttlcache/v3 v3.3.0/go.mod h1:bj2/e0l4jRnQdrnSTaGTsh4GSXvMjQcy41i7th0GVGw=
|
github.com/jellydator/ttlcache/v3 v3.3.0/go.mod h1:bj2/e0l4jRnQdrnSTaGTsh4GSXvMjQcy41i7th0GVGw=
|
||||||
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
@ -308,6 +320,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
|||||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||||
|
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||||
|
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@ -415,6 +429,8 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
|
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||||
|
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
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=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -422,6 +438,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||||
|
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||||
|
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@ -555,6 +573,10 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=
|
||||||
|
gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=
|
||||||
|
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
|
||||||
|
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
@ -5,6 +5,7 @@ type Config struct {
|
|||||||
Storage StorageConfig `yaml:"storage"`
|
Storage StorageConfig `yaml:"storage"`
|
||||||
LogLevel string `yaml:"log_level" env:"AUTHENTIK_LOG_LEVEL, overwrite"`
|
LogLevel string `yaml:"log_level" env:"AUTHENTIK_LOG_LEVEL, overwrite"`
|
||||||
ErrorReporting ErrorReportingConfig `yaml:"error_reporting" env:", prefix=AUTHENTIK_ERROR_REPORTING__"`
|
ErrorReporting ErrorReportingConfig `yaml:"error_reporting" env:", prefix=AUTHENTIK_ERROR_REPORTING__"`
|
||||||
|
Postgresql PostgresqlConfig `yaml:"postgresql" env:", prefix=AUTHENTIK_POSTGRESQL__"`
|
||||||
Redis RedisConfig `yaml:"redis" env:", prefix=AUTHENTIK_REDIS__"`
|
Redis RedisConfig `yaml:"redis" env:", prefix=AUTHENTIK_REDIS__"`
|
||||||
Outposts OutpostConfig `yaml:"outposts" env:", prefix=AUTHENTIK_OUTPOSTS__"`
|
Outposts OutpostConfig `yaml:"outposts" env:", prefix=AUTHENTIK_OUTPOSTS__"`
|
||||||
|
|
||||||
@ -25,6 +26,16 @@ type Config struct {
|
|||||||
AuthentikInsecure bool `env:"AUTHENTIK_INSECURE"`
|
AuthentikInsecure bool `env:"AUTHENTIK_INSECURE"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: SSL
|
||||||
|
type PostgresqlConfig struct {
|
||||||
|
Host string `yaml:"host" env:"HOST, overwrite"`
|
||||||
|
Port string `yaml:"port" env:"PORT, overwrite"`
|
||||||
|
User string `yaml:"user" env:"USER, overwrite"`
|
||||||
|
Password string `yaml:"password" env:"PASSWORD, overwrite"`
|
||||||
|
Name string `yaml:"name" env:"NAME, overwrite"`
|
||||||
|
DefaultSchema string `yaml:"default_schema" env:"DEFAULT_SCHEMA, overwrite"`
|
||||||
|
}
|
||||||
|
|
||||||
type RedisConfig struct {
|
type RedisConfig struct {
|
||||||
Host string `yaml:"host" env:"HOST, overwrite"`
|
Host string `yaml:"host" env:"HOST, overwrite"`
|
||||||
Port int `yaml:"port" env:"PORT, overwrite"`
|
Port int `yaml:"port" env:"PORT, overwrite"`
|
||||||
|
62
internal/web/files.go
Normal file
62
internal/web/files.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package web
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-http-utils/etag"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
|
"goauthentik.io/internal/config"
|
||||||
|
"goauthentik.io/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
type File struct {
|
||||||
|
ID string `gorm:"primaryKey"`
|
||||||
|
|
||||||
|
Name string
|
||||||
|
Content []byte
|
||||||
|
Location string
|
||||||
|
Public bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) configureFiles() {
|
||||||
|
// Setup routers
|
||||||
|
filesRouter := ws.loggingRouter.NewRoute().Subrouter()
|
||||||
|
filesRouter.Use(ws.filesHeaderMiddleware)
|
||||||
|
|
||||||
|
filesRouter.PathPrefix(config.Get().Web.Path).PathPrefix("/files/public/{pk}").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
|
pk := vars["pk"]
|
||||||
|
|
||||||
|
var file File
|
||||||
|
ws.postgresClient.First(&file, "id = ? AND public = true AND content <> NULL", pk)
|
||||||
|
|
||||||
|
// TODO: get from DB
|
||||||
|
rw.Write(file.Content)
|
||||||
|
})
|
||||||
|
|
||||||
|
filesRouter.PathPrefix(config.Get().Web.Path).PathPrefix("/files/private/{pk}").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
|
// TODO: check session
|
||||||
|
|
||||||
|
pk := vars["pk"]
|
||||||
|
|
||||||
|
var file File
|
||||||
|
ws.postgresClient.First(&file, "id = ? AND content <> NULL", pk)
|
||||||
|
|
||||||
|
rw.Write([]byte(file.Content))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: anything else?
|
||||||
|
func (ws *WebServer) filesHeaderMiddleware(h http.Handler) http.Handler {
|
||||||
|
etagHandler := etag.Handler(h, false)
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Cache-Control", "public, no-transform")
|
||||||
|
w.Header().Set("X-authentik-version", constants.VERSION)
|
||||||
|
w.Header().Set("Vary", "X-authentik-version, Etag")
|
||||||
|
etagHandler.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
@ -17,6 +17,8 @@ import (
|
|||||||
"github.com/gorilla/securecookie"
|
"github.com/gorilla/securecookie"
|
||||||
"github.com/pires/go-proxyproto"
|
"github.com/pires/go-proxyproto"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"goauthentik.io/api/v3"
|
"goauthentik.io/api/v3"
|
||||||
"goauthentik.io/internal/config"
|
"goauthentik.io/internal/config"
|
||||||
@ -49,6 +51,7 @@ type WebServer struct {
|
|||||||
mainRouter *mux.Router
|
mainRouter *mux.Router
|
||||||
loggingRouter *mux.Router
|
loggingRouter *mux.Router
|
||||||
log *log.Entry
|
log *log.Entry
|
||||||
|
postgresClient *gorm.DB
|
||||||
upstreamClient *http.Client
|
upstreamClient *http.Client
|
||||||
upstreamURL *url.URL
|
upstreamURL *url.URL
|
||||||
|
|
||||||
@ -64,6 +67,21 @@ func NewWebServer() *WebServer {
|
|||||||
loggingHandler := mainHandler.NewRoute().Subrouter()
|
loggingHandler := mainHandler.NewRoute().Subrouter()
|
||||||
loggingHandler.Use(web.NewLoggingHandler(l, nil))
|
loggingHandler.Use(web.NewLoggingHandler(l, nil))
|
||||||
|
|
||||||
|
// TODO: ssl
|
||||||
|
postgresDsn := fmt.Sprintf(
|
||||||
|
"host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
|
||||||
|
config.Get().Postgresql.Host,
|
||||||
|
config.Get().Postgresql.Port,
|
||||||
|
config.Get().Postgresql.User,
|
||||||
|
config.Get().Postgresql.Password,
|
||||||
|
config.Get().Postgresql.Name,
|
||||||
|
)
|
||||||
|
|
||||||
|
db, err := gorm.Open(postgres.Open(postgresDsn), &gorm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
tmp := os.TempDir()
|
tmp := os.TempDir()
|
||||||
socketPath := path.Join(tmp, UnixSocketName)
|
socketPath := path.Join(tmp, UnixSocketName)
|
||||||
|
|
||||||
@ -88,6 +106,7 @@ func NewWebServer() *WebServer {
|
|||||||
mainRouter: mainHandler,
|
mainRouter: mainHandler,
|
||||||
loggingRouter: loggingHandler,
|
loggingRouter: loggingHandler,
|
||||||
log: l,
|
log: l,
|
||||||
|
postgresClient: db,
|
||||||
gunicornReady: false,
|
gunicornReady: false,
|
||||||
upstreamClient: upstreamClient,
|
upstreamClient: upstreamClient,
|
||||||
upstreamURL: u,
|
upstreamURL: u,
|
||||||
|
Reference in New Issue
Block a user