From ae19b9868325be5ced2338e169d5c4e322eba23f Mon Sep 17 00:00:00 2001 From: ko_oler <kooler89@gmail.com> Date: Mon, 28 Oct 2024 18:31:27 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8C=20=D0=B0=D0=B2=D1=82=D0=BE=D1=80=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8F=20=D1=81=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B7=D0=BD=D1=8B=D0=BC=D0=B8=20Identity=20=D1=81=20=D0=BE?= =?UTF-8?q?=D0=B4=D0=B8=D0=BD=D0=B0=D0=BA=D0=BE=D0=B2=D1=8B=D0=BC=20email?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 1 + go.sum | 2 + logs/zap/example_test.go | 2 +- pkg/auth/context.go | 14 +++++ pkg/auth/factory.go | 42 ++++++++++++- pkg/auth/factory_internal_test.go | 62 +++++++++++++++++++ pkg/auth/grpc.go | 23 +++---- pkg/auth/user.go | 4 +- .../middleware/access_logging_middleware.go | 20 ++++++ pkg/users/middleware/caching_middleware.go | 21 +++++-- .../middleware/error_logging_middleware.go | 10 +++ pkg/users/middleware/logging_middleware.go | 14 +++++ pkg/users/middleware/recovering_middleware.go | 12 ++++ pkg/users/middleware/telemetry_middleware.go | 41 ++++++++++++ pkg/users/mocks/Users.go | 30 +++++++++ pkg/users/service.go | 1 + pkg/users/transport/client.go | 9 +++ pkg/users/transport/endpoints.microgen.go | 1 + pkg/users/transport/exchanges.microgen.go | 8 +++ pkg/users/transport/grpc/client.go | 1 + pkg/users/transport/grpc/client.microgen.go | 7 +++ .../protobuf_endpoint_converters.microgen.go | 40 ++++++++++++ pkg/users/transport/grpc/server.go | 1 + pkg/users/transport/grpc/server.microgen.go | 15 +++++ pkg/users/transport/server.microgen.go | 9 +++ 25 files changed, 365 insertions(+), 25 deletions(-) create mode 100644 pkg/auth/factory_internal_test.go diff --git a/go.mod b/go.mod index 1f94424c..8fb26873 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/bep/gowebp v0.4.0 github.com/expr-lang/expr v1.16.9 github.com/go-kit/kit v0.13.0 + github.com/golang-jwt/jwt/v5 v5.2.1 github.com/gosimple/slug v1.14.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru/v2 v2.0.7 diff --git a/go.sum b/go.sum index 4b2f278b..737f85da 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= diff --git a/logs/zap/example_test.go b/logs/zap/example_test.go index dc182fb0..6ab0f02d 100644 --- a/logs/zap/example_test.go +++ b/logs/zap/example_test.go @@ -61,7 +61,7 @@ func TestExample(t *testing.T) { Once() usersService := &usersmocks.Users{} - usersService.On("GetByIdentity", mock.Anything, "74d90aaf").Return(user, nil).Once() + usersService.On("Login", mock.Anything, "74d90aaf", mock.Anything).Return(user, nil).Once() factory := auth.PrincipalFactory{Users: usersService} diff --git a/pkg/auth/context.go b/pkg/auth/context.go index d4476810..a7d78b33 100644 --- a/pkg/auth/context.go +++ b/pkg/auth/context.go @@ -25,3 +25,17 @@ func WithPrincipal(ctx context.Context, p Principal) context.Context { func WithSystem(ctx context.Context) context.Context { return WithPrincipal(ctx, &SystemPrincipal{}) } + +type authToken struct{} + +func GetAuthToken(ctx context.Context) string { + t, _ := ctx.Value(authToken{}).(string) + return t +} + +func WithAuthToken(ctx context.Context, token string) context.Context { + if ctx == nil { + ctx = context.Background() + } + return context.WithValue(ctx, authToken{}, token) +} diff --git a/pkg/auth/factory.go b/pkg/auth/factory.go index 2394c62a..f1086b5f 100644 --- a/pkg/auth/factory.go +++ b/pkg/auth/factory.go @@ -1,15 +1,18 @@ package auth import ( + "fmt" "strings" "git.perx.ru/perxis/perxis-go/pkg/clients" "git.perx.ru/perxis/perxis-go/pkg/collaborators" "git.perx.ru/perxis/perxis-go/pkg/environments" + "git.perx.ru/perxis/perxis-go/pkg/errors" "git.perx.ru/perxis/perxis-go/pkg/members" "git.perx.ru/perxis/perxis-go/pkg/roles" "git.perx.ru/perxis/perxis-go/pkg/spaces" "git.perx.ru/perxis/perxis-go/pkg/users" + "github.com/golang-jwt/jwt/v5" ) type PrincipalFactory struct { @@ -22,9 +25,31 @@ type PrincipalFactory struct { environments.Environments } -func (f PrincipalFactory) User(identity string) Principal { - return &UserPrincipal{ - identity: identity, +func getValueFromToken(tokenString, name string) (string, error) { + var value string + + t := strings.Split(tokenString, "Bearer ") + if len(t) == 2 { //nolint:mnd //not mnd + tokenString = t[1] + } + // Используем ParseUnverified, так как считаем, что токен был уже проверен до получения + token, _, err := new(jwt.Parser).ParseUnverified(tokenString, jwt.MapClaims{}) + if err != nil { + return "", err + } + if claims, ok := token.Claims.(jwt.MapClaims); ok { + value = fmt.Sprint(claims[name]) + } + if value == "" { + return "", errors.New("invalid token payload") + } + + return value, nil +} + +func (f PrincipalFactory) User(identity ...string) Principal { + p := &UserPrincipal{ + identity: identity[0], users: f.Users, members: f.Members, roles: f.Roles, @@ -32,6 +57,12 @@ func (f PrincipalFactory) User(identity string) Principal { spaces: f.Spaces, environments: f.Environments, } + + if len(identity) > 1 { + p.email = identity[1] + } + + return p } func (f PrincipalFactory) Client(param *clients.GetByParams) Principal { @@ -65,6 +96,11 @@ func (f PrincipalFactory) Principal(principalId string) Principal { return f.Client(&clients.GetByParams{OAuthClientID: strings.TrimSuffix(principalId, "@clients")}) case strings.HasPrefix(principalId, "API-Key"): return f.Client(&clients.GetByParams{APIKey: strings.TrimPrefix(principalId, "API-Key ")}) + case strings.HasPrefix(principalId, "Bearer "): + var email string + email, _ = getValueFromToken(principalId, "email") + principalId, _ = getValueFromToken(principalId, "sub") + return f.User(principalId, email) default: return f.User(principalId) } diff --git a/pkg/auth/factory_internal_test.go b/pkg/auth/factory_internal_test.go new file mode 100644 index 00000000..bbe79af9 --- /dev/null +++ b/pkg/auth/factory_internal_test.go @@ -0,0 +1,62 @@ +package auth + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_getValueFromToken(t *testing.T) { + tests := []struct { + name string + tokenString string + field string + want string + wantErr bool + }{ + { + "With Bearer", + "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfaWRlbnRfMiIsImVtYWlsIjoidGVzdEB" + + "0ZXN0LnJ1IiwiaWF0IjoxNTE2MjM5MDIyfQ.MLo310mkPmZdJlIRo3POhevFwd-O_UyxE-1opbQMVVs", + "email", + "test@test.ru", + false, + }, + { + "Without Bearer", + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfaWRlbnRfMiIsImVtYWlsIjoidGVzdEB0ZXN0Ln" + + "J1IiwiaWF0IjoxNTE2MjM5MDIyfQ.MLo310mkPmZdJlIRo3POhevFwd-O_UyxE-1opbQMVVs", + "email", + "test@test.ru", + false, + }, + { + "Sub", + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfaWRlbnRfMiIsImVtYWlsIjoidGVzdEB0ZXN0Ln" + + "J1IiwiaWF0IjoxNTE2MjM5MDIyfQ.MLo310mkPmZdJlIRo3POhevFwd-O_UyxE-1opbQMVVs", + "sub", + "usr_ident_2", + false, + }, + { + "Invalid token", + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.zdWIiOiJ1c3JfaWRlbnRfMiIsImVtYWlsIjoidGVzdEB0ZXN0LnJ1I" + + "iwiaWF0IjoxNTE2MjM5MDIyfQ.MLo310mkPmZdJlIRo3POhevFwd-O_UyxE-1opbQMVVs", + "email", + "test@test.ru", + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getValueFromToken(tt.tokenString, tt.field) + if !tt.wantErr { + require.NoError(t, err) + assert.Equal(t, tt.want, got) + } else { + assert.Error(t, err) + } + }) + } +} diff --git a/pkg/auth/grpc.go b/pkg/auth/grpc.go index a947a33b..508d5480 100644 --- a/pkg/auth/grpc.go +++ b/pkg/auth/grpc.go @@ -16,9 +16,8 @@ import ( ) const ( - OAuth2IdentityMetadata = "x-perxis-identity" - TLSIdentityMetadata = "x-forwarded-client-cert" - AccessMetadata = "x-perxis-access" + TLSIdentityMetadata = "x-forwarded-client-cert" + AccessMetadata = "x-perxis-access" AuthorizationMetadata = "authorization" ) @@ -28,15 +27,9 @@ func GRPCToContext(factory *PrincipalFactory) kitgrpc.ServerRequestFunc { if identity := md.Get(TLSIdentityMetadata); len(identity) > 0 { return WithPrincipal(ctx, factory.Principal(identity[0])) } - - if identity := md.Get(OAuth2IdentityMetadata); len(identity) > 0 { - return WithPrincipal(ctx, factory.Principal(identity[0])) + if token := md.Get(AuthorizationMetadata); len(token) > 0 { + return WithPrincipal(WithAuthToken(ctx, token[0]), factory.Principal(token[0])) } - - if identity := md.Get(AuthorizationMetadata); len(identity) > 0 { - return WithPrincipal(ctx, factory.Principal(identity[0])) - } - if access := md.Get(AccessMetadata); len(access) > 0 { return WithPrincipal(ctx, factory.System()) } @@ -51,19 +44,19 @@ func ContextToGRPC() kitgrpc.ClientRequestFunc { switch p := p.(type) { case *UserPrincipal: - if p.GetIdentity(ctx) != "" { - (*md)[OAuth2IdentityMetadata] = []string{p.GetIdentity(ctx)} + (*md)[AuthorizationMetadata] = []string{p.GetIdentity(ctx)} + if GetAuthToken(ctx) != "" { + (*md)[AuthorizationMetadata] = []string{GetAuthToken(ctx)} } case *ClientPrincipal: if ident := p.GetIdentity(ctx); ident != nil { switch { case ident.OAuthClientID != "": - (*md)[OAuth2IdentityMetadata] = []string{ident.OAuthClientID + "@clients"} + (*md)[AuthorizationMetadata] = []string{ident.OAuthClientID + "@clients"} case ident.TLSSubject != "": (*md)[TLSIdentityMetadata] = []string{ident.TLSSubject} case ident.APIKey != "": (*md)[AuthorizationMetadata] = []string{"API-Key " + ident.APIKey} - } } case *SystemPrincipal: diff --git a/pkg/auth/user.go b/pkg/auth/user.go index 29e87945..37d32f1b 100644 --- a/pkg/auth/user.go +++ b/pkg/auth/user.go @@ -18,6 +18,7 @@ import ( type UserPrincipal struct { id string identity string + email string user *users.User invalid bool @@ -128,8 +129,7 @@ func (u *UserPrincipal) User(ctx context.Context) *users.User { case u.id != "": user, err = u.users.Get(WithSystem(ctx), u.id) case u.identity != "": - ctx = WithSystem(ctx) - user, err = u.users.GetByIdentity(WithSystem(ctx), u.identity) + user, err = u.users.Login(WithSystem(ctx), u.identity, u.email) } if err != nil || user == nil { diff --git a/pkg/users/middleware/access_logging_middleware.go b/pkg/users/middleware/access_logging_middleware.go index fa830272..8875212d 100644 --- a/pkg/users/middleware/access_logging_middleware.go +++ b/pkg/users/middleware/access_logging_middleware.go @@ -128,6 +128,26 @@ func (m *accessLoggingMiddleware) GetByIdentity(ctx context.Context, identity st return user, err } +func (m *accessLoggingMiddleware) Login(ctx context.Context, identity string, email string) (user *users.User, err error) { + begin := time.Now() + + m.logger.Debug("Login.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("identity", identity), + zap.Reflect("email", email), + ) + + user, err = m.next.Login(ctx, identity, email) + + m.logger.Debug("Login.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("user", user), + zap.Error(err), + ) + + return user, err +} + func (m *accessLoggingMiddleware) Update(ctx context.Context, user *users.User) (err error) { begin := time.Now() diff --git a/pkg/users/middleware/caching_middleware.go b/pkg/users/middleware/caching_middleware.go index 966da731..6faba7c3 100644 --- a/pkg/users/middleware/caching_middleware.go +++ b/pkg/users/middleware/caching_middleware.go @@ -27,7 +27,6 @@ func (m cachingMiddleware) Create(ctx context.Context, create *service.User) (us } func (m cachingMiddleware) Get(ctx context.Context, id string) (user *service.User, err error) { - value, e := m.cache.Get(id) if e == nil { return value.(*service.User).Clone(), nil @@ -48,7 +47,6 @@ func (m cachingMiddleware) Find(ctx context.Context, filter *service.Filter, opt } func (m cachingMiddleware) Update(ctx context.Context, update *service.User) (err error) { - err = m.next.Update(ctx, update) value, e := m.cache.Get(update.ID) if err == nil && e == nil { @@ -62,7 +60,6 @@ func (m cachingMiddleware) Update(ctx context.Context, update *service.User) (er } func (m cachingMiddleware) Delete(ctx context.Context, id string) (err error) { - err = m.next.Delete(ctx, id) value, e := m.cache.Get(id) if err == nil && e == nil { @@ -76,7 +73,6 @@ func (m cachingMiddleware) Delete(ctx context.Context, id string) (err error) { } func (m cachingMiddleware) GetByIdentity(ctx context.Context, identity string) (user *service.User, err error) { - value, e := m.cache.Get(identity) if e == nil { return value.(*service.User).Clone(), nil @@ -91,3 +87,20 @@ func (m cachingMiddleware) GetByIdentity(ctx context.Context, identity string) ( } return nil, err } + +//nolint:nonamedreturns //generated +func (m cachingMiddleware) Login(ctx context.Context, identity string, email string) (user *service.User, err error) { + value, e := m.cache.Get(identity) + if e == nil { + return value.(*service.User).Clone(), nil //nolint:errcheck //generated + } + user, err = m.next.Login(ctx, identity, email) + if err == nil { + _ = m.cache.Set(user.ID, user) + for _, i := range user.Identities { + _ = m.cache.Set(i, user) + } + return user.Clone(), nil + } + return nil, err +} diff --git a/pkg/users/middleware/error_logging_middleware.go b/pkg/users/middleware/error_logging_middleware.go index b8abb51a..8355e238 100644 --- a/pkg/users/middleware/error_logging_middleware.go +++ b/pkg/users/middleware/error_logging_middleware.go @@ -80,6 +80,16 @@ func (m *errorLoggingMiddleware) GetByIdentity(ctx context.Context, identity str return m.next.GetByIdentity(ctx, identity) } +func (m *errorLoggingMiddleware) Login(ctx context.Context, identity string, email string) (user *users.User, err error) { + logger := m.logger + defer func() { + if err != nil { + logger.Warn("response error", zap.Error(err)) + } + }() + return m.next.Login(ctx, identity, email) +} + func (m *errorLoggingMiddleware) Update(ctx context.Context, user *users.User) (err error) { logger := m.logger defer func() { diff --git a/pkg/users/middleware/logging_middleware.go b/pkg/users/middleware/logging_middleware.go index f6a0b9b6..fa0137f3 100644 --- a/pkg/users/middleware/logging_middleware.go +++ b/pkg/users/middleware/logging_middleware.go @@ -119,3 +119,17 @@ func (m *loggingMiddleware) GetByIdentity(ctx context.Context, identity string) } return user, err } + +//nolint:nonamedreturns //generated +func (m *loggingMiddleware) Login(ctx context.Context, identity string, email string) (user *users.User, err error) { + logger := m.logger.With( + logzap.Caller(ctx), + logzap.Object(pkgId.NewUserId(identity)), + ) + + user, err = m.next.Login(ctx, identity, email) + if err != nil { + logger.Error("Failed to login", zap.Error(err)) + } + return user, err +} diff --git a/pkg/users/middleware/recovering_middleware.go b/pkg/users/middleware/recovering_middleware.go index e58c5b91..e3d196eb 100644 --- a/pkg/users/middleware/recovering_middleware.go +++ b/pkg/users/middleware/recovering_middleware.go @@ -91,6 +91,18 @@ func (m *recoveringMiddleware) GetByIdentity(ctx context.Context, identity strin return m.next.GetByIdentity(ctx, identity) } +func (m *recoveringMiddleware) Login(ctx context.Context, identity string, email string) (user *users.User, err error) { + logger := m.logger + defer func() { + if r := recover(); r != nil { + logger.Error("panic", zap.Error(fmt.Errorf("%v", r))) + err = fmt.Errorf("%v", r) + } + }() + + return m.next.Login(ctx, identity, email) +} + func (m *recoveringMiddleware) Update(ctx context.Context, user *users.User) (err error) { logger := m.logger defer func() { diff --git a/pkg/users/middleware/telemetry_middleware.go b/pkg/users/middleware/telemetry_middleware.go index 25088bfd..d122366e 100644 --- a/pkg/users/middleware/telemetry_middleware.go +++ b/pkg/users/middleware/telemetry_middleware.go @@ -254,6 +254,47 @@ func (_d telemetryMiddleware) GetByIdentity(ctx context.Context, identity string return user, err } +// Login implements users.Users +func (_d telemetryMiddleware) Login(ctx context.Context, identity string, email string) (user *users.User, err error) { + var att = []attribute.KeyValue{ + attribute.String("service", "Users"), + attribute.String("method", "Login"), + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) + + start := time.Now() + ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Users.Login") + defer _span.End() + + user, err = _d.Users.Login(ctx, identity, email) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := pkgId.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "identity": identity, + "email": email}, map[string]interface{}{ + "user": user, + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return user, err +} + // Update implements users.Users func (_d telemetryMiddleware) Update(ctx context.Context, user *users.User) (err error) { var att = []attribute.KeyValue{ diff --git a/pkg/users/mocks/Users.go b/pkg/users/mocks/Users.go index 989c6e68..ba8feef5 100644 --- a/pkg/users/mocks/Users.go +++ b/pkg/users/mocks/Users.go @@ -161,6 +161,36 @@ func (_m *Users) GetByIdentity(ctx context.Context, identity string) (*users.Use return r0, r1 } +// Login provides a mock function with given fields: ctx, identity, email +func (_m *Users) Login(ctx context.Context, identity string, email string) (*users.User, error) { + ret := _m.Called(ctx, identity, email) + + if len(ret) == 0 { + panic("no return value specified for Login") + } + + var r0 *users.User + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) (*users.User, error)); ok { + return rf(ctx, identity, email) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string) *users.User); ok { + r0 = rf(ctx, identity, email) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*users.User) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, identity, email) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // Update provides a mock function with given fields: ctx, user func (_m *Users) Update(ctx context.Context, user *users.User) error { ret := _m.Called(ctx, user) diff --git a/pkg/users/service.go b/pkg/users/service.go index a244c517..9f839c3a 100644 --- a/pkg/users/service.go +++ b/pkg/users/service.go @@ -16,6 +16,7 @@ type Users interface { Update(ctx context.Context, user *User) (err error) Delete(ctx context.Context, id string) (err error) GetByIdentity(ctx context.Context, identity string) (user *User, err error) + Login(ctx context.Context, identity string, email string) (user *User, err error) } type Filter struct { diff --git a/pkg/users/transport/client.go b/pkg/users/transport/client.go index 01537b11..c06e4add 100644 --- a/pkg/users/transport/client.go +++ b/pkg/users/transport/client.go @@ -65,3 +65,12 @@ func (set EndpointsSet) GetByIdentity(arg0 context.Context, arg1 string) (res0 * } return response.(*GetByIdentityResponse).User, res1 } + +func (set EndpointsSet) Login(arg0 context.Context, arg1 string, arg2 string) (res0 *users.User, res1 error) { + request := LoginRequest{Identity: arg1, Email: arg2} + response, res1 := set.LoginEndpoint(arg0, &request) + if res1 != nil { + return + } + return response.(*LoginResponse).User, res1 +} diff --git a/pkg/users/transport/endpoints.microgen.go b/pkg/users/transport/endpoints.microgen.go index 264025bf..c65d3390 100644 --- a/pkg/users/transport/endpoints.microgen.go +++ b/pkg/users/transport/endpoints.microgen.go @@ -12,4 +12,5 @@ type EndpointsSet struct { UpdateEndpoint endpoint.Endpoint DeleteEndpoint endpoint.Endpoint GetByIdentityEndpoint endpoint.Endpoint + LoginEndpoint endpoint.Endpoint } diff --git a/pkg/users/transport/exchanges.microgen.go b/pkg/users/transport/exchanges.microgen.go index f70b8cdf..8a06c45c 100644 --- a/pkg/users/transport/exchanges.microgen.go +++ b/pkg/users/transport/exchanges.microgen.go @@ -49,4 +49,12 @@ type ( GetByIdentityResponse struct { User *users.User `json:"user"` } + + LoginRequest struct { + Identity string `json:"identity"` + Email string `json:"email"` + } + LoginResponse struct { + User *users.User `json:"user"` + } ) diff --git a/pkg/users/transport/grpc/client.go b/pkg/users/transport/grpc/client.go index 7364d5fc..7ead5f93 100644 --- a/pkg/users/transport/grpc/client.go +++ b/pkg/users/transport/grpc/client.go @@ -18,5 +18,6 @@ func NewClient(conn *grpc.ClientConn, opts ...grpckit.ClientOption) transport.En GetByIdentityEndpoint: grpcerr.ClientMiddleware(c.GetByIdentityEndpoint), GetEndpoint: grpcerr.ClientMiddleware(c.GetEndpoint), UpdateEndpoint: grpcerr.ClientMiddleware(c.UpdateEndpoint), + LoginEndpoint: grpcerr.ClientMiddleware(c.LoginEndpoint), } } diff --git a/pkg/users/transport/grpc/client.microgen.go b/pkg/users/transport/grpc/client.microgen.go index 4fcd2868..433483e0 100644 --- a/pkg/users/transport/grpc/client.microgen.go +++ b/pkg/users/transport/grpc/client.microgen.go @@ -50,6 +50,13 @@ func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOpt pb.GetResponse{}, opts..., ).Endpoint(), + LoginEndpoint: grpckit.NewClient( + conn, addr, "Login", + _Encode_Login_Request, + _Decode_Login_Response, + pb.LoginResponse{}, + opts..., + ).Endpoint(), UpdateEndpoint: grpckit.NewClient( conn, addr, "Update", _Encode_Update_Request, diff --git a/pkg/users/transport/grpc/protobuf_endpoint_converters.microgen.go b/pkg/users/transport/grpc/protobuf_endpoint_converters.microgen.go index 2b45912b..8c120ca4 100644 --- a/pkg/users/transport/grpc/protobuf_endpoint_converters.microgen.go +++ b/pkg/users/transport/grpc/protobuf_endpoint_converters.microgen.go @@ -63,6 +63,14 @@ func _Encode_Update_Request(ctx context.Context, request interface{}) (interface return &pb.UpdateRequest{Update: reqUpdate}, nil } +func _Encode_Login_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil LoginRequest") + } + req := request.(*transport.LoginRequest) + return &pb.LoginRequest{Email: req.Email, Identity: req.Identity}, nil +} + func _Encode_Delete_Request(ctx context.Context, request interface{}) (interface{}, error) { if request == nil { return nil, errors.New("nil DeleteRequest") @@ -95,6 +103,18 @@ func _Encode_Get_Response(ctx context.Context, response interface{}) (interface{ return &pb.GetResponse{User: respUser}, nil } +func _Encode_Login_Response(ctx context.Context, response interface{}) (interface{}, error) { + if response == nil { + return nil, errors.New("nil LoginResponse") + } + resp := response.(*transport.LoginResponse) + respUser, err := PtrUserToProto(resp.User) + if err != nil { + return nil, err + } + return &pb.LoginResponse{User: respUser}, nil +} + func _Encode_Find_Response(ctx context.Context, response interface{}) (interface{}, error) { if response == nil { return nil, errors.New("nil FindResponse") @@ -165,6 +185,14 @@ func _Decode_Update_Request(ctx context.Context, request interface{}) (interface return &transport.UpdateRequest{Update: reqUpdate}, nil } +func _Decode_Login_Request(ctx context.Context, request interface{}) (interface{}, error) { + if request == nil { + return nil, errors.New("nil LoginRequest") + } + req := request.(*pb.LoginRequest) + return &transport.LoginRequest{Email: req.Email, Identity: req.Identity}, nil +} + func _Decode_Delete_Request(ctx context.Context, request interface{}) (interface{}, error) { if request == nil { return nil, errors.New("nil DeleteRequest") @@ -197,6 +225,18 @@ func _Decode_Get_Response(ctx context.Context, response interface{}) (interface{ return &transport.GetResponse{User: respUser}, nil } +func _Decode_Login_Response(ctx context.Context, response interface{}) (interface{}, error) { + if response == nil { + return nil, errors.New("nil LoginResponse") + } + resp := response.(*pb.LoginResponse) + respUser, err := ProtoToPtrUser(resp.User) + if err != nil { + return nil, err + } + return &transport.LoginResponse{User: respUser}, nil +} + func _Decode_Find_Response(ctx context.Context, response interface{}) (interface{}, error) { if response == nil { return nil, errors.New("nil FindResponse") diff --git a/pkg/users/transport/grpc/server.go b/pkg/users/transport/grpc/server.go index 07211008..d14583cc 100644 --- a/pkg/users/transport/grpc/server.go +++ b/pkg/users/transport/grpc/server.go @@ -17,6 +17,7 @@ func NewServer(svc users.Users, opts ...grpckit.ServerOption) pb.UsersServer { GetByIdentityEndpoint: grpcerr.ServerMiddleware(eps.GetByIdentityEndpoint), GetEndpoint: grpcerr.ServerMiddleware(eps.GetEndpoint), UpdateEndpoint: grpcerr.ServerMiddleware(eps.UpdateEndpoint), + LoginEndpoint: grpcerr.ServerMiddleware(eps.LoginEndpoint), } return NewGRPCServer(&eps, opts...) } diff --git a/pkg/users/transport/grpc/server.microgen.go b/pkg/users/transport/grpc/server.microgen.go index 8817f6d8..678f6ef1 100644 --- a/pkg/users/transport/grpc/server.microgen.go +++ b/pkg/users/transport/grpc/server.microgen.go @@ -18,6 +18,7 @@ type usersServer struct { update grpc.Handler delete grpc.Handler getByIdentity grpc.Handler + login grpc.Handler pb.UnimplementedUsersServer } @@ -54,6 +55,12 @@ func NewGRPCServer(endpoints *transport.EndpointsSet, opts ...grpc.ServerOption) _Encode_GetByIdentity_Response, opts..., ), + login: grpc.NewServer( + endpoints.LoginEndpoint, + _Decode_Login_Request, + _Encode_Login_Response, + opts..., + ), update: grpc.NewServer( endpoints.UpdateEndpoint, _Decode_Update_Request, @@ -110,3 +117,11 @@ func (S *usersServer) GetByIdentity(ctx context.Context, req *pb.GetByIdentityRe } return resp.(*pb.GetByIdentityResponse), nil } + +func (S *usersServer) Login(ctx context.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) { + _, resp, err := S.login.ServeGRPC(ctx, req) + if err != nil { + return nil, err + } + return resp.(*pb.LoginResponse), nil +} diff --git a/pkg/users/transport/server.microgen.go b/pkg/users/transport/server.microgen.go index e12645ef..6f5c3727 100644 --- a/pkg/users/transport/server.microgen.go +++ b/pkg/users/transport/server.microgen.go @@ -16,6 +16,7 @@ func Endpoints(svc users.Users) EndpointsSet { FindEndpoint: FindEndpoint(svc), GetByIdentityEndpoint: GetByIdentityEndpoint(svc), GetEndpoint: GetEndpoint(svc), + LoginEndpoint: LoginEndpoint(svc), UpdateEndpoint: UpdateEndpoint(svc), } } @@ -70,3 +71,11 @@ func GetByIdentityEndpoint(svc users.Users) endpoint.Endpoint { return &GetByIdentityResponse{User: res0}, res1 } } + +func LoginEndpoint(svc users.Users) endpoint.Endpoint { + return func(arg0 context.Context, request interface{}) (interface{}, error) { + req := request.(*LoginRequest) + res0, res1 := svc.Login(arg0, req.Identity, req.Email) + return &LoginResponse{User: res0}, res1 + } +} -- GitLab