Skip to content

Commit

Permalink
Merge pull request #6 from solumD/Task-6
Browse files Browse the repository at this point in the history
Task 6
  • Loading branch information
solumD authored Nov 22, 2024
2 parents b5a0b9b + 40b19a0 commit 6e6987f
Show file tree
Hide file tree
Showing 123 changed files with 349 additions and 19,436 deletions.
6 changes: 5 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ HTTP_HOST=localhost
HTTP_PORT=8081

SWAGGER_HOST=localhost
SWAGGER_PORT=8091
SWAGGER_PORT=8091

AUTH_GRPC_HOST=localhost
AUTH_GRPC_PORT=50051
CERT_PATH=./tls/auth/service.pem
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.idea
/bin//coverage.out
/bin
/coverage.out
/tls/
/vendor.protogen
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,12 @@ vendor-proto:
git clone https://github.com/grpc-ecosystem/grpc-gateway vendor.protogen/openapiv2 &&\
mv vendor.protogen/openapiv2/protoc-gen-openapiv2/options/*.proto vendor.protogen/protoc-gen-openapiv2/options &&\
rm -rf vendor.protogen/openapiv2 ;\
fi
fi

gen-cert:
openssl genrsa -out ca.key 4096
openssl req -new -x509 -key ca.key -sha256 -subj "/C=RU/ST=Moscow/O=Solum INC." -days 365 -out ca.cert
openssl genrsa -out service.key 4096
openssl req -new -key service.key -out service.csr -config certificate.conf
openssl x509 -req -in service.csr -CA ca.cert -CAkey ca.key -CAcreateserial \
-out service.pem -days 365 -sha256 -extfile certificate.conf -extensions req_ext
Binary file removed bin/golangci-lint
Binary file not shown.
Binary file removed bin/goose
Binary file not shown.
Binary file removed bin/protoc-gen-go
Binary file not shown.
Binary file removed bin/protoc-gen-go-grpc
Binary file not shown.
Binary file removed bin/protoc-gen-grpc-gateway
Binary file not shown.
Binary file removed bin/protoc-gen-openapiv2
Binary file not shown.
Binary file removed bin/protoc-gen-validate
Binary file not shown.
Binary file removed bin/statik
Binary file not shown.
17 changes: 17 additions & 0 deletions certificate.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[req]
default_bits = 4096
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[dn]
C = RU
ST = Moscow
O = Solum INC.
CN = localhost
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = ::1
IP.2 = 127.0.0.1
13 changes: 6 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,27 @@ require (
github.com/envoyproxy/protoc-gen-validate v1.1.0
github.com/georgysavva/scany v1.2.2
github.com/gojuno/minimock/v3 v3.4.1
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0
github.com/jackc/pgx/v4 v4.18.3
github.com/joho/godotenv v1.5.1
github.com/pkg/errors v0.9.1
github.com/rakyll/statik v0.1.7
github.com/stretchr/testify v1.8.4
github.com/solumD/auth v0.0.0-20241121111616-95b6b5d31eea
github.com/stretchr/testify v1.9.0
google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38
)

require (
github.com/rogpeppe/go-internal v1.13.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
require gopkg.in/yaml.v3 v3.0.1 // indirect

require (
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.14.3
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgtype v1.14.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgtype v1.14.4 // indirect
github.com/jackc/puddle v1.3.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
Expand Down
114 changes: 109 additions & 5 deletions go.sum

Large diffs are not rendered by default.

30 changes: 26 additions & 4 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,28 @@ import (

"github.com/solumD/chat-server/internal/closer"
"github.com/solumD/chat-server/internal/config"
"github.com/solumD/chat-server/internal/interceptor"
desc "github.com/solumD/chat-server/pkg/chat_v1"
_ "github.com/solumD/chat-server/statik" //

grpcMW "github.com/grpc-ecosystem/go-grpc-middleware"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/rakyll/statik/fs"
"github.com/rs/cors"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
)

const configPath = ".env"
const (
configPath = ".env"
)

var (
corsAllowedMethods = []string{"GET", "POST", "DELETE", "OPTIONS"}
corsAllowedHeaders = []string{"Accept", "Content-Type", "Content-Length", "Authorization"}
)

// App структура приложения
type App struct {
Expand Down Expand Up @@ -121,7 +131,19 @@ func (a *App) initServiceProvider() {
}

func (a *App) initGRPCServer(ctx context.Context) {
a.grpcServer = grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
creds, err := credentials.NewServerTLSFromFile("./tls/service/service.pem", "./tls/service/service.key")
if err != nil {
log.Fatalf("failed to load TLS keys: %v", err)
}

a.grpcServer = grpc.NewServer(
grpc.UnaryInterceptor(
grpcMW.ChainUnaryServer(
interceptor.ValidateInterceptor,
interceptor.NewAuthInterceptor(a.serviceProvider.AuthClient(ctx)).Get()),
),
grpc.Creds(creds),
)

reflection.Register(a.grpcServer)

Expand All @@ -143,8 +165,8 @@ func (a *App) initHTTPServer(ctx context.Context) error {

corsMiddleware := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "POST", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Content-Type", "Content-Length", "Authorization"},
AllowedMethods: corsAllowedMethods,
AllowedHeaders: corsAllowedHeaders,
AllowCredentials: true,
})

Expand Down
45 changes: 43 additions & 2 deletions internal/app/service_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"context"
"log"

"github.com/solumD/auth/pkg/access_v1"
api "github.com/solumD/chat-server/internal/api/chat"
"github.com/solumD/chat-server/internal/client/auth"
"github.com/solumD/chat-server/internal/client/db"
"github.com/solumD/chat-server/internal/client/db/pg"
"github.com/solumD/chat-server/internal/client/db/transaction"
Expand All @@ -14,6 +16,8 @@ import (
chatRepo "github.com/solumD/chat-server/internal/repository/chat"
"github.com/solumD/chat-server/internal/service"
chatSrv "github.com/solumD/chat-server/internal/service/chat"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)

// Структура приложения со всеми зависимостями
Expand All @@ -22,9 +26,11 @@ type serviceProvider struct {
grpcConfig config.GRPCConfig
httpConfig config.HTTPConfig
swaggerConfig config.SwaggerConfig
authConfig config.AuthConfig

dbClient db.Client
txManager db.TxManager
dbClient db.Client
txManager db.TxManager
authClient auth.Client

chatRepository repository.ChatRepository
chatService service.ChatService
Expand Down Expand Up @@ -92,6 +98,20 @@ func (s *serviceProvider) SwaggerConfig() config.HTTPConfig {
return s.swaggerConfig
}

// AuthConfig инициализирует конфиг auth клиента
func (s *serviceProvider) AuthConfig() config.AuthConfig {
if s.authConfig == nil {
cfg, err := config.NewAuthConfig()
if err != nil {
log.Fatalf("failed to get auth config")
}

s.authConfig = cfg
}

return s.authConfig
}

// DBClient инициализирует клиент базы данных
func (s *serviceProvider) DBClient(ctx context.Context) db.Client {
if s.dbClient == nil {
Expand All @@ -112,6 +132,27 @@ func (s *serviceProvider) DBClient(ctx context.Context) db.Client {
return s.dbClient
}

func (s *serviceProvider) AuthClient(ctx context.Context) auth.Client {
if s.authClient == nil {
creds, err := credentials.NewClientTLSFromFile(s.AuthConfig().CertPath(), "")
if err != nil {
log.Fatalf("could not process credentials: %v", err)
}

conn, err := grpc.DialContext(ctx, s.AuthConfig().Address(), grpc.WithTransportCredentials(creds))
if err != nil {
log.Fatalf("failed to connect to %s: %v", s.AuthConfig().Address(), err)
}

closer.Add(conn.Close)

client := access_v1.NewAccessV1Client(conn)
s.authClient = auth.New(client)
}

return s.authClient
}

// TxManager инициализирует менеджер транзакций
func (s *serviceProvider) TxManager(ctx context.Context) db.TxManager {
if s.txManager == nil {
Expand Down
37 changes: 37 additions & 0 deletions internal/client/auth/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package auth

import (
"context"
"fmt"

"github.com/solumD/auth/pkg/access_v1"
)

// Client интерфейс клиента auth
type Client interface {
Check(ctx context.Context, endpoint string) error
}

type client struct {
accessClient access_v1.AccessV1Client
}

// New возвращает новый объект клиента auth
func New(accessClient access_v1.AccessV1Client) Client {
return &client{
accessClient: accessClient,
}
}

// Check отправляет запрос в сервис auth на проверкку доступа
func (c *client) Check(ctx context.Context, endpoint string) error {
req := &access_v1.CheckRequest{
EndpointAddress: endpoint,
}

if _, err := c.accessClient.Check(ctx, req); err != nil {
return fmt.Errorf("access check error: %v", err)
}

return nil
}
52 changes: 52 additions & 0 deletions internal/config/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package config

import (
"errors"
"net"
"os"
)

const (
authGrpcHostEnvName = "AUTH_GRPC_HOST"
authGrpcPortEnvName = "AUTH_GRPC_PORT"
authCertPathEnvName = "CERT_PATH"
)

type authConfig struct {
host string
port string
certPath string
}

// NewAuthConfig returns new auth client config
func NewAuthConfig() (AuthConfig, error) {
host := os.Getenv(authGrpcHostEnvName)
if len(host) == 0 {
return nil, errors.New("auth client host not found")
}

port := os.Getenv(authGrpcPortEnvName)
if len(port) == 0 {
return nil, errors.New("auth client port not found")
}

certPath := os.Getenv(authCertPathEnvName)
if len(certPath) == 0 {
return nil, errors.New("cert path not found")
}

return &authConfig{
host: host,
port: port,
certPath: certPath,
}, nil
}

// Address returns a full address of a auth client
func (cfg *authConfig) Address() string {
return net.JoinHostPort(cfg.host, cfg.port)
}

func (cfg *authConfig) CertPath() string {
return cfg.certPath
}
6 changes: 6 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ type SwaggerConfig interface {
Address() string
}

// AuthConfig интерфейс конфига клиента auth
type AuthConfig interface {
Address() string
CertPath() string
}

// Load reads ,env file from path and loads
// variables into a project
func Load(path string) error {
Expand Down
36 changes: 36 additions & 0 deletions internal/interceptor/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package interceptor

import (
"context"

"github.com/solumD/chat-server/internal/client/auth"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)

type authInterceptor struct {
authClient auth.Client
}

// NewAuthInterceptor возвращает структуру интерцептора auth
func NewAuthInterceptor(authClient auth.Client) *authInterceptor {
return &authInterceptor{
authClient: authClient,
}
}

// Get возвращает интерцептор, который делает запрос к сервису auth
func (i *authInterceptor) Get() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
md, ok := metadata.FromIncomingContext(ctx)
if ok {
ctx = metadata.NewOutgoingContext(ctx, md)
}

if err = i.authClient.Check(ctx, info.FullMethod); err != nil {
return nil, err
}

return handler(ctx, req)
}
}
Loading

0 comments on commit 6e6987f

Please sign in to comment.