From fa090dbf5b6fa149a39247e1adf1c14a100b59b9 Mon Sep 17 00:00:00 2001 From: "David J. Allen" Date: Sun, 10 Mar 2024 20:15:19 -0600 Subject: [PATCH] Added cache files --- internal/cache/sqlite/clients.go | 154 ++++++++++++++++++++++++++++ internal/cache/sqlite/providers.go | 156 +++++++++++++++++++++++++++++ internal/cache/sqlite/trusted.go | 107 ++++++++++++++++++++ 3 files changed, 417 insertions(+) create mode 100644 internal/cache/sqlite/clients.go create mode 100644 internal/cache/sqlite/providers.go create mode 100644 internal/cache/sqlite/trusted.go diff --git a/internal/cache/sqlite/clients.go b/internal/cache/sqlite/clients.go new file mode 100644 index 0000000..00af1aa --- /dev/null +++ b/internal/cache/sqlite/clients.go @@ -0,0 +1,154 @@ +package cache + +import ( + "davidallendj/opaal/internal/oauth" + "fmt" + + "github.com/jmoiron/sqlx" +) + +func CreateOAuthClientsIfNotExists(path string) (*sqlx.DB, error) { + schema := ` + CREATE TABLE IF NOT EXISTS oauth_clients ( + id TEXT NOT NULL, + secret TEXT NOT NULL, + name TEXT, + description TEXT, + issuer TEXT, + registration_access_token TEXT, + redirect_uris TEXT, + scope TEXT + PRIMARY KEY (id) + ); + ` + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return nil, fmt.Errorf("could not open database: %v", err) + } + db.MustExec(schema) + return db, nil +} + +func InsertOAuthClients(path string, clients *[]oauth.Client) error { + if clients == nil { + return fmt.Errorf("states == nil") + } + + // create database if it doesn't already exist + db, err := CreateOAuthClientsIfNotExists(path) + if err != nil { + return err + } + + // insert all probe states into db + tx := db.MustBegin() + for _, state := range *clients { + sql := `INSERT OR REPLACE INTO oauth_clients + ( + id, + secret, + name, + description, + issuer, + registration_access_token, + redirect_uris, + scope + ) + VALUES + ( + :id, + :secret, + :name, + :description, + :issuer, + :registration_access_token, + :redirect_uris, + :scope + );` + _, err := tx.NamedExec(sql, &state) + if err != nil { + fmt.Printf("could not execute transaction: %v\n", err) + } + } + err = tx.Commit() + if err != nil { + return fmt.Errorf("could not commit transaction: %v", err) + } + return nil +} + +func GetOAuthClient(path string, id string) (*oauth.Client, error) { + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return nil, fmt.Errorf("could not open database: %v", err) + } + + results := &oauth.Client{} + err = db.Select(&results, "SELECT * FROM oauth_clients ORDER BY host ASC, port ASC LIMIT 1;") + if err != nil { + return nil, fmt.Errorf("could not retrieve probes: %v", err) + } + return results, nil +} + +func GetOAuthClients(path string) ([]oauth.Client, error) { + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return nil, fmt.Errorf("could not open database: %v", err) + } + + results := []oauth.Client{} + err = db.Select(&results, "SELECT * FROM oauth_clients;") + if err != nil { + return nil, fmt.Errorf("could not retrieve probes: %v", err) + } + return results, nil +} + +func UpdateOAuthClient(path string, clients *[]oauth.Client) error { + if clients == nil { + return fmt.Errorf("clients is nil") + } + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return fmt.Errorf("could not open database: %v", err) + } + tx := db.MustBegin() + for _, state := range *clients { + sql := `UPDATE FROM identity_providers WHERE client_id = :client_id;` + _, err := tx.NamedExec(sql, &state) + if err != nil { + fmt.Printf("could not execute transaction: %v\n", err) + } + } + + err = tx.Commit() + if err != nil { + return fmt.Errorf("could not commit transaction: %v", err) + } + return nil +} + +func DeleteOAuthClients(path string, clientIds []string) error { + if clientIds == nil { + return fmt.Errorf("no probe results found") + } + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return fmt.Errorf("could not open database: %v", err) + } + tx := db.MustBegin() + for _, state := range clientIds { + sql := `DELETE FROM identity_providers WHERE client_id = :client_id;` + _, err := tx.NamedExec(sql, &state) + if err != nil { + fmt.Printf("could not execute transaction: %v\n", err) + } + } + + err = tx.Commit() + if err != nil { + return fmt.Errorf("could not commit transaction: %v", err) + } + return nil +} diff --git a/internal/cache/sqlite/providers.go b/internal/cache/sqlite/providers.go new file mode 100644 index 0000000..893cc03 --- /dev/null +++ b/internal/cache/sqlite/providers.go @@ -0,0 +1,156 @@ +package cache + +import ( + "davidallendj/opaal/internal/oidc" + "fmt" + + "github.com/jmoiron/sqlx" + _ "github.com/mattn/go-sqlite3" +) + +func CreateIdentityProvidersIfNotExists(path string) (*sqlx.DB, error) { + schema := ` + CREATE TABLE IF NOT EXISTS identity_providers ( + issuer TEXT NOT NULL, + authorization_endpoint TEXT, + token_endpoint TEXT, + revocation_endpoint TEXT, + introspection_endpoint TEXT, + userinfo_endpoint TEXT, + jwks_uri TEXT, + response_types_supported TEXT, + response_modes_supported TEXT, + grant_types_supported TEXT, + token_endpoint_auth_methods_supported TEXT, + subject_types_supported TEXT, + id_token_signing_alg_values_supported TEXT, + claim_types_supported TEXT, + claims_supported TEXT, + jwks TEXT, + + PRIMARY KEY (issuer) + ); + ` + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return nil, fmt.Errorf("could not open database: %v", err) + } + db.MustExec(schema) + return db, nil +} + +func InsertIdentityProviders(path string, providers *[]oidc.IdentityProvider) error { + if providers == nil { + return fmt.Errorf("states == nil") + } + + // create database if it doesn't already exist + db, err := CreateIdentityProvidersIfNotExists(path) + if err != nil { + return err + } + + // insert all probe states into db + tx := db.MustBegin() + for _, state := range *providers { + sql := `INSERT OR REPLACE INTO identity_providers + ( + issuer, + authorization_endpoint, + token_endpoint, + revocation_endpoint, + introspection_endpoint, + userinfo_endpoint, + jwks_uri, + response_types_supported, + response_modes_supported, + grant_types_supported, + token_endpoint_auth_methods_supported, + subject_types_supported, + id_token_signing_alg_values_supported, + claim_types_supported, + claims_supported, + jwks + ) + VALUES + ( + :issuer, + :authorization_endpoint, + :token_endpoint, + :revocation_endpoint, + :introspection_endpoint, + :userinfo_endpoint, + :jwks_uri, + :response_types_supported, + :response_modes_supported, + :grant_types_supported, + :token_endpoint_auth_methods_supported, + :subject_types_supported, + :id_token_signing_alg_values_supported, + :claim_types_supported, + :claims_supported, + :jwks + );` + _, err := tx.NamedExec(sql, &state) + if err != nil { + fmt.Printf("could not execute transaction: %v\n", err) + } + } + err = tx.Commit() + if err != nil { + return fmt.Errorf("could not commit transaction: %v", err) + } + return nil +} + +func GetIdentityProvider(path string, issuer string) (*oidc.IdentityProvider, error) { + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return nil, fmt.Errorf("could not open database: %v", err) + } + + results := &oidc.IdentityProvider{} + err = db.Select(&results, "SELECT * FROM magellan_scanned_ports ORDER BY host ASC, port ASC LIMIT 1;") + if err != nil { + return nil, fmt.Errorf("could not retrieve probes: %v", err) + } + return results, nil +} + +func GetIdentityProviders(path string) ([]oidc.IdentityProvider, error) { + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return nil, fmt.Errorf("could not open database: %v", err) + } + + results := []oidc.IdentityProvider{} + err = db.Select(&results, "SELECT * FROM magellan_scanned_ports ORDER BY host ASC, port ASC;") + if err != nil { + return nil, fmt.Errorf("could not retrieve probes: %v", err) + } + return results, nil +} + +func DeleteIdentityProviders(path string, results *[]oidc.IdentityProvider) error { + if results == nil { + return fmt.Errorf("no probe results found") + } + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return fmt.Errorf("could not open database: %v", err) + } + tx := db.MustBegin() + for _, state := range *results { + sql := `DELETE FROM identity_providers WHERE host = :issuer;` + _, err := tx.NamedExec(sql, &state) + if err != nil { + fmt.Printf("could not execute transaction: %v\n", err) + } + } + + err = tx.Commit() + if err != nil { + return fmt.Errorf("could not commit transaction: %v", err) + } + return nil +} diff --git a/internal/cache/sqlite/trusted.go b/internal/cache/sqlite/trusted.go new file mode 100644 index 0000000..ecc6145 --- /dev/null +++ b/internal/cache/sqlite/trusted.go @@ -0,0 +1,107 @@ +package cache + +import ( + "davidallendj/opaal/internal/oauth" + "fmt" + + "github.com/jmoiron/sqlx" +) + +func CreateTrustedIfNotExists(path string) (*sqlx.DB, error) { + schema := ` + CREATE TABLE IF NOT EXISTS trusted_issuers ( + id TEXT NOT NULL, + allow_any_subject NUMBER, + expires_at NUMBER, + issuer TEXT, + public_key NUMBER, + scope TEXT, + subject TEXT, + PRIMARY KEY (id) + ); + ` + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return nil, fmt.Errorf("could not open database: %v", err) + } + db.MustExec(schema) + return db, nil +} + +func InsertTrustedIssuer(path string, issuer *oauth.TrustedIssuer) error { + // create database if it doesn't already exist + db, err := CreateOAuthClientsIfNotExists(path) + if err != nil { + return err + } + + // insert all probe states into db + tx := db.MustBegin() + sql := `INSERT OR REPLACE INTO trusted_issuers + ( + id, + allow_any_subject + expires_at, + issuer, + public_key, + scope, + subject + ) + VALUES + ( + :id, + :allow_any_subject, + :expires_at, + :issuer, + :public_key, + :scope, + :subject + );` + _, err = tx.NamedExec(sql, &issuer) + if err != nil { + fmt.Printf("could not execute transaction: %v\n", err) + } + err = tx.Commit() + if err != nil { + return fmt.Errorf("could not commit transaction: %v", err) + } + return nil +} + +func GetTrustedIssuer(path string, issuer string) (*oauth.TrustedIssuer, error) { + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return nil, fmt.Errorf("could not open database: %v", err) + } + + results := &oauth.TrustedIssuer{} + err = db.Select(&results, "SELECT * FROM trusted_issuers ORDER BY host ASC, port ASC LIMIT 1;") + if err != nil { + return nil, fmt.Errorf("could not retrieve probes: %v", err) + } + return results, nil +} + +func DeleteTrustedIssuer(path string, ids []string) error { + if ids == nil { + return fmt.Errorf("no probe results found") + } + db, err := sqlx.Open("sqlite3", path) + if err != nil { + return fmt.Errorf("could not open database: %v", err) + } + tx := db.MustBegin() + for _, state := range ids { + sql := `DELETE FROM identity_providers WHERE id = :id;` + _, err := tx.NamedExec(sql, &state) + if err != nil { + fmt.Printf("could not execute transaction: %v\n", err) + } + } + + err = tx.Commit() + if err != nil { + return fmt.Errorf("could not commit transaction: %v", err) + } + return nil +}