From ec206bae2e0cc074c1ff885be8cbdc86d3056a61 Mon Sep 17 00:00:00 2001 From: Jacob Lindgren Date: Mon, 5 Feb 2024 11:35:22 -0600 Subject: [PATCH] add ALLOWLIST_ENABLED configuration setting --- deployments/deployment.yaml | 5 +++ internal/config/config.go | 3 ++ internal/handlers/allowlist_handler.go | 8 +++-- internal/handlers/registration_handler.go | 42 +++++++++++++---------- internal/store/in_memory_store_impl.go | 2 +- internal/store/interface.go | 2 +- internal/store/postgres_store_impl.go | 6 ++-- 7 files changed, 40 insertions(+), 28 deletions(-) diff --git a/deployments/deployment.yaml b/deployments/deployment.yaml index 443a064..6b07069 100644 --- a/deployments/deployment.yaml +++ b/deployments/deployment.yaml @@ -131,6 +131,8 @@ objects: value: ${TOKEN_TTL_DURATION} - name: STORE_BACKEND value: ${STORE_BACKEND} + - name: ALLOWLIST_ENABLED + value: ${ALLOWLIST_ENABLED} - name: DISABLE_CATCHALL value: ${DISABLE_CATCHALL} - name: IS_INTERNAL_LABEL @@ -325,3 +327,6 @@ parameters: - name: CERT_DIR description: the base directory where ssl certs are stored value: "/certs" +- name: ALLOWLIST_ENABLED + description: whether to check registrations against the internal allowlist + value: "false" diff --git a/internal/config/config.go b/internal/config/config.go index 46d0d8d..8b0fce3 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -40,6 +40,7 @@ type MbopConfig struct { KeyCloakTokenGrantType string KeyCloakTokenClientID string + AllowlistEnabled bool StoreBackend string DatabaseHost string DatabasePort string @@ -61,6 +62,7 @@ func Get() *MbopConfig { } disableCatchAll, _ := strconv.ParseBool(fetchWithDefault("DISABLE_CATCHALL", "false")) + allowlistEnabled, _ := strconv.ParseBool(fetchWithDefault("ALLOWLIST_ENABLED", "false")) debug, _ := strconv.ParseBool(fetchWithDefault("DEBUG", "false")) certDir := fetchWithDefault("CERT_DIR", "/certs") keyCloakTimeout, _ := strconv.ParseInt(fetchWithDefault("KEYCLOAK_TIMEOUT", "60"), 0, 64) @@ -90,6 +92,7 @@ func Get() *MbopConfig { DatabasePassword: fetchWithDefault("DATABASE_PASSWORD", ""), DatabaseName: fetchWithDefault("DATABASE_NAME", "mbop"), StoreBackend: fetchWithDefault("STORE_BACKEND", "memory"), + AllowlistEnabled: allowlistEnabled, CognitoAppClientID: fetchWithDefault("COGNITO_APP_CLIENT_ID", ""), CognitoAppClientSecret: fetchWithDefault("COGNITO_APP_CLIENT_SECRET", ""), diff --git a/internal/handlers/allowlist_handler.go b/internal/handlers/allowlist_handler.go index 947dd68..84e88ab 100644 --- a/internal/handlers/allowlist_handler.go +++ b/internal/handlers/allowlist_handler.go @@ -4,10 +4,10 @@ import ( "encoding/json" "errors" "net/http" - "runtime" "time" "github.com/go-chi/chi/v5" + l "github.com/redhatinsights/mbop/internal/logger" "github.com/redhatinsights/mbop/internal/store" "github.com/redhatinsights/platform-go-middlewares/identity" ) @@ -85,7 +85,6 @@ func AllowlistListHandler(w http.ResponseWriter, r *http.Request) { db := store.GetStore() - runtime.Breakpoint() addrs, err := db.AllowedAddresses(id.Identity.OrgID) if err != nil { do500(w, "error listing addresses: %w"+err.Error()) @@ -101,5 +100,8 @@ func AllowlistListHandler(w http.ResponseWriter, r *http.Request) { } } - json.NewEncoder(w).Encode(out) + err = json.NewEncoder(w).Encode(out) + if err != nil { + l.Log.Info("failed to encode response", "error", err) + } } diff --git a/internal/handlers/registration_handler.go b/internal/handlers/registration_handler.go index 75b6639..f7c6843 100644 --- a/internal/handlers/registration_handler.go +++ b/internal/handlers/registration_handler.go @@ -8,6 +8,7 @@ import ( "time" "github.com/go-chi/chi/v5" + "github.com/redhatinsights/mbop/internal/config" "github.com/redhatinsights/mbop/internal/store" "github.com/redhatinsights/platform-go-middlewares/identity" ) @@ -78,27 +79,21 @@ func RegistrationListHandler(w http.ResponseWriter, r *http.Request) { func RegistrationCreateHandler(w http.ResponseWriter, r *http.Request) { id := identity.Get(r.Context()) - if !id.Identity.User.OrgAdmin { - doError(w, "user must be org admin to register satellite", 403) - return - } - if id.Identity.User.Username == "" { - do400(w, "[username] not present in identity header") - return - } - db := store.GetStore() - allowed, err := db.AllowedIP(&store.Address{ - IP: r.Header.Get("x-forwarded-for"), - OrgID: id.Identity.OrgID, - }) - if err != nil { - do500(w, "error listing ip addresses: "+err.Error()) - return - } - if !allowed { - doError(w, "address is not allowlisted", 403) + if config.Get().AllowlistEnabled { + allowed, err := db.AllowedIP(&store.Address{ + IP: r.Header.Get("x-forwarded-for"), + OrgID: id.Identity.OrgID, + }) + if err != nil { + do500(w, "error listing ip addresses: "+err.Error()) + return + } + if !allowed { + doError(w, "address is not allowlisted", 403) + return + } } b, err := io.ReadAll(r.Body) @@ -124,6 +119,15 @@ func RegistrationCreateHandler(w http.ResponseWriter, r *http.Request) { return } + if !id.Identity.User.OrgAdmin { + doError(w, "user must be org admin to register satellite", 403) + return + } + if id.Identity.User.Username == "" { + do400(w, "[username] not present in identity header") + return + } + gatewayCN, err := getCertCN(r.Header.Get(CertHeader)) if err != nil { do400(w, err.Error()) diff --git a/internal/store/in_memory_store_impl.go b/internal/store/in_memory_store_impl.go index c27febb..a6a6366 100644 --- a/internal/store/in_memory_store_impl.go +++ b/internal/store/in_memory_store_impl.go @@ -76,7 +76,7 @@ func (m *inMemoryStore) Delete(orgID string, uid string) error { return ErrRegistrationNotFound } -func (m *inMemoryStore) AllowedAddresses(orgID string) ([]Address, error) { +func (m *inMemoryStore) AllowedAddresses(_ string) ([]Address, error) { return m.allowedAddresses, nil } func (m *inMemoryStore) AllowedIP(ip *Address) (bool, error) { diff --git a/internal/store/interface.go b/internal/store/interface.go index 1756b48..debdc82 100644 --- a/internal/store/interface.go +++ b/internal/store/interface.go @@ -17,7 +17,7 @@ type RegistrationStore interface { } type AllowlistStore interface { - AllowedAddresses(orgId string) ([]Address, error) + AllowedAddresses(orgID string) ([]Address, error) AllowedIP(ip *Address) (bool, error) AllowAddress(ip *Address) error DenyAddress(ip *Address) error diff --git a/internal/store/postgres_store_impl.go b/internal/store/postgres_store_impl.go index 31b220a..829c6e1 100644 --- a/internal/store/postgres_store_impl.go +++ b/internal/store/postgres_store_impl.go @@ -3,7 +3,6 @@ package store import ( "database/sql" "encoding/json" - "runtime" "time" // the pgx driver for the database @@ -210,16 +209,15 @@ func (p *postgresStore) DenyAddress(ip *Address) error { return nil } -func (p *postgresStore) AllowedAddresses(orgId string) ([]Address, error) { +func (p *postgresStore) AllowedAddresses(orgID string) ([]Address, error) { rows, err := p.db.Query(`select org_id, ip, created_at from allowlist - where org_id = $1`, orgId) + where org_id = $1`, orgID) if err != nil { return nil, err } - runtime.Breakpoint() addresses := make([]Address, 0) for rows.Next() { var (