diff --git a/go.mod b/go.mod index 1f94424c686dc81bb80569395734cae6eeddfb2b..8fb26873d6124318c865be5eb68f786952507f5a 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 4b2f278b81ef6999417ee78fb77df8203b8073db..737f85da4ced4b905e27ee814747b94cfd4c4ee4 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 dc182fb0fb764b9b7ca3a232678564c8878a72b0..6ab0f02d0b68c62904058df6e7dd4fc2cbb84aef 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 d447681068fefc974089f351d7654056314796b7..a7d78b3372ef69eab5ee29e16ac7f38665591eee 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 2394c62a2f15ca7605959b3f5b31996a5c79a164..f1086b5f5ed63670404f5869041e33ef599cc893 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 0000000000000000000000000000000000000000..bbe79af928dc86f18a1f19b84249c70c407203f0 --- /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 a947a33bab75da4c55ca9575e15d915fbc480b67..508d5480f213536dd96c2c028ac77248fd3f8d5b 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 29e879457bebc4da201ce126c6c140e02989f2c0..37d32f1b557f4cb306a39f12961b44088e9cebf4 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 fa83027280cfc95fb86f0bbe6051f5d3844310ff..8875212d6e5b718a2351a59375023db4dca56a5c 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 966da731feef900ac7ad0a852c108fbc536af5d7..6faba7c33cd15018800332a019f35569f629d287 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 b8abb51a5aa7684f68f1d97fc0cdf9077a0d6087..8355e23818a1956bd052cac96957661264f30569 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 f6a0b9b697e6832ea8fb6eaaa97c882ec43bdc78..fa0137f3d569dc7048dbaa46bbe16cc01d5b1138 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 e58c5b911f4106268f81136545677df1666e9bd0..e3d196ebfcc8d13eeb4c533f8cef40c072496bdc 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 25088bfd631d5b2dd23c58d861c6051098d01907..d122366ee2648032dab9cea7bcd301b5d1c5c98f 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 989c6e68158ef3b397d345fbe08b55012eec60a8..ba8feef5f047db356b99f056110b575b3570dec2 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 a244c5171f61263293094b40344537a3fc3117fe..9f839c3afdc203b474d6ab936495fb8e4009da03 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 01537b1123040311fcd9fb036c8765066d2f65b1..c06e4addd529f629543e2fdc0d2cfb129dd2650c 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 264025bfc25edd39b423f5ca983188bc6e3a9e60..c65d3390efddbd153dbd1208a498ea62fa7f0749 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 f70b8cdfe93eb8b843ec66136e8fa63bccc735ee..8a06c45c8ee4f76139ec7f91e91a561dc7acd69f 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 7364d5fce73a58580ed59bd71539bab3a1e68668..7ead5f9363d753ee9f1c180b0046953017f5c9bb 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 4fcd2868c5d20dbb1b60187940c50a6327529da5..433483e032ecd6f9e84494432cada2df6b570e57 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 2b45912bd1ab18ab8651b18cd17fbc6679b2d883..8c120ca444ef1f4f0ef1bee5411b6dde461e5d63 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 07211008e3d631e1c23a658a31fa67f8f983a058..d14583cc07aeae33420680b5fc98aa40e25d2770 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 8817f6d832fc1d971ed9f36e80de1e5375e7d00d..678f6ef1d84926f503a7b7e3aac994bb222b7810 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 e12645efc79921da957e359848d9dca606f6364b..6f5c37277a9acb6ae22d2f5f2e7e02f6ede4af3b 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 + } +}