Compare commits
	
		
			3 Commits
		
	
	
		
			version/20
			...
			root/maint
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 182d264029 | |||
| 9f1cde18b2 | |||
| e7cfe5343a | 
							
								
								
									
										9
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								Makefile
									
									
									
									
									
								
							@ -149,7 +149,7 @@ gen-client-ts: gen-clean-ts  ## Build and install the authentik API for Typescri
 | 
			
		||||
	docker run \
 | 
			
		||||
		--rm -v ${PWD}:/local \
 | 
			
		||||
		--user ${UID}:${GID} \
 | 
			
		||||
		docker.io/openapitools/openapi-generator-cli:v6.5.0 generate \
 | 
			
		||||
		docker.io/openapitools/openapi-generator-cli:v7.10.0 generate \
 | 
			
		||||
		-i /local/schema.yml \
 | 
			
		||||
		-g typescript-fetch \
 | 
			
		||||
		-o /local/${GEN_API_TS} \
 | 
			
		||||
@ -165,7 +165,7 @@ gen-client-py: gen-clean-py ## Build and install the authentik API for Python
 | 
			
		||||
	docker run \
 | 
			
		||||
		--rm -v ${PWD}:/local \
 | 
			
		||||
		--user ${UID}:${GID} \
 | 
			
		||||
		docker.io/openapitools/openapi-generator-cli:v7.4.0 generate \
 | 
			
		||||
		docker.io/openapitools/openapi-generator-cli:v7.10.0 generate \
 | 
			
		||||
		-i /local/schema.yml \
 | 
			
		||||
		-g python \
 | 
			
		||||
		-o /local/${GEN_API_PY} \
 | 
			
		||||
@ -184,13 +184,14 @@ gen-client-go: gen-clean-go  ## Build and install the authentik API for Golang
 | 
			
		||||
	docker run \
 | 
			
		||||
		--rm -v ${PWD}/${GEN_API_GO}:/local \
 | 
			
		||||
		--user ${UID}:${GID} \
 | 
			
		||||
		docker.io/openapitools/openapi-generator-cli:v6.5.0 generate \
 | 
			
		||||
		docker.io/openapitools/openapi-generator-cli:v7.10.0 generate \
 | 
			
		||||
		-i /local/schema.yml \
 | 
			
		||||
		-g go \
 | 
			
		||||
		-o /local/ \
 | 
			
		||||
		-c /local/config.yaml
 | 
			
		||||
	go mod edit -replace goauthentik.io/api/v3=./${GEN_API_GO}
 | 
			
		||||
	rm -rf ./${GEN_API_GO}/config.yaml ./${GEN_API_GO}/templates/
 | 
			
		||||
	rm -rf ./${GEN_API_GO}/config.yaml ./${GEN_API_GO}/templates/ ./${GEN_API_GO}/test
 | 
			
		||||
	go run golang.org/x/tools/cmd/goimports@latest -w ./${GEN_API_GO}
 | 
			
		||||
 | 
			
		||||
gen-dev-config:  ## Generate a local development config file
 | 
			
		||||
	python -m scripts.generate_config
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@ -29,7 +29,7 @@ require (
 | 
			
		||||
	github.com/spf13/cobra v1.8.1
 | 
			
		||||
	github.com/stretchr/testify v1.9.0
 | 
			
		||||
	github.com/wwt/guac v1.3.2
 | 
			
		||||
	goauthentik.io/api/v3 v3.2024102.2
 | 
			
		||||
	goauthentik.io/api/v3 v3.2024102.3
 | 
			
		||||
	golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
 | 
			
		||||
	golang.org/x/oauth2 v0.24.0
 | 
			
		||||
	golang.org/x/sync v0.9.0
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							@ -299,8 +299,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
 | 
			
		||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
 | 
			
		||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 | 
			
		||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 | 
			
		||||
goauthentik.io/api/v3 v3.2024102.2 h1:k2sIU7TkT2fOomBYo5KEc/mz5ipzaZUp5TuEOJLPX4g=
 | 
			
		||||
goauthentik.io/api/v3 v3.2024102.2/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
 | 
			
		||||
goauthentik.io/api/v3 v3.2024102.3 h1:akjkJMS7tj4Df/oRb0kylkZnRYskRhereXXbhvcvi1g=
 | 
			
		||||
goauthentik.io/api/v3 v3.2024102.3/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
			
		||||
 | 
			
		||||
@ -80,7 +80,7 @@ func NewAPIController(akURL url.URL, token string) *APIController {
 | 
			
		||||
	var outposts *api.PaginatedOutpostList
 | 
			
		||||
	var err error
 | 
			
		||||
	for {
 | 
			
		||||
		outposts, _, err = apiClient.OutpostsApi.OutpostsInstancesList(context.Background()).Execute()
 | 
			
		||||
		outposts, _, err = apiClient.OutpostsAPI.OutpostsInstancesList(context.Background()).Execute()
 | 
			
		||||
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			break
 | 
			
		||||
@ -96,7 +96,7 @@ func NewAPIController(akURL url.URL, token string) *APIController {
 | 
			
		||||
 | 
			
		||||
	log.WithField("name", outpost.Name).Debug("Fetched outpost configuration")
 | 
			
		||||
 | 
			
		||||
	akConfig, _, err := apiClient.RootApi.RootConfigRetrieve(context.Background()).Execute()
 | 
			
		||||
	akConfig, _, err := apiClient.RootAPI.RootConfigRetrieve(context.Background()).Execute()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.WithError(err).Error("Failed to fetch global configuration")
 | 
			
		||||
		return nil
 | 
			
		||||
@ -174,7 +174,7 @@ func (a *APIController) Token() string {
 | 
			
		||||
func (a *APIController) OnRefresh() error {
 | 
			
		||||
	// Because we don't know the outpost UUID, we simply do a list and pick the first
 | 
			
		||||
	// The service account this token belongs to should only have access to a single outpost
 | 
			
		||||
	outposts, _, err := a.Client.OutpostsApi.OutpostsInstancesList(context.Background()).Execute()
 | 
			
		||||
	outposts, _, err := a.Client.OutpostsAPI.OutpostsInstancesList(context.Background()).Execute()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.WithError(err).Error("Failed to fetch outpost configuration")
 | 
			
		||||
		return err
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CryptoStore struct {
 | 
			
		||||
	api *api.CryptoApiService
 | 
			
		||||
	api *api.CryptoAPIService
 | 
			
		||||
 | 
			
		||||
	log *log.Entry
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ type CryptoStore struct {
 | 
			
		||||
	certificates map[string]*tls.Certificate
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewCryptoStore(cryptoApi *api.CryptoApiService) *CryptoStore {
 | 
			
		||||
func NewCryptoStore(cryptoApi *api.CryptoAPIService) *CryptoStore {
 | 
			
		||||
	return &CryptoStore{
 | 
			
		||||
		api:          cryptoApi,
 | 
			
		||||
		log:          log.WithField("logger", "authentik.outpost.cryptostore"),
 | 
			
		||||
 | 
			
		||||
@ -139,7 +139,7 @@ func (fe *FlowExecutor) SetSession(s *http.Cookie) {
 | 
			
		||||
func (fe *FlowExecutor) WarmUp() error {
 | 
			
		||||
	gcsp := sentry.StartSpan(fe.Context, "authentik.outposts.flow_executor.get_challenge")
 | 
			
		||||
	defer gcsp.Finish()
 | 
			
		||||
	req := fe.api.FlowsApi.FlowsExecutorGet(gcsp.Context(), fe.flowSlug).Query(fe.Params.Encode())
 | 
			
		||||
	req := fe.api.FlowsAPI.FlowsExecutorGet(gcsp.Context(), fe.flowSlug).Query(fe.Params.Encode())
 | 
			
		||||
	_, _, err := req.Execute()
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
@ -156,7 +156,7 @@ func (fe *FlowExecutor) Execute() (bool, error) {
 | 
			
		||||
func (fe *FlowExecutor) getInitialChallenge() (*api.ChallengeTypes, error) {
 | 
			
		||||
	// Get challenge
 | 
			
		||||
	gcsp := sentry.StartSpan(fe.Context, "authentik.outposts.flow_executor.get_challenge")
 | 
			
		||||
	req := fe.api.FlowsApi.FlowsExecutorGet(gcsp.Context(), fe.flowSlug).Query(fe.Params.Encode())
 | 
			
		||||
	req := fe.api.FlowsAPI.FlowsExecutorGet(gcsp.Context(), fe.flowSlug).Query(fe.Params.Encode())
 | 
			
		||||
	challenge, _, err := req.Execute()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
@ -179,7 +179,7 @@ func (fe *FlowExecutor) getInitialChallenge() (*api.ChallengeTypes, error) {
 | 
			
		||||
func (fe *FlowExecutor) solveFlowChallenge(challenge *api.ChallengeTypes, depth int) (bool, error) {
 | 
			
		||||
	// Resole challenge
 | 
			
		||||
	scsp := sentry.StartSpan(fe.Context, "authentik.outposts.flow_executor.solve_challenge")
 | 
			
		||||
	responseReq := fe.api.FlowsApi.FlowsExecutorSolve(scsp.Context(), fe.flowSlug).Query(fe.Params.Encode())
 | 
			
		||||
	responseReq := fe.api.FlowsAPI.FlowsExecutorSolve(scsp.Context(), fe.flowSlug).Query(fe.Params.Encode())
 | 
			
		||||
	i := challenge.GetActualInstance()
 | 
			
		||||
	if i == nil {
 | 
			
		||||
		return false, errors.New("response request instance was null")
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,7 @@ func (db *DirectBinder) Bind(username string, req *bind.Request) (ldap.LDAPResul
 | 
			
		||||
		return ldap.LDAPResultInvalidCredentials, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	access, _, err := fe.ApiClient().OutpostsApi.OutpostsLdapAccessCheck(
 | 
			
		||||
	access, _, err := fe.ApiClient().OutpostsAPI.OutpostsLdapAccessCheck(
 | 
			
		||||
		req.Context(), db.si.GetProviderID(),
 | 
			
		||||
	).AppSlug(db.si.GetAppSlug()).Execute()
 | 
			
		||||
	if !access.Access.Passing {
 | 
			
		||||
@ -84,7 +84,7 @@ func (db *DirectBinder) Bind(username string, req *bind.Request) (ldap.LDAPResul
 | 
			
		||||
	req.Log().Info("User has access")
 | 
			
		||||
	uisp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.bind.user_info")
 | 
			
		||||
	// Get user info to store in context
 | 
			
		||||
	userInfo, _, err := fe.ApiClient().CoreApi.CoreUsersMeRetrieve(context.Background()).Execute()
 | 
			
		||||
	userInfo, _, err := fe.ApiClient().CoreAPI.CoreUsersMeRetrieve(context.Background()).Execute()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		metrics.RequestsRejected.With(prometheus.Labels{
 | 
			
		||||
			"outpost_name": db.si.GetOutpostName(),
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ func NewServer(ac *ak.APIController) *LDAPServer {
 | 
			
		||||
	ls := &LDAPServer{
 | 
			
		||||
		log:       log.WithField("logger", "authentik.outpost.ldap"),
 | 
			
		||||
		ac:        ac,
 | 
			
		||||
		cs:        ak.NewCryptoStore(ac.Client.CryptoApi),
 | 
			
		||||
		cs:        ak.NewCryptoStore(ac.Client.CryptoAPI),
 | 
			
		||||
		providers: []*ProviderInstance{},
 | 
			
		||||
	}
 | 
			
		||||
	s := ldap.NewServer()
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ func (ls *LDAPServer) getCurrentProvider(pk int32) *ProviderInstance {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ls *LDAPServer) Refresh() error {
 | 
			
		||||
	apiProviders, err := ak.Paginator(ls.ac.Client.OutpostsApi.OutpostsLdapList(context.Background()), ak.PaginatorOptions{
 | 
			
		||||
	apiProviders, err := ak.Paginator(ls.ac.Client.OutpostsAPI.OutpostsLdapList(context.Background()), ak.PaginatorOptions{
 | 
			
		||||
		PageSize: 100,
 | 
			
		||||
		Logger:   ls.log,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
@ -113,7 +113,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult,
 | 
			
		||||
		errs.Go(func() error {
 | 
			
		||||
			if flags.CanSearch {
 | 
			
		||||
				uapisp := sentry.StartSpan(errCtx, "authentik.providers.ldap.search.api_user")
 | 
			
		||||
				searchReq, skip := utils.ParseFilterForUser(c.CoreApi.CoreUsersList(uapisp.Context()).IncludeGroups(true), parsedFilter, false)
 | 
			
		||||
				searchReq, skip := utils.ParseFilterForUser(c.CoreAPI.CoreUsersList(uapisp.Context()).IncludeGroups(true), parsedFilter, false)
 | 
			
		||||
 | 
			
		||||
				if skip {
 | 
			
		||||
					req.Log().Trace("Skip backend request")
 | 
			
		||||
@ -132,7 +132,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult,
 | 
			
		||||
			} else {
 | 
			
		||||
				if flags.UserInfo == nil {
 | 
			
		||||
					uapisp := sentry.StartSpan(errCtx, "authentik.providers.ldap.search.api_user")
 | 
			
		||||
					u, _, err := c.CoreApi.CoreUsersRetrieve(uapisp.Context(), flags.UserPk).Execute()
 | 
			
		||||
					u, _, err := c.CoreAPI.CoreUsersRetrieve(uapisp.Context(), flags.UserPk).Execute()
 | 
			
		||||
					uapisp.Finish()
 | 
			
		||||
 | 
			
		||||
					if err != nil {
 | 
			
		||||
@ -155,7 +155,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult,
 | 
			
		||||
	if needGroups {
 | 
			
		||||
		errs.Go(func() error {
 | 
			
		||||
			gapisp := sentry.StartSpan(errCtx, "authentik.providers.ldap.search.api_group")
 | 
			
		||||
			searchReq, skip := utils.ParseFilterForGroup(c.CoreApi.CoreGroupsList(gapisp.Context()).IncludeUsers(true), parsedFilter, false)
 | 
			
		||||
			searchReq, skip := utils.ParseFilterForGroup(c.CoreAPI.CoreGroupsList(gapisp.Context()).IncludeUsers(true), parsedFilter, false)
 | 
			
		||||
			if skip {
 | 
			
		||||
				req.Log().Trace("Skip backend request")
 | 
			
		||||
				return nil
 | 
			
		||||
 | 
			
		||||
@ -39,12 +39,12 @@ func NewMemorySearcher(si server.LDAPServerInstance) *MemorySearcher {
 | 
			
		||||
	}
 | 
			
		||||
	ms.log.Debug("initialised memory searcher")
 | 
			
		||||
	// Error is not handled here, we get an empty/truncated list and the error is logged
 | 
			
		||||
	users, _ := ak.Paginator(ms.si.GetAPIClient().CoreApi.CoreUsersList(context.TODO()).IncludeGroups(true), ak.PaginatorOptions{
 | 
			
		||||
	users, _ := ak.Paginator(ms.si.GetAPIClient().CoreAPI.CoreUsersList(context.TODO()).IncludeGroups(true), ak.PaginatorOptions{
 | 
			
		||||
		PageSize: 100,
 | 
			
		||||
		Logger:   ms.log,
 | 
			
		||||
	})
 | 
			
		||||
	ms.users = users
 | 
			
		||||
	groups, _ := ak.Paginator(ms.si.GetAPIClient().CoreApi.CoreGroupsList(context.TODO()).IncludeUsers(true), ak.PaginatorOptions{
 | 
			
		||||
	groups, _ := ak.Paginator(ms.si.GetAPIClient().CoreAPI.CoreGroupsList(context.TODO()).IncludeUsers(true), ak.PaginatorOptions{
 | 
			
		||||
		PageSize: 100,
 | 
			
		||||
		Logger:   ms.log,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
@ -120,7 +120,7 @@ func (a *Application) ReportMisconfiguration(r *http.Request, msg string, fields
 | 
			
		||||
		ClientIp: *api.NewNullableString(api.PtrString(r.RemoteAddr)),
 | 
			
		||||
		Context:  fields,
 | 
			
		||||
	}
 | 
			
		||||
	_, _, err := a.ak.Client.EventsApi.EventsEventsCreate(context.Background()).EventRequest(req).Execute()
 | 
			
		||||
	_, _, err := a.ak.Client.EventsAPI.EventsEventsCreate(context.Background()).EventRequest(req).Execute()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		a.log.WithError(err).Warning("failed to report configuration error")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ func NewProxyServer(ac *ak.APIController) *ProxyServer {
 | 
			
		||||
		globalMux.Use(sentryhttp.New(sentryhttp.Options{}).Handle)
 | 
			
		||||
	}
 | 
			
		||||
	s := &ProxyServer{
 | 
			
		||||
		cryptoStore: ak.NewCryptoStore(ac.Client.CryptoApi),
 | 
			
		||||
		cryptoStore: ak.NewCryptoStore(ac.Client.CryptoAPI),
 | 
			
		||||
		apps:        make(map[string]*application.Application),
 | 
			
		||||
		log:         l,
 | 
			
		||||
		mux:         rootMux,
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (ps *ProxyServer) Refresh() error {
 | 
			
		||||
	providers, err := ak.Paginator(ps.akAPI.Client.OutpostsApi.OutpostsProxyList(context.Background()), ak.PaginatorOptions{
 | 
			
		||||
	providers, err := ak.Paginator(ps.akAPI.Client.OutpostsAPI.OutpostsProxyList(context.Background()), ak.PaginatorOptions{
 | 
			
		||||
		PageSize: 100,
 | 
			
		||||
		Logger:   ps.log,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,7 @@ func parseCIDRs(raw string) []*net.IPNet {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rs *RadiusServer) Refresh() error {
 | 
			
		||||
	apiProviders, err := ak.Paginator(rs.ac.Client.OutpostsApi.OutpostsRadiusList(context.Background()), ak.PaginatorOptions{
 | 
			
		||||
	apiProviders, err := ak.Paginator(rs.ac.Client.OutpostsAPI.OutpostsRadiusList(context.Background()), ak.PaginatorOptions{
 | 
			
		||||
		PageSize: 100,
 | 
			
		||||
		Logger:   rs.log,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ func (rs *RadiusServer) Handle_AccessRequest(w radius.ResponseWriter, r *RadiusR
 | 
			
		||||
		_ = w.Write(r.Response(radius.CodeAccessReject))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	access, _, err := fe.ApiClient().OutpostsApi.OutpostsRadiusAccessCheck(
 | 
			
		||||
	access, _, err := fe.ApiClient().OutpostsAPI.OutpostsRadiusAccessCheck(
 | 
			
		||||
		r.Context(), r.pi.providerId,
 | 
			
		||||
	).AppSlug(r.pi.appSlug).Execute()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ type Watcher struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewWatcher(client *api.APIClient) *Watcher {
 | 
			
		||||
	cs := ak.NewCryptoStore(client.CryptoApi)
 | 
			
		||||
	cs := ak.NewCryptoStore(client.CryptoAPI)
 | 
			
		||||
	l := log.WithField("logger", "authentik.router.brand_tls")
 | 
			
		||||
	cert, err := crypto.GenerateSelfSignedCert()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@ -47,7 +47,7 @@ func (w *Watcher) Start() {
 | 
			
		||||
 | 
			
		||||
func (w *Watcher) Check() {
 | 
			
		||||
	w.log.Info("updating brand certificates")
 | 
			
		||||
	brands, err := ak.Paginator(w.client.CoreApi.CoreBrandsList(context.Background()), ak.PaginatorOptions{
 | 
			
		||||
	brands, err := ak.Paginator(w.client.CoreAPI.CoreBrandsList(context.Background()), ak.PaginatorOptions{
 | 
			
		||||
		PageSize: 100,
 | 
			
		||||
		Logger:   w.log,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user