diff --git a/internal/api/oidc_redirect.go b/internal/api/oidc_redirect.go index c39d2a0cb..92f307175 100644 --- a/internal/api/oidc_redirect.go +++ b/internal/api/oidc_redirect.go @@ -132,9 +132,7 @@ func OIDCRedirect(router *gin.RouterGroup) { user.Details().UserGender = clean.Name(string(userInfo.GetGender())) // Set UI locale. - if locale, _, _ := userInfo.GetLocale().Raw(); len(locale.String()) == 2 { - user.Settings().UILanguage = locale.String() - } + user.Settings().UILanguage = clean.Locale(userInfo.GetLocale().String(), "") // Set UI timezone. user.Settings().UITimeZone = userInfo.GetZoneinfo() diff --git a/pkg/clean/locale.go b/pkg/clean/locale.go new file mode 100644 index 000000000..ef14596b9 --- /dev/null +++ b/pkg/clean/locale.go @@ -0,0 +1,21 @@ +package clean + +import "strings" + +// Locale returns the normalized locale string in POSIX format with underscore, or the default locale otherwise. +// See https://en.wikipedia.org/wiki/Locale_(computer_software) for details. +func Locale(locale, defaultLocale string) string { + if locale == "" { + return defaultLocale + } + + locale, _, _ = strings.Cut(strings.Replace(locale, "-", "_", 1), ".") + + if l := len(locale); l == 2 { + return strings.ToLower(locale) + } else if l == 5 && locale[2] == '_' { + return strings.ToLower(locale[:2]) + "_" + strings.ToUpper(locale[3:]) + } + + return defaultLocale +} diff --git a/pkg/clean/locale_test.go b/pkg/clean/locale_test.go new file mode 100644 index 000000000..0c5fbec39 --- /dev/null +++ b/pkg/clean/locale_test.go @@ -0,0 +1,32 @@ +package clean + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestLocale(t *testing.T) { + t.Run("Empty", func(t *testing.T) { + assert.Equal(t, "", Locale("", "")) + assert.Equal(t, "de", Locale("", "de")) + assert.Equal(t, "und", Locale("", "und")) + }) + t.Run("Language", func(t *testing.T) { + assert.Equal(t, "de", Locale("de", "")) + assert.Equal(t, "", Locale("und", "")) + assert.Equal(t, "de", Locale("und", "de")) + assert.Equal(t, "cs", Locale("cs", "und")) + }) + t.Run("Territory", func(t *testing.T) { + assert.Equal(t, "cs_CZ", Locale("cs_CZ", "")) + assert.Equal(t, "cs_CZ", Locale("cs-CZ", "")) + assert.Equal(t, "cs_CZ", Locale("cs_cz", "")) + assert.Equal(t, "cs_CZ", Locale("cs-cz", "")) + assert.Equal(t, "cs_CZ", Locale("Cs_cz", "")) + assert.Equal(t, "cs_CZ", Locale("Cs-cz", "")) + assert.Equal(t, "cs_CZ", Locale("cs_CZ", "und")) + assert.Equal(t, "cs_CZ", Locale("cs-CZ", "und")) + assert.Equal(t, "und", Locale("cs-CZX", "und")) + }) +}