Skip to content
Snippets Groups Projects
Commit ea006d09 authored by Anton Sattarov's avatar Anton Sattarov :cucumber:
Browse files

Merge branch 'feature/PRXS-1074-Account' into 'feature/1004-AddPublicEntities'

Перенесён в репозиторий services/account

See merge request perxis/perxis-go!36
parents 4b3a8015 4eadae77
No related branches found
No related tags found
No related merge requests found
Showing
with 689 additions and 0 deletions
package account
import (
"git.perx.ru/perxis/perxis-go/pkg/account/versions"
"git.perx.ru/perxis/perxis-go/pkg/auth"
"git.perx.ru/perxis/perxis-go/pkg/members"
msobserver "git.perx.ru/perxis/perxis-go/pkg/members/observer"
"git.perx.ru/perxis/perxis-go/pkg/organizations"
"git.perx.ru/perxis/perxis-go/pkg/users"
"google.golang.org/grpc"
)
type Account struct {
users.Users
members.Members
organizations.Organizations
versions.Versions
// сервис, отвечающий за отслеживание сервисом `members` событий от других сервисов
MembersObserver msobserver.Observer
// используется для добавления в контекст информации о пользователе, инициировавшем запрос
PrincipalFactory *auth.PrincipalFactory
ClientConn *grpc.ClientConn
}
package client
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"net/url"
"time"
"git.perx.ru/perxis/perxis-go/pkg/account"
"git.perx.ru/perxis/perxis-go/pkg/cache"
serviceMembers "git.perx.ru/perxis/perxis-go/pkg/members/middleware"
membersObserverTransport "git.perx.ru/perxis/perxis-go/pkg/members/observer/transport/grpc"
membersTransport "git.perx.ru/perxis/perxis-go/pkg/members/transport/grpc"
serviceOrganizations "git.perx.ru/perxis/perxis-go/pkg/organizations/middleware"
organizationsTransport "git.perx.ru/perxis/perxis-go/pkg/organizations/transport/grpc"
serviceUsers "git.perx.ru/perxis/perxis-go/pkg/users/middleware"
usersTransport "git.perx.ru/perxis/perxis-go/pkg/users/transport/grpc"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
"go.uber.org/zap"
"golang.org/x/oauth2/clientcredentials"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/credentials/oauth"
)
const (
DefaultCacheSize = 1000
DefaultCacheTTL = time.Second * 10
)
func NewClient(ctx context.Context, addr string, opts ...Option) (*account.Account, *grpc.ClientConn, error) {
client := &account.Account{}
dialOpts := make([]grpc.DialOption, 0)
config := &config{}
for _, o := range opts {
o(config)
}
if config.logger == nil {
config.logger = zap.NewNop()
}
dialOpts = append(dialOpts, grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()))
if config.auth == nil {
dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
} else {
if config.auth.TLS != nil {
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(config.auth.TLS.cacert) {
return nil, nil, fmt.Errorf("CA certificate not loaded")
}
clientCert, err := tls.X509KeyPair(config.auth.TLS.cert, config.auth.TLS.key)
if err != nil {
return nil, nil, err
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{clientCert},
RootCAs: certPool,
}
dialOpts = append(dialOpts,
grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)),
)
}
if config.auth.OAuth2 != nil {
if config.auth.OAuth2 != nil {
// create external grpc client
conf := &clientcredentials.Config{
TokenURL: config.auth.OAuth2.tokenURL,
ClientID: config.auth.OAuth2.clientID,
ClientSecret: config.auth.OAuth2.clientSecret,
EndpointParams: url.Values{"audience": {config.auth.OAuth2.audience}},
}
cred := oauth.TokenSource{
TokenSource: conf.TokenSource(ctx),
}
dialOpts = append(dialOpts,
grpc.WithPerRPCCredentials(cred),
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})), // обязательно использовать tls для credentials oauth.TokenSource https://github.com/grpc/grpc-go/blob/64031cbfcf4d84c026be93ad7b74b3c290100893/credentials/oauth/oauth.go#L160
)
}
}
}
accountConn, err := grpc.Dial(addr, dialOpts...)
if err != nil {
return nil, nil, err
}
client.Members = membersTransport.NewGRPCClient(accountConn, "", config.clientOptions...)
client.Organizations = organizationsTransport.NewGRPCClient(accountConn, "", config.clientOptions...)
client.Users = usersTransport.NewGRPCClient(accountConn, "", config.clientOptions...)
client.MembersObserver = membersObserverTransport.NewGRPCClient(accountConn, "", config.clientOptions...)
if !config.noCache {
client = WithCaching(client, DefaultCacheSize, DefaultCacheTTL)
}
if !config.noLog {
client = WithLogging(client, config.logger, config.accessLog)
}
return client, accountConn, nil
}
func WithCaching(client *account.Account, size int, ttl time.Duration) *account.Account {
c := *client
c.Members = serviceMembers.CachingMiddleware(cache.NewCache(size, ttl))(client.Members)
c.Organizations = serviceOrganizations.CachingMiddleware(cache.NewCache(size, ttl))(client.Organizations)
c.Users = serviceUsers.CachingMiddleware(cache.NewCache(size, ttl))(client.Users)
return &c
}
func WithLogging(client *account.Account, logger *zap.Logger, accessLog bool) *account.Account {
c := *client
c.Members = serviceMembers.WithLog(c.Members, logger, accessLog)
c.Organizations = serviceOrganizations.WithLog(c.Organizations, logger, accessLog)
c.Users = serviceUsers.WithLog(c.Users, logger, accessLog)
return &c
}
package client
import (
"github.com/go-kit/kit/transport/grpc"
"go.uber.org/zap"
)
type config struct {
auth *authConfig
noCache bool
noLog bool
accessLog bool
debug bool
clientOptions []grpc.ClientOption
logger *zap.Logger
}
type authConfig struct {
OAuth2 *authOAuth2Config
TLS *authTLSConfig
}
type authOAuth2Config struct {
tokenURL string
clientID string // параметр из auth0 (клиент с таким id должен быть создан в perxis)
clientSecret string
audience string // параметр из auth0 (название связанного с Application API)
}
type authTLSConfig struct {
cacert []byte
cert []byte
key []byte
}
type Option func(c *config)
func AuthOAuth2(tokenUrl, clientID, clientSecret, audience string) Option {
return func(c *config) {
if c.auth == nil {
c.auth = &authConfig{}
}
c.auth.OAuth2 = &authOAuth2Config{
tokenURL: tokenUrl,
clientID: clientID,
clientSecret: clientSecret,
audience: audience,
}
}
}
func AuthTLS(cacert, cert, key []byte) Option {
return func(c *config) {
if c.auth == nil {
c.auth = &authConfig{}
}
c.auth.TLS = &authTLSConfig{
cacert: cacert,
cert: cert,
key: key,
}
}
}
func NoCache() Option {
return func(c *config) {
c.noCache = true
}
}
func NoLog() Option {
return func(c *config) {
c.noLog = true
}
}
func GrpcClientOptions(opts ...grpc.ClientOption) Option {
return func(c *config) {
c.clientOptions = opts
}
}
func Logger(logger *zap.Logger) Option {
return func(c *config) {
c.logger = logger
}
}
func AccessLog() Option {
return func(c *config) {
c.accessLog = true
}
}
// Code generated by mockery v2.7.4. DO NOT EDIT.
package mocks
import (
context "context"
version "git.perx.ru/perxis/perxis-go/pkg/version"
mock "github.com/stretchr/testify/mock"
)
// Versions is an autogenerated mock type for the Versions type
type Versions struct {
mock.Mock
}
// Get provides a mock function with given fields: ctx
func (_m *Versions) Get(ctx context.Context) (*version.Version, error) {
ret := _m.Called(ctx)
var r0 *version.Version
if rf, ok := ret.Get(0).(func(context.Context) *version.Version); ok {
r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*version.Version)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
package versions
import (
"context"
"git.perx.ru/perxis/perxis-go/pkg/version"
)
// @microgen grpc
// @protobuf git.perx.ru/perxis/perxis-go/proto/versions/account
// @grpc-addr account.Versions
type Versions interface {
Get(ctx context.Context) (version *version.Version, err error)
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
package transport
import (
"context"
"errors"
version "git.perx.ru/perxis/perxis-go/pkg/version"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
func (set EndpointsSet) Get(arg0 context.Context) (res0 *version.Version, res1 error) {
request := GetRequest{}
response, res1 := set.GetEndpoint(arg0, &request)
if res1 != nil {
if e, ok := status.FromError(res1); ok || e.Code() == codes.Internal || e.Code() == codes.Unknown {
res1 = errors.New(e.Message())
}
return
}
return response.(*GetResponse).Version, res1
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
package transport
import endpoint "github.com/go-kit/kit/endpoint"
// EndpointsSet implements Versions API and used for transport purposes.
type EndpointsSet struct {
GetEndpoint endpoint.Endpoint
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
package transport
import version "git.perx.ru/perxis/perxis-go/pkg/version"
type (
// Formal exchange type, please do not delete.
GetRequest struct{}
GetResponse struct {
Version *version.Version `json:"version"`
}
)
// Code generated by microgen 0.9.1. DO NOT EDIT.
package transportgrpc
import (
transport "git.perx.ru/perxis/perxis-go/pkg/account/versions/transport"
pb "git.perx.ru/perxis/perxis-go/proto/versions/account"
grpckit "github.com/go-kit/kit/transport/grpc"
grpc "google.golang.org/grpc"
)
func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOption) transport.EndpointsSet {
if addr == "" {
addr = "account.Versions"
}
return transport.EndpointsSet{GetEndpoint: grpckit.NewClient(
conn, addr, "Get",
_Encode_Get_Request,
_Decode_Get_Response,
pb.GetResponse{},
opts...,
).Endpoint()}
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
// Please, do not change functions names!
package transportgrpc
import (
"context"
"errors"
transport2 "git.perx.ru/perxis/perxis-go/pkg/account/versions/transport"
pb "git.perx.ru/perxis/perxis-go/proto/versions/account"
empty "github.com/golang/protobuf/ptypes/empty"
)
func _Encode_Get_Request(ctx context.Context, request interface{}) (interface{}, error) {
return &empty.Empty{}, nil
}
func _Encode_Get_Response(ctx context.Context, response interface{}) (interface{}, error) {
if response == nil {
return nil, errors.New("nil GetResponse")
}
resp := response.(*transport2.GetResponse)
respVersion, err := PtrVersionsVersionToProto(resp.Version)
if err != nil {
return nil, err
}
return &pb.GetResponse{Version: respVersion}, nil
}
func _Decode_Get_Request(ctx context.Context, request interface{}) (interface{}, error) {
return &empty.Empty{}, nil
}
func _Decode_Get_Response(ctx context.Context, response interface{}) (interface{}, error) {
if response == nil {
return nil, errors.New("nil GetResponse")
}
resp := response.(*pb.GetResponse)
respVersion, err := ProtoToPtrVersionsVersion(resp.Version)
if err != nil {
return nil, err
}
return &transport2.GetResponse{Version: respVersion}, nil
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
// It is better for you if you do not change functions names!
// This file will never be overwritten.
package transportgrpc
import (
"git.perx.ru/perxis/perxis-go/pkg/version"
"git.perx.ru/perxis/perxis-go/proto/common"
)
func PtrVersionsVersionToProto(version *version.Version) (*common.Version, error) {
pVersion := &common.Version{
ApiVersion: version.APIVersion,
ServerVersion: version.ServerVersion,
Commit: version.Commit,
BuildTime: version.BuildTime,
BuildNumber: int32(version.BuildNumber),
}
return pVersion, nil
}
func ProtoToPtrVersionsVersion(protoVersion *common.Version) (*version.Version, error) {
version := &version.Version{
APIVersion: protoVersion.ApiVersion,
ServerVersion: protoVersion.ServerVersion,
Commit: protoVersion.Commit,
BuildTime: protoVersion.BuildTime,
BuildNumber: int(protoVersion.BuildNumber),
}
return version, nil
}
func PtrVersionVersionToProto(version *version.Version) (*common.Version, error) {
panic("function not provided") // TODO: provide converter
}
func ProtoToPtrVersionVersion(protoVersion *common.Version) (*version.Version, error) {
panic("function not provided") // TODO: provide converter
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
// DO NOT EDIT.
package transportgrpc
import (
transport "git.perx.ru/perxis/perxis-go/pkg/account/versions/transport"
pb "git.perx.ru/perxis/perxis-go/proto/versions/account"
grpc "github.com/go-kit/kit/transport/grpc"
empty "github.com/golang/protobuf/ptypes/empty"
context "golang.org/x/net/context"
)
type versionsServer struct {
get grpc.Handler
pb.UnimplementedVersionsServer
}
func NewGRPCServer(endpoints *transport.EndpointsSet, opts ...grpc.ServerOption) pb.VersionsServer {
return &versionsServer{get: grpc.NewServer(
endpoints.GetEndpoint,
_Decode_Get_Request,
_Encode_Get_Response,
opts...,
)}
}
func (S *versionsServer) Get(ctx context.Context, req *empty.Empty) (*pb.GetResponse, error) {
_, resp, err := S.get.ServeGRPC(ctx, req)
if err != nil {
return nil, err
}
return resp.(*pb.GetResponse), nil
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
package transport
import (
"context"
versions "git.perx.ru/perxis/perxis-go/pkg/account/versions"
endpoint "github.com/go-kit/kit/endpoint"
)
func Endpoints(svc versions.Versions) EndpointsSet {
return EndpointsSet{GetEndpoint: GetEndpoint(svc)}
}
func GetEndpoint(svc versions.Versions) endpoint.Endpoint {
return func(arg0 context.Context, request interface{}) (interface{}, error) {
res0, res1 := svc.Get(arg0)
return &GetResponse{Version: res0}, res1
}
}
// Code generated by mockery v2.7.4. DO NOT EDIT.
package mocks
import (
context "context"
collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
mock "github.com/stretchr/testify/mock"
)
// Observer is an autogenerated mock type for the Observer type
type Observer struct {
mock.Mock
}
// OnCollaboratorSet provides a mock function with given fields: ctx, collaborator
func (_m *Observer) OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (string, error) {
ret := _m.Called(ctx, collaborator)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *collaborators.Collaborator) error); ok {
r0 = rf(ctx, collaborator)
} else {
r0 = ret.Error(0)
}
return "", r0
}
package observer
import (
"context"
"git.perx.ru/perxis/perxis-go/pkg/collaborators"
)
// @microgen grpc
// @protobuf git.perx.ru/perxis/perxis-go/proto/members
// @grpc-addr account.members.Observer
type Observer interface {
OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (delayedTaskID string, err error)
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
package transport
import (
"context"
"errors"
collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
func (set EndpointsSet) OnCollaboratorSet(arg0 context.Context, arg1 *collaborators.Collaborator) (res0 string, res1 error) {
request := OnCollaboratorSetRequest{Collaborator: arg1}
response, res1 := set.OnCollaboratorSetEndpoint(arg0, &request)
if res1 != nil {
if e, ok := status.FromError(res1); ok || e.Code() == codes.Internal || e.Code() == codes.Unknown {
res1 = errors.New(e.Message())
}
return
}
return response.(*OnCollaboratorSetResponse).DelayedTaskID, res1
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
package transport
import endpoint "github.com/go-kit/kit/endpoint"
// EndpointsSet implements Observer API and used for transport purposes.
type EndpointsSet struct {
OnCollaboratorSetEndpoint endpoint.Endpoint
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
package transport
import collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
type (
OnCollaboratorSetRequest struct {
Collaborator *collaborators.Collaborator `json:"collaborator"`
}
OnCollaboratorSetResponse struct {
DelayedTaskID string `json:"delayed_task_id"`
}
)
// Code generated by microgen 0.9.1. DO NOT EDIT.
package transportgrpc
import (
transport "git.perx.ru/perxis/perxis-go/pkg/members/observer/transport"
pb "git.perx.ru/perxis/perxis-go/proto/members"
grpckit "github.com/go-kit/kit/transport/grpc"
grpc "google.golang.org/grpc"
)
func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOption) transport.EndpointsSet {
if addr == "" {
addr = "account.members.Observer"
}
return transport.EndpointsSet{OnCollaboratorSetEndpoint: grpckit.NewClient(
conn, addr, "OnCollaboratorSet",
_Encode_OnCollaboratorSet_Request,
_Decode_OnCollaboratorSet_Response,
pb.OnCollaboratorSetResponse{},
opts...,
).Endpoint()}
}
// Code generated by microgen 0.9.1. DO NOT EDIT.
// Please, do not change functions names!
package transportgrpc
import (
"context"
"errors"
transport "git.perx.ru/perxis/perxis-go/pkg/members/observer/transport"
pb "git.perx.ru/perxis/perxis-go/proto/members"
)
func _Encode_OnCollaboratorSet_Request(ctx context.Context, request interface{}) (interface{}, error) {
if request == nil {
return nil, errors.New("nil OnCollaboratorSetRequest")
}
req := request.(*transport.OnCollaboratorSetRequest)
reqCollaborator, err := PtrCollaboratorsCollaboratorToProto(req.Collaborator)
if err != nil {
return nil, err
}
return &pb.OnCollaboratorSetRequest{Collaborator: reqCollaborator}, nil
}
func _Decode_OnCollaboratorSet_Request(ctx context.Context, request interface{}) (interface{}, error) {
if request == nil {
return nil, errors.New("nil OnCollaboratorSetRequest")
}
req := request.(*pb.OnCollaboratorSetRequest)
reqCollaborator, err := ProtoToPtrCollaboratorsCollaborator(req.Collaborator)
if err != nil {
return nil, err
}
return &transport.OnCollaboratorSetRequest{Collaborator: reqCollaborator}, nil
}
func _Decode_OnCollaboratorSet_Response(ctx context.Context, response interface{}) (interface{}, error) {
if response == nil {
return nil, errors.New("nil OnCollaboratorSetResponse")
}
resp := response.(*pb.OnCollaboratorSetResponse)
return &transport.OnCollaboratorSetResponse{DelayedTaskID: string(resp.DelayedTaskId)}, nil
}
func _Encode_OnCollaboratorSet_Response(ctx context.Context, response interface{}) (interface{}, error) {
if response == nil {
return nil, errors.New("nil OnCollaboratorSetResponse")
}
resp := response.(*transport.OnCollaboratorSetResponse)
return &pb.OnCollaboratorSetResponse{DelayedTaskId: resp.DelayedTaskID}, nil
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment