Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 1958080: CONSOLE-2535: Internationalize login page #71

Merged
merged 2 commits into from
May 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
github.com/spf13/pflag v1.0.5
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/text v0.3.4
jhadvig marked this conversation as resolved.
Show resolved Hide resolved
gopkg.in/ldap.v2 v2.5.1
k8s.io/api v0.21.0
k8s.io/apimachinery v0.21.0
Expand Down
4 changes: 4 additions & 0 deletions pkg/server/errorpage/errorpage.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"k8s.io/klog/v2"

"github.com/openshift/library-go/pkg/apiserver/httprequest"

"github.com/openshift/oauth-server/pkg/server/locales"
)

// ErrorPage implements auth and grant error handling by rendering an error page for browser-like clients
Expand Down Expand Up @@ -56,6 +58,7 @@ func (p *ErrorPage) GrantError(err error, w http.ResponseWriter, req *http.Reque
type ErrorData struct {
Error string
ErrorCode string
Locale locales.Localization
}

// ErrorPageRenderer handles rendering a given error code/message
Expand Down Expand Up @@ -88,6 +91,7 @@ func NewErrorPageTemplateRenderer(templateFile string) (ErrorPageRenderer, error
func (r *errorPageTemplateRenderer) Render(data ErrorData, w http.ResponseWriter, req *http.Request) {
w.Header().Add("Content-Type", "text/html; charset=UTF-8")
w.WriteHeader(http.StatusOK)
data.Locale = locales.GetLocale(req.Header.Get("Accept-Language"))
if err := r.errorPageTemplate.Execute(w, data); err != nil {
utilruntime.HandleError(fmt.Errorf("unable to render error page template: %v", err))
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/errorpage/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var defaultErrorPageTemplate = template.Must(template.New("defaultErrorPageTempl
const defaultErrorPageTemplateString = `<!DOCTYPE html>
<html lang="en-us" data-test-id="login">
<head>
<title>Error - OKD</title>
<title>{{ .Locale.Error }} . OKD</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="data:image/x-icon;base64,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">
Expand Down
82 changes: 82 additions & 0 deletions pkg/server/locales/locales.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package locales

import (
"golang.org/x/text/language"
"k8s.io/klog/v2"
)

type Localization map[string]string

var supportedLocalizations = map[string]Localization{
language.English.String(): locale_en,
language.Chinese.String(): locale_zh,
language.Japanese.String(): locale_ja,
language.Korean.String(): locale_ko,
}

func GetLocale(acceptLangHeader string) Localization {
locale, ok := supportedLocalizations[getPreferredLang(acceptLangHeader)]
if !ok {
return locale_en
}
return locale
}

func getPreferredLang(acceptLangHeader string) string {
matcher := language.NewMatcher(supportedLangs)
userPrefs, _, err := language.ParseAcceptLanguage(acceptLangHeader)
if err != nil {
klog.V(5).Infof("Error parsing 'Accept-Language' header, falling back to English language: %v", err)
return language.English.String()
}
tag, _, _ := matcher.Match(userPrefs...)
base, _ := tag.Base()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no language variations?

return base.String()
}

var supportedLangs = []language.Tag{
language.English, // en - first language is fallback
language.Chinese, // zh
language.Japanese, // ja
language.Korean, // ko
}

var locale_en = Localization{
"LogInToYourAccount": "Log in to your account",
"Username": "Username",
"Password": "Password",
"LogIn": "Log in",
"WelcomeTo": "Welcome to",
"LogInWith": "Log in with",
"Error": "Error",
}

var locale_zh = Localization{
"LogInToYourAccount": "登录到您的帐户",
"Username": "用户名",
"Password": "密码",
"LogIn": "登录",
"WelcomeTo": "欢迎使用",
"LogInWith": "登录使用",
"Error": "错误",
}

var locale_ja = Localization{
"LogInToYourAccount": "アカウントにログイン",
"Username": "ユーザー名",
"Password": "パスワード",
"LogIn": "ログイン",
"WelcomeTo": "ようこそ:",
"LogInWith": "ログイン:",
"Error": "エラー",
}

var locale_ko = Localization{
"LogInToYourAccount": "귀하의 계정에 로그인하십시오",
"Username": "사용자 이름",
"Password": "암호",
"LogIn": "로그인",
"WelcomeTo": "환영합니다",
"LogInWith": "로그인",
"Error": "오류",
}
52 changes: 52 additions & 0 deletions pkg/server/locales/locales_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package locales

import (
"reflect"
"testing"
)

func TestLocales(t *testing.T) {
tests := []struct {
name string
header string
locale Localization
}{
{
name: "Test empty 'Accept-Language' request header which defaults to English language",
header: "",
locale: locale_en,
},
{
name: "Test 'Accept-Language' request header which favours English language",
header: "fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5",
locale: locale_en,
},
{
name: "Test 'Accept-Language' request header which favours Japan language",
header: "ja;q=0.8, en;q=0.7",
locale: locale_ja,
},
{
name: "Test 'Accept-Language' request header which favours Korean language",
header: "ja;q=0.8, ko;q=0.9",
locale: locale_ko,
},
{
name: "Test 'Accept-Language' request header which favours Chinese language",
header: "en;q=0.3, zh;q=0.7",
locale: locale_zh,
},
{
name: "Test empty 'Accept-Language' request header which doesn't match any supported languages, so defaults to English language",
header: "fr;q=0.5, de;q=0.8",
locale: locale_en,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !reflect.DeepEqual(GetLocale(tt.header), tt.locale) {
t.Error(tt.name)
}
})
}
}
4 changes: 4 additions & 0 deletions pkg/server/login/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
metrics "github.com/openshift/oauth-server/pkg/prometheus"
"github.com/openshift/oauth-server/pkg/server/csrf"
"github.com/openshift/oauth-server/pkg/server/errorpage"
"github.com/openshift/oauth-server/pkg/server/locales"
"github.com/openshift/oauth-server/pkg/server/redirect"
)

Expand Down Expand Up @@ -63,6 +64,8 @@ type LoginForm struct {

Names LoginFormFields
Values LoginFormFields

Locale locales.Localization
}

type LoginFormFields struct {
Expand Down Expand Up @@ -128,6 +131,7 @@ func (l *Login) handleLoginForm(w http.ResponseWriter, req *http.Request) {
return
}

form.Locale = locales.GetLocale(req.Header.Get("Accept-Language"))
form.ErrorCode = req.URL.Query().Get(reasonParam)
if len(form.ErrorCode) > 0 {
if msg, hasMsg := errorMessages[form.ErrorCode]; hasMsg {
Expand Down
12 changes: 6 additions & 6 deletions pkg/server/login/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var defaultLoginTemplate = template.Must(template.New("defaultLoginForm").Parse(
const defaultLoginTemplateString = `<!DOCTYPE html>
<html lang="en-us" data-test-id="login">
<head>
<title>Login - OKD</title>
<title>{{ .Locale.LogIn }} . OKD</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="data:image/x-icon;base64,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">
Expand Down Expand Up @@ -246,7 +246,7 @@ select.pf-c-form-control.pf-m-success { --pf-c-form-control--PaddingRight: var(-
</header>
<main class="pf-c-login__main">
<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">Log in to your account</h1>
<h1 class="pf-c-title pf-m-3xl">{{ .Locale.LogInToYourAccount }}</h1>
</header>
<div class="pf-c-login__main-body">
<form class="pf-c-form" role="form" action="{{ .Action }}" method="POST">
Expand All @@ -264,26 +264,26 @@ select.pf-c-form-control.pf-m-success { --pf-c-form-control--PaddingRight: var(-
</div>
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="inputUsername">
<span class="pf-c-form__label-text">Username</span>
<span class="pf-c-form__label-text">{{ .Locale.Username }}</span>
<span class="pf-c-form__label-required" aria-hidden="true">*</span>
</label>
<input type="text" class="pf-c-form-control" id="inputUsername" placeholder="" tabindex="1" autofocus="autofocus" type="text" name="{{ .Names.Username }}" value="{{ .Values.Username }}">
</div>
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="inputPassword">
<span class="pf-c-form__label-text">Password</span>
<span class="pf-c-form__label-text">{{ .Locale.Password }}</span>
<span class="pf-c-form__label-required" aria-hidden="true">*</span>
</label>
<input type="password" class="pf-c-form-control" id="inputPassword" placeholder="" tabindex="2" type="password" name="{{ .Names.Password }}" value="">
</div>
<div class="pf-c-form__group pf-m-action">
<button class="pf-c-button pf-m-primary pf-m-block" type="submit" tabindex="3">Log in</button>
<button class="pf-c-button pf-m-primary pf-m-block" type="submit" tabindex="3">{{ .Locale.LogIn }}</button>
</div>
</form>
</div>
</main>
<footer class="pf-c-login__footer">
<p>Welcome to OKD.</p>
<p>{{ .Locale.WelcomeTo }} OKD</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we lost the product name here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did we ? I still see the OKD there, we just pulled it out of the double curly brackets.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed that. Really you're not supposed to concat strings, instead making them a parameter in the message so the order of the words can change. That might be tricky here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OKD should be in the double curly brackets.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rebeccaalpert That doesn't work here since it's a Go template and not using i18next :/

Copy link

@rebeccaalpert rebeccaalpert Apr 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bleh. Aiko did raise this as an issue re: ordering.

I let them all know the context, but it's better if we can give them good inputs from the beginning.

Copy link
Member

@sg00dwin sg00dwin Apr 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed that. Really you're not supposed to concat strings, instead making them a parameter in the message so the order of the words can change. That might be tricky here.

@jhadvig how will this need to be structured to handle translation changes to word order? eg. if locale_jp becomes OKD {{ .Locale.WelcomeTo }}

</footer>
</div>
</div>
Expand Down
5 changes: 4 additions & 1 deletion pkg/server/selectprovider/selectprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/openshift/oauth-server/pkg/api"
"github.com/openshift/oauth-server/pkg/oauth/handlers"
"github.com/openshift/oauth-server/pkg/server/locales"
)

type SelectProviderRenderer interface {
Expand All @@ -31,6 +32,7 @@ func NewSelectProvider(render SelectProviderRenderer, forceInterstitial bool) ha

type ProviderData struct {
Providers []api.ProviderInfo
Locale locales.Localization
}

// NewSelectProviderRenderer creates a select provider renderer that takes in an optional custom template to
Expand Down Expand Up @@ -108,7 +110,8 @@ type selectProviderTemplateRenderer struct {
func (r selectProviderTemplateRenderer) Render(providers []api.ProviderInfo, w http.ResponseWriter, req *http.Request) {
w.Header().Add("Content-Type", "text/html; charset=UTF-8")
w.WriteHeader(http.StatusOK)
if err := r.selectProviderTemplate.Execute(w, ProviderData{Providers: providers}); err != nil {
locale := locales.GetLocale(req.Header.Get("Accept-Language"))
if err := r.selectProviderTemplate.Execute(w, ProviderData{Providers: providers, Locale: locale}); err != nil {
utilruntime.HandleError(fmt.Errorf("unable to render select provider template: %v", err))
}
}
Loading