mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 03:47:33 +00:00
feat: restrict languages (#6931)
* feat: return 404 or 409 if org reg disallowed * fix: system limit permissions * feat: add iam limits api * feat: disallow public org registrations on default instance * add integration test * test: integration * fix test * docs: describe public org registrations * avoid updating docs deps * fix system limits integration test * silence integration tests * fix linting * ignore strange linter complaints * review * improve reset properties naming * redefine the api * use restrictions aggregate * test query * simplify and test projection * test commands * fix unit tests * move integration test * support restrictions on default instance * also test GetRestrictions * self review * lint * abstract away resource owner * fix tests * configure supported languages * fix allowed languages * fix tests * default lang must not be restricted * preferred language must be allowed * change preferred languages * check languages everywhere * lint * test command side * lint * add integration test * add integration test * restrict supported ui locales * lint * lint * cleanup * lint * allow undefined preferred language * fix integration tests * update main * fix env var * ignore linter * ignore linter * improve integration test config * reduce cognitive complexity * compile * check for duplicates * remove useless restriction checks * review * revert restriction renaming * fix language restrictions * lint * generate * allow custom texts for supported langs for now * fix tests * cleanup * cleanup * cleanup * lint * unsupported preferred lang is allowed * fix integration test * finish reverting to old property name * finish reverting to old property name * load languages * refactor(i18n): centralize translators and fs * lint * amplify no validations on preferred languages * fix integration test * lint * fix resetting allowed languages * test unchanged restrictions
This commit is contained in:
@@ -6,11 +6,9 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/rakyll/statik/fs"
|
||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||
"github.com/zitadel/oidc/v3/pkg/op"
|
||||
"golang.org/x/exp/slog"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/assets"
|
||||
http_utils "github.com/zitadel/zitadel/internal/api/http"
|
||||
@@ -23,7 +21,6 @@ import (
|
||||
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
|
||||
"github.com/zitadel/zitadel/internal/i18n"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/telemetry/metrics"
|
||||
)
|
||||
@@ -167,10 +164,6 @@ func ignoredQuotaLimitEndpoint(endpoints *EndpointConfig) []string {
|
||||
}
|
||||
|
||||
func createOPConfig(config Config, defaultLogoutRedirectURI string, cryptoKey []byte) (*op.Config, error) {
|
||||
supportedLanguages, err := getSupportedLanguages()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opConfig := &op.Config{
|
||||
DefaultLogoutRedirectURI: defaultLogoutRedirectURI,
|
||||
CodeMethodS256: config.CodeMethodS256,
|
||||
@@ -178,7 +171,6 @@ func createOPConfig(config Config, defaultLogoutRedirectURI string, cryptoKey []
|
||||
AuthMethodPrivateKeyJWT: config.AuthMethodPrivateKeyJWT,
|
||||
GrantTypeRefreshToken: config.GrantTypeRefreshToken,
|
||||
RequestObjectSupported: config.RequestObjectSupported,
|
||||
SupportedUILocales: supportedLanguages,
|
||||
DeviceAuthorization: config.DeviceAuth.toOPConfig(),
|
||||
}
|
||||
if cryptoLength := len(cryptoKey); cryptoLength != 32 {
|
||||
@@ -211,11 +203,3 @@ func newStorage(config Config, command *command.Commands, query *query.Queries,
|
||||
func (o *OPStorage) Health(ctx context.Context) error {
|
||||
return o.repo.Health(ctx)
|
||||
}
|
||||
|
||||
func getSupportedLanguages() ([]language.Tag, error) {
|
||||
statikLoginFS, err := fs.NewWithNamespace("login")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i18n.SupportedLanguages(statikLoginFS)
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/auth/repository"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/i18n"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
@@ -103,8 +104,15 @@ func (s *Server) Ready(ctx context.Context, r *op.Request[struct{}]) (_ *op.Resp
|
||||
func (s *Server) Discovery(ctx context.Context, r *op.Request[struct{}]) (_ *op.Response, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
return op.NewResponse(s.createDiscoveryConfig(ctx)), nil
|
||||
restrictions, err := s.query.GetInstanceRestrictions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allowedLanguages := restrictions.AllowedLanguages
|
||||
if len(allowedLanguages) == 0 {
|
||||
allowedLanguages = i18n.SupportedLanguages()
|
||||
}
|
||||
return op.NewResponse(s.createDiscoveryConfig(ctx, allowedLanguages)), nil
|
||||
}
|
||||
|
||||
func (s *Server) Keys(ctx context.Context, r *op.Request[struct{}]) (_ *op.Response, err error) {
|
||||
@@ -205,7 +213,7 @@ func (s *Server) EndSession(ctx context.Context, r *op.Request[oidc.EndSessionRe
|
||||
return s.LegacyServer.EndSession(ctx, r)
|
||||
}
|
||||
|
||||
func (s *Server) createDiscoveryConfig(ctx context.Context) *oidc.DiscoveryConfiguration {
|
||||
func (s *Server) createDiscoveryConfig(ctx context.Context, supportedUILocales oidc.Locales) *oidc.DiscoveryConfiguration {
|
||||
issuer := op.IssuerFromContext(ctx)
|
||||
return &oidc.DiscoveryConfiguration{
|
||||
Issuer: issuer,
|
||||
@@ -231,7 +239,7 @@ func (s *Server) createDiscoveryConfig(ctx context.Context) *oidc.DiscoveryConfi
|
||||
RevocationEndpointAuthMethodsSupported: op.AuthMethodsRevocationEndpoint(s.Provider()),
|
||||
ClaimsSupported: op.SupportedClaims(s.Provider()),
|
||||
CodeChallengeMethodsSupported: op.CodeChallengeMethods(s.Provider()),
|
||||
UILocalesSupported: s.Provider().SupportedUILocales(),
|
||||
UILocalesSupported: supportedUILocales,
|
||||
RequestParameterSupported: s.Provider().RequestObjectSupported(),
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,8 @@ func TestServer_createDiscoveryConfig(t *testing.T) {
|
||||
signingKeyAlgorithm string
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
ctx context.Context
|
||||
supportedUILocales []language.Tag
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -36,7 +37,6 @@ func TestServer_createDiscoveryConfig(t *testing.T) {
|
||||
AuthMethodPrivateKeyJWT: true,
|
||||
GrantTypeRefreshToken: true,
|
||||
RequestObjectSupported: true,
|
||||
SupportedUILocales: []language.Tag{language.English, language.German},
|
||||
},
|
||||
nil,
|
||||
)
|
||||
@@ -56,7 +56,8 @@ func TestServer_createDiscoveryConfig(t *testing.T) {
|
||||
signingKeyAlgorithm: "RS256",
|
||||
},
|
||||
args{
|
||||
ctx: op.ContextWithIssuer(context.Background(), "https://issuer.com"),
|
||||
ctx: op.ContextWithIssuer(context.Background(), "https://issuer.com"),
|
||||
supportedUILocales: []language.Tag{language.English, language.German},
|
||||
},
|
||||
&oidc.DiscoveryConfiguration{
|
||||
Issuer: "https://issuer.com",
|
||||
@@ -113,7 +114,7 @@ func TestServer_createDiscoveryConfig(t *testing.T) {
|
||||
LegacyServer: tt.fields.LegacyServer,
|
||||
signingKeyAlgorithm: tt.fields.signingKeyAlgorithm,
|
||||
}
|
||||
assert.Equalf(t, tt.want, s.createDiscoveryConfig(tt.args.ctx), "createDiscoveryConfig(%v)", tt.args.ctx)
|
||||
assert.Equalf(t, tt.want, s.createDiscoveryConfig(tt.args.ctx, tt.args.supportedUILocales), "createDiscoveryConfig(%v)", tt.args.ctx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user