diff --git a/servers/gateway/gateway.go b/servers/gateway/gateway.go index 425a05a..14925ae 100644 --- a/servers/gateway/gateway.go +++ b/servers/gateway/gateway.go @@ -21,7 +21,14 @@ package gateway import ( "compress/gzip" "context" + "crypto/subtle" "fmt" + "log" + "mime" + "net/http" + "os" + "strings" + "github.com/7cav/api/cache" "github.com/7cav/api/middleware" "github.com/7cav/api/proto" @@ -29,16 +36,12 @@ import ( "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/rakyll/statik/fs" "google.golang.org/grpc" - "log" - "mime" - "net/http" - "os" - "strings" ) type Service struct { Address string Cache *cache.RedisCache + APISecret string } var ( @@ -59,6 +62,21 @@ func getOpenAPIHandler() http.Handler { return http.FileServer(statikFs) } +func authMiddleware(secret string, next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + authHeader := r.Header.Get("Authorization") + token := strings.TrimPrefix(authHeader, "Bearer ") + + if subtle.ConstantTimeCompare([]byte(token), []byte(secret)) != 1 { + Warn.Printf("Unauthorized HTTP access attempt from %s", r.RemoteAddr) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + next.ServeHTTP(w, r) + }) +} + func compressionMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { @@ -118,7 +136,8 @@ func (service *Service) Server() *http.Server { openApi := getOpenAPIHandler() - handler := middleware.CacheMiddleware(service.Cache, compressionMiddleware(gwMux)) + handler := authMiddleware(service.APISecret, + middleware.CacheMiddleware(service.Cache, compressionMiddleware(gwMux))) // if requests start with /api then forward it on to the grpc-gateway client // otherwise, just serve it as norma (basically the OpenAPI) diff --git a/servers/server.go b/servers/server.go index 262e5a0..eb3c36a 100644 --- a/servers/server.go +++ b/servers/server.go @@ -38,7 +38,7 @@ import ( "gorm.io/gorm" ) -const version = "2.0.0" +const version = "2.0.1" type MicroServer struct { addr string @@ -181,7 +181,8 @@ func servGRPC(server *MicroServer, lis net.Listener, grpcOpts []grpc.ServerOptio } func servHTTP(server *MicroServer, lis net.Listener) { - service := httpServices.Service{Address: server.addr, Cache: server.cache} + secret := setupAuth() + service := httpServices.Service{Address: server.addr, Cache: server.cache, APISecret: secret,} server.httpServer = service.Server() if err := server.httpServer.Serve(lis); err != nil { Error.Fatalf("unable to start HTTP servers: ", err)