@ -1138,6 +1138,6 @@ class File(SerializerModel):
 | 
			
		||||
                CONFIG.get("web.path", "/")[:-1]
 | 
			
		||||
                + f"/files/{'public' if self.public else 'private'}/{self.pk}"
 | 
			
		||||
            )
 | 
			
		||||
        elif self.location.startswith("/"):
 | 
			
		||||
        elif self.location.startswith("/static"):
 | 
			
		||||
            return CONFIG.get("web.path", "/")[:-1] + self.location
 | 
			
		||||
        return self.location
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								go.mod
									
									
									
									
									
								
							@ -62,6 +62,12 @@ require (
 | 
			
		||||
	github.com/go-openapi/validate v0.24.0 // indirect
 | 
			
		||||
	github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // 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/klauspost/compress v1.18.0 // 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/metric v1.24.0 // indirect
 | 
			
		||||
	go.opentelemetry.io/otel/trace v1.24.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.36.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.31.0 // indirect
 | 
			
		||||
	golang.org/x/text v0.24.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.39.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.33.0 // indirect
 | 
			
		||||
	golang.org/x/text v0.26.0 // indirect
 | 
			
		||||
	google.golang.org/protobuf v1.36.5 // indirect
 | 
			
		||||
	gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
			
		||||
	gorm.io/driver/postgres v1.6.0 // indirect
 | 
			
		||||
	gorm.io/gorm v1.30.0 // indirect
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 | 
			
		||||
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/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
 | 
			
		||||
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/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc=
 | 
			
		||||
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/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 | 
			
		||||
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.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
 | 
			
		||||
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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 | 
			
		||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
 | 
			
		||||
@ -415,6 +429,7 @@ 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.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
 | 
			
		||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
 | 
			
		||||
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.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
@ -422,6 +437,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.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
 | 
			
		||||
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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
@ -555,6 +572,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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 | 
			
		||||
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-20190106161140-3f1c8253044a/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"`
 | 
			
		||||
	LogLevel       string               `yaml:"log_level" env:"AUTHENTIK_LOG_LEVEL, overwrite"`
 | 
			
		||||
	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__"`
 | 
			
		||||
	Outposts       OutpostConfig        `yaml:"outposts" env:", prefix=AUTHENTIK_OUTPOSTS__"`
 | 
			
		||||
 | 
			
		||||
@ -25,6 +26,16 @@ type Config struct {
 | 
			
		||||
	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 {
 | 
			
		||||
	Host      string `yaml:"host" env:"HOST, 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/pires/go-proxyproto"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"gorm.io/driver/postgres"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
 | 
			
		||||
	"goauthentik.io/api/v3"
 | 
			
		||||
	"goauthentik.io/internal/config"
 | 
			
		||||
@ -49,6 +51,7 @@ type WebServer struct {
 | 
			
		||||
	mainRouter     *mux.Router
 | 
			
		||||
	loggingRouter  *mux.Router
 | 
			
		||||
	log            *log.Entry
 | 
			
		||||
	postgresClient *gorm.DB
 | 
			
		||||
	upstreamClient *http.Client
 | 
			
		||||
	upstreamURL    *url.URL
 | 
			
		||||
 | 
			
		||||
@ -64,6 +67,21 @@ func NewWebServer() *WebServer {
 | 
			
		||||
	loggingHandler := mainHandler.NewRoute().Subrouter()
 | 
			
		||||
	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()
 | 
			
		||||
	socketPath := path.Join(tmp, UnixSocketName)
 | 
			
		||||
 | 
			
		||||
@ -88,6 +106,7 @@ func NewWebServer() *WebServer {
 | 
			
		||||
		mainRouter:     mainHandler,
 | 
			
		||||
		loggingRouter:  loggingHandler,
 | 
			
		||||
		log:            l,
 | 
			
		||||
		postgresClient: db,
 | 
			
		||||
		gunicornReady:  false,
 | 
			
		||||
		upstreamClient: upstreamClient,
 | 
			
		||||
		upstreamURL:    u,
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user