mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 01:47:33 +00:00
fix: translation (#647)
* fix: translation * fix: translation * fix: translation * fix: remove unused code * fix: log err
This commit is contained in:
@@ -43,7 +43,7 @@ func VerifyTokenAndWriteCtxData(ctx context.Context, token, orgID string, t *Tok
|
||||
}
|
||||
}
|
||||
|
||||
userID, clientID, agentID, err := verifyAccessToken(ctx, token, t, method)
|
||||
userID, clientID, agentID, prefLang, err := verifyAccessToken(ctx, token, t, method)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -54,7 +54,7 @@ func VerifyTokenAndWriteCtxData(ctx context.Context, token, orgID string, t *Tok
|
||||
if err := checkOrigin(ctx, origins); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return context.WithValue(ctx, dataKey, CtxData{UserID: userID, OrgID: orgID, ProjectID: projectID, AgentID: agentID}), nil
|
||||
return context.WithValue(ctx, dataKey, CtxData{UserID: userID, OrgID: orgID, ProjectID: projectID, AgentID: agentID, PreferredLanguage: prefLang}), nil
|
||||
}
|
||||
|
||||
func SetCtxData(ctx context.Context, ctxData CtxData) context.Context {
|
||||
|
@@ -15,8 +15,8 @@ type testVerifier struct {
|
||||
grant *Grant
|
||||
}
|
||||
|
||||
func (v *testVerifier) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, error) {
|
||||
return "userID", "agentID", nil
|
||||
func (v *testVerifier) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, error) {
|
||||
return "userID", "agentID", "de", nil
|
||||
}
|
||||
|
||||
func (v *testVerifier) ResolveGrants(ctx context.Context) (*Grant, error) {
|
||||
|
@@ -19,7 +19,7 @@ type TokenVerifier struct {
|
||||
}
|
||||
|
||||
type authZRepo interface {
|
||||
VerifyAccessToken(ctx context.Context, token, clientID string) (userID, agentID string, err error)
|
||||
VerifyAccessToken(ctx context.Context, token, clientID string) (userID, agentID, prefLang string, err error)
|
||||
VerifierClientID(ctx context.Context, name string) (clientID string, err error)
|
||||
ResolveGrants(ctx context.Context) (grant *Grant, err error)
|
||||
ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (projectID string, origins []string, err error)
|
||||
@@ -30,13 +30,13 @@ func Start(authZRepo authZRepo) (v *TokenVerifier) {
|
||||
return &TokenVerifier{authZRepo: authZRepo}
|
||||
}
|
||||
|
||||
func (v *TokenVerifier) VerifyAccessToken(ctx context.Context, token string, method string) (userID, clientID, agentID string, err error) {
|
||||
func (v *TokenVerifier) VerifyAccessToken(ctx context.Context, token string, method string) (userID, clientID, agentID, prefLang string, err error) {
|
||||
clientID, err = v.clientIDFromMethod(ctx, method)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
return "", "", "", "", err
|
||||
}
|
||||
userID, agentID, err = v.authZRepo.VerifyAccessToken(ctx, token, clientID)
|
||||
return userID, clientID, agentID, err
|
||||
userID, agentID, prefLang, err = v.authZRepo.VerifyAccessToken(ctx, token, clientID)
|
||||
return userID, clientID, agentID, prefLang, err
|
||||
}
|
||||
|
||||
type client struct {
|
||||
@@ -101,10 +101,10 @@ func (v *TokenVerifier) CheckAuthMethod(method string) (Option, bool) {
|
||||
return authOpt, ok
|
||||
}
|
||||
|
||||
func verifyAccessToken(ctx context.Context, token string, t *TokenVerifier, method string) (userID, clientID, agentID string, err error) {
|
||||
func verifyAccessToken(ctx context.Context, token string, t *TokenVerifier, method string) (userID, clientID, agentID, prefLang string, err error) {
|
||||
parts := strings.Split(token, BearerPrefix)
|
||||
if len(parts) != 2 {
|
||||
return "", "", "", caos_errs.ThrowUnauthenticated(nil, "AUTH-7fs1e", "invalid auth header")
|
||||
return "", "", "", "", caos_errs.ThrowUnauthenticated(nil, "AUTH-7fs1e", "invalid auth header")
|
||||
}
|
||||
return t.VerifyAccessToken(ctx, parts[1], method)
|
||||
}
|
||||
|
@@ -58,7 +58,7 @@ func Test_VerifyAccessToken(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, _, _, err := verifyAccessToken(tt.args.ctx, tt.args.token, tt.args.verifier, tt.args.method)
|
||||
_, _, _, _, err := verifyAccessToken(tt.args.ctx, tt.args.token, tt.args.verifier, tt.args.method)
|
||||
if tt.wantErr && err == nil {
|
||||
t.Errorf("got wrong result, should get err: actual: %v ", err)
|
||||
}
|
||||
|
@@ -1,16 +1,15 @@
|
||||
package grpc
|
||||
package errors
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/logging"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
"github.com/caos/zitadel/pkg/grpc/message"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func CaosToGRPCError(ctx context.Context, err error, translator *i18n.Translator) error {
|
||||
func CaosToGRPCError(ctx context.Context, err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -19,10 +18,8 @@ func CaosToGRPCError(ctx context.Context, err error, translator *i18n.Translator
|
||||
return status.Convert(err).Err()
|
||||
}
|
||||
msg := key
|
||||
if translator != nil {
|
||||
msg = translator.LocalizeFromCtx(ctx, key, nil)
|
||||
msg += " (" + id + ")"
|
||||
}
|
||||
msg += " (" + id + ")"
|
||||
|
||||
s, err := status.New(code, msg).WithDetails(&message.ErrorDetail{Id: id, Message: key})
|
||||
if err != nil {
|
||||
logging.Log("GRPC-gIeRw").WithError(err).Debug("unable to add detail")
|
@@ -1,4 +1,4 @@
|
||||
package grpc
|
||||
package errors
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -8,13 +8,11 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
)
|
||||
|
||||
func TestCaosToGRPCError(t *testing.T) {
|
||||
type args struct {
|
||||
err error
|
||||
translator *i18n.Translator
|
||||
err error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -28,18 +26,18 @@ func TestCaosToGRPCError(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"unknown error",
|
||||
args{errors.New("unknown"), nil},
|
||||
args{errors.New("unknown")},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"caos error",
|
||||
args{caos_errs.ThrowInternal(nil, "", "message"), nil},
|
||||
args{caos_errs.ThrowInternal(nil, "", "message")},
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := CaosToGRPCError(context.Background(), tt.args.err, tt.args.translator); (err != nil) != tt.wantErr {
|
||||
if err := CaosToGRPCError(context.Background(), tt.args.err); (err != nil) != tt.wantErr {
|
||||
t.Errorf("CaosToGRPCError() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
@@ -21,8 +21,8 @@ var (
|
||||
|
||||
type verifierMock struct{}
|
||||
|
||||
func (v *verifierMock) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, error) {
|
||||
return "", "", nil
|
||||
func (v *verifierMock) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, error) {
|
||||
return "", "", "", nil
|
||||
}
|
||||
func (v *verifierMock) ResolveGrants(ctx context.Context) (*authz.Grant, error) {
|
||||
return nil, nil
|
||||
|
@@ -2,24 +2,20 @@ package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/api/grpc/errors"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
grpc_util "github.com/caos/zitadel/internal/api/grpc"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
_ "github.com/caos/zitadel/internal/statik"
|
||||
)
|
||||
|
||||
func ErrorHandler(defaultLanguage language.Tag) grpc.UnaryServerInterceptor {
|
||||
translator := newZitadelTranslator(defaultLanguage)
|
||||
|
||||
func ErrorHandler() grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
return toGRPCError(ctx, req, handler, translator)
|
||||
return toGRPCError(ctx, req, handler)
|
||||
}
|
||||
}
|
||||
|
||||
func toGRPCError(ctx context.Context, req interface{}, handler grpc.UnaryHandler, translator *i18n.Translator) (interface{}, error) {
|
||||
func toGRPCError(ctx context.Context, req interface{}, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
resp, err := handler(ctx, req)
|
||||
return resp, grpc_util.CaosToGRPCError(ctx, err, translator)
|
||||
return resp, errors.CaosToGRPCError(ctx, err)
|
||||
}
|
||||
|
@@ -50,7 +50,7 @@ func Test_toGRPCError(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := toGRPCError(tt.args.ctx, tt.args.req, tt.args.handler, nil)
|
||||
got, err := toGRPCError(tt.args.ctx, tt.args.req, tt.args.handler)
|
||||
if (err != nil) != tt.res.wantErr {
|
||||
t.Errorf("toGRPCError() error = %v, wantErr %v", err, tt.res.wantErr)
|
||||
return
|
||||
|
@@ -18,6 +18,9 @@ func TranslationHandler(defaultLanguage language.Tag) func(ctx context.Context,
|
||||
if loc, ok := resp.(localizers); ok && resp != nil {
|
||||
translateFields(ctx, loc, translator)
|
||||
}
|
||||
if err != nil {
|
||||
err = translateError(ctx, err, translator)
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@ package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
@@ -26,6 +28,17 @@ func translateFields(ctx context.Context, object localizers, translator *i18n.Tr
|
||||
}
|
||||
}
|
||||
|
||||
func translateError(ctx context.Context, err error, translator *i18n.Translator) error {
|
||||
if translator == nil || err == nil {
|
||||
return err
|
||||
}
|
||||
caosErr := new(caos_errs.CaosError)
|
||||
if errors.As(err, &caosErr) {
|
||||
caosErr.SetMessage(translator.LocalizeFromCtx(ctx, caosErr.GetMessage(), nil))
|
||||
}
|
||||
return caosErr
|
||||
}
|
||||
|
||||
func newZitadelTranslator(defaultLanguage language.Tag) *i18n.Translator {
|
||||
return translatorFromNamespace("zitadel", defaultLanguage)
|
||||
}
|
||||
|
@@ -30,14 +30,13 @@ func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, lang l
|
||||
middleware.TracingStatsServer(http.Healthz, http.Readiness, http.Validation),
|
||||
grpc.UnaryInterceptor(
|
||||
grpc_middleware.ChainUnaryServer(
|
||||
middleware.ErrorHandler(lang),
|
||||
middleware.ErrorHandler(),
|
||||
middleware.AuthorizationInterceptor(verifier, authConfig),
|
||||
middleware.TranslationHandler(lang),
|
||||
grpc_middleware.ChainUnaryServer(
|
||||
middleware.AuthorizationInterceptor(verifier, authConfig),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
func Serve(ctx context.Context, server *grpc.Server, port string) {
|
||||
|
@@ -2,6 +2,8 @@ package oidc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/logging"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/caos/oidc/pkg/oidc"
|
||||
"github.com/caos/oidc/pkg/op"
|
||||
@@ -78,6 +80,8 @@ func (o *OPStorage) GetUserinfoFromScopes(ctx context.Context, userID string, sc
|
||||
userInfo.PreferredUsername = user.PreferredLoginName
|
||||
userInfo.UpdatedAt = user.ChangeDate
|
||||
userInfo.Gender = oidc.Gender(getGender(user.Gender))
|
||||
userInfo.Locale, err = language.Parse(user.PreferredLanguage)
|
||||
logging.Log("OIDC-4ks9F").OnError(err).Debug("unable to parse locale")
|
||||
case scopePhone:
|
||||
userInfo.PhoneNumber = user.Phone
|
||||
userInfo.PhoneNumberVerified = user.IsPhoneVerified
|
||||
|
Reference in New Issue
Block a user