From 009ced969a2345cf4ed568e76012c1dcdb94e7f5 Mon Sep 17 00:00:00 2001 From: satyam1023 Date: Mon, 21 Apr 2025 16:39:51 +0530 Subject: [PATCH 1/4] getpolicydetails --- go.mod | 5 ++- go.sum | 19 +++++++++++ src/pkg/checkout.go | 79 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index a540ed1..b295914 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,10 @@ module github.com/authnull0/database-agent go 1.22.1 -require github.com/spf13/viper v1.19.0 +require ( + github.com/google/uuid v1.4.0 + github.com/spf13/viper v1.19.0 +) require ( filippo.io/edwards25519 v1.1.0 // indirect diff --git a/go.sum b/go.sum index dd57622..764e5b8 100644 --- a/go.sum +++ b/go.sum @@ -5,9 +5,13 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJc github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+8Y+8shw= github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= @@ -16,10 +20,18 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60= github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -31,6 +43,10 @@ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6 github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= @@ -56,6 +72,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= @@ -88,6 +105,8 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/src/pkg/checkout.go b/src/pkg/checkout.go index 964ad2a..c7c6525 100644 --- a/src/pkg/checkout.go +++ b/src/pkg/checkout.go @@ -14,6 +14,7 @@ import ( "time" "github.com/authnull0/database-agent/utils" + "github.com/google/uuid" ) type GetAllJobQueueRequest struct { @@ -29,6 +30,7 @@ type GetAllJobQueueResponse struct { Data []JobQueue `json:"data"` } type JobQueue struct { + PolicyID uuid.UUID `gorm:"primaryKey;column:id"` ID int `gorm:"primaryKey;column:id"` JobName string `gorm:"column:job_name"` Status string `gorm:"column:status"` @@ -61,7 +63,24 @@ type CreateDatabaseCredentialRequestDto struct { Password string `json:"password"` } +type GetPolicyDetails struct { + OrgId int `json:"orgId"` + TenantId int `json:"tenantId"` + PolicyID uuid.UUID `json:"policyId"` +} + +type GetPolicyDetailsResponse struct { + Code int `json:"code"` + Message string `json:"message"` + DatabaseName string `json:"database_name"` + Tables []string `json:"tables"` + FieldMasking map[string][]string `json:"field_masking"` + User string `json:"user"` + Privilege []string `json:"privilege"` +} + func PollCheckoutJob(db *sql.DB, dbName string, Config DBConfig) error { + //API call to get all jobs from the queue url := "https://prod.api.authnull.com/api/v1/databaseService/getJobQueue" orgID, _ := strconv.Atoi(Config.OrgID) @@ -118,10 +137,15 @@ func PollCheckoutJob(db *sql.DB, dbName string, Config DBConfig) error { log.Printf("No jobs found in the queue") return nil } - //Iterate through the jobs and process them for _, job := range response.Data { //Call Other Function to rotate the Password for the DB User in the Database + policyDetails, err := FetchPolicyDetails(orgID, tenantID, job.PolicyID) + if err != nil { + log.Printf("Error fetching policy details for job %s: %v", job.JobName, err) + continue + } + fmt.Println("Policy details:", policyDetails) success, err := GenerateCredentials(db, Config, dbName, response.DbUserName, job.Host, job.WalletUserID, job.IssuerID, job.Table_Name, job.Fields, job.Privilege) if err != nil { @@ -169,7 +193,40 @@ func PollCheckoutJob(db *sql.DB, dbName string, Config DBConfig) error { return nil } -func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName string, host string, WalletUserID int, IssuerId int, TableName string, Fields string, Privlege string) (bool, error) { + +func FetchPolicyDetails(orgID int, tenantID int, policyID uuid.UUID) (*GetPolicyDetailsResponse, error) { + url := "https://prod.api.authnull.com/api/v1/policyService/getPolicyDetails" + + // Prepare the payload + payload := GetPolicyDetails{ + OrgId: orgID, + TenantId: tenantID, + PolicyID: policyID, + } + + payloadBytes, _ := json.Marshal(payload) + req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes)) + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + var result GetPolicyDetailsResponse + if err := json.Unmarshal(body, &result); err != nil { + return nil, err + } + if result.Code != 200 { + return nil, fmt.Errorf("failed to fetch policy: %s", result.Message) + } + + return &result, nil +} + +func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName string, host string, WalletUserID int, IssuerId int, TableName string, Fields string, Privlege string, policyID uuid.UUID) (bool, error) { //Rotate the Credentials for the DB User in the Database //Step1 : Generate a Random Password for the DB User password, err := GenerateRandomPassword(16) @@ -247,8 +304,20 @@ func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName return false, err } log.Printf("Password for user %s updated successfully in ProxySQL", dbUserName) + orgId, _ := strconv.Atoi(Config.OrgID) tenantId, _ := strconv.Atoi(Config.TenantID) + + policyDetails, err := FetchPolicyDetails(orgId, tenantId, policyID) + if err != nil { + log.Printf("Error while fetching policy details: %v", err) + return false, err + } + + // Populate Tables, FieldMasking, and Privilege from the policy details + tables := policyDetails.Tables + fieldMasking := policyDetails.FieldMasking + privilege := policyDetails.Privilege //Step3 : Call Create Database Credential API //Create the request body databaseCredentialRequest := CreateDatabaseCredentialRequestDto{ @@ -260,10 +329,10 @@ func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName CredentialType: "DATABASE", DatabaseName: dbName, Password: password, - Tables: []string{TableName}, - FieldMasking: map[string][]string{TableName: {Fields}}, + Tables: tables, + FieldMasking: fieldMasking, DBUser: dbUserName, - Privilege: []string{Privlege}, + Privilege: privilege, } //Call the API err = CallCreateDatabaseCredentialAPI(databaseCredentialRequest) From 4538b6c516c298cb205e80b416f4570009a3e96c Mon Sep 17 00:00:00 2001 From: satyam1023 Date: Mon, 21 Apr 2025 16:41:57 +0530 Subject: [PATCH 2/4] getpolicydetails --- src/pkg/checkout.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkg/checkout.go b/src/pkg/checkout.go index c7c6525..e7ed904 100644 --- a/src/pkg/checkout.go +++ b/src/pkg/checkout.go @@ -147,7 +147,7 @@ func PollCheckoutJob(db *sql.DB, dbName string, Config DBConfig) error { } fmt.Println("Policy details:", policyDetails) - success, err := GenerateCredentials(db, Config, dbName, response.DbUserName, job.Host, job.WalletUserID, job.IssuerID, job.Table_Name, job.Fields, job.Privilege) + success, err := GenerateCredentials(db, Config, dbName, response.DbUserName, job.Host, job.WalletUserID, job.IssuerID, job.Table_Name, job.Fields, job.Privilege, job.PolicyID) if err != nil { log.Printf("Error while generating credentials: %v", err) continue From 02115cf8167af7ba6d77e034d0b777a166007682 Mon Sep 17 00:00:00 2001 From: satyam1023 Date: Mon, 21 Apr 2025 17:25:31 +0530 Subject: [PATCH 3/4] unmarshalling the json and then populating --- src/pkg/checkout.go | 111 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 20 deletions(-) diff --git a/src/pkg/checkout.go b/src/pkg/checkout.go index 9dcf57c..6297725 100644 --- a/src/pkg/checkout.go +++ b/src/pkg/checkout.go @@ -69,16 +69,40 @@ type GetPolicyDetails struct { TenantId int `json:"tenantId"` PolicyID uuid.UUID `json:"policyId"` } - type GetPolicyDetailsResponse struct { Code int `json:"code"` Message string `json:"message"` - DatabaseName string `json:"database_name"` + DatabaseName string `json:"database_name"` // Consistent with CreateDatabaseCredentialRequestDto Tables []string `json:"tables"` FieldMasking map[string][]string `json:"field_masking"` - User string `json:"user"` Privilege []string `json:"privilege"` } +type PolicyAPIResponse struct { + IsValid bool `json:"isValid"` + Message string `json:"message"` + Status string `json:"status"` + Code int `json:"code"` + RequestID string `json:"requestId"` + Credential struct { + Context []string `json:"@context"` + CredentialSubject struct { + CredentialType string `json:"credentialType"` + DatabaseName string `json:"databaseName"` + FieldMasking map[string][]string `json:"fieldMasking"` + Host string `json:"host"` + ID string `json:"id"` + Password string `json:"password"` + Privilege []string `json:"privilege"` + Schema string `json:"schema"` + Tables []string `json:"tables"` + User string `json:"user"` + } `json:"credentialSubject"` + ExpirationDate string `json:"expirationDate"` + ID string `json:"id"` + IssuanceDate string `json:"issuanceDate"` + Issuer string `json:"issuer"` + } `json:"credential"` +} func PollCheckoutJob(db *sql.DB, dbName string, Config DBConfig) error { @@ -147,11 +171,16 @@ func PollCheckoutJob(db *sql.DB, dbName string, Config DBConfig) error { log.Printf("Error fetching policy details for job %s: %v", job.JobName, err) continue } + log.Printf("Policy details retrieved - Tables: %v, FieldMasking: %v, Privileges: %v", + policyDetails.Tables, policyDetails.FieldMasking, policyDetails.Privilege) + fmt.Println("Policy details:", policyDetails) fmt.Println("Job Details :", job) - success, err := GenerateCredentials(db, Config, dbName, response.DbUserName, job.Host, job.WalletUserID, job.IssuerID, job.Table_Name, job.Fields, job.Privileges, job.PolicyID) + success, err := GenerateCredentials(db, Config, dbName, response.DbUserName, job.Host, + job.WalletUserID, job.IssuerID, job.Table_Name, job.Fields, job.Privileges, + job.PolicyID, policyDetails) if err != nil { log.Printf("Error while generating credentials: %v", err) continue @@ -208,29 +237,77 @@ func FetchPolicyDetails(orgID int, tenantID int, policyID uuid.UUID) (*GetPolicy PolicyID: policyID, } - payloadBytes, _ := json.Marshal(payload) - req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes)) + payloadBytes, err := json.Marshal(payload) + if err != nil { + return nil, fmt.Errorf("failed to marshal policy request: %w", err) + } + + req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes)) + if err != nil { + return nil, fmt.Errorf("failed to create HTTP request: %w", err) + } req.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to execute HTTP request: %w", err) } defer resp.Body.Close() - body, _ := io.ReadAll(resp.Body) - var result GetPolicyDetailsResponse - if err := json.Unmarshal(body, &result); err != nil { - return nil, err + // Check HTTP status code + if resp.StatusCode != http.StatusOK { + bodyBytes, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("API returned non-OK status: %d, body: %s", resp.StatusCode, string(bodyBytes)) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %w", err) + } + + // Parse the full response + var apiResponse PolicyAPIResponse + if err := json.Unmarshal(body, &apiResponse); err != nil { + return nil, fmt.Errorf("failed to parse policy response: %w", err) } - if result.Code != 200 { - return nil, fmt.Errorf("failed to fetch policy: %s", result.Message) + + if !apiResponse.IsValid || apiResponse.Code != 200 { + return nil, fmt.Errorf("invalid policy response: %s (code: %d)", apiResponse.Message, apiResponse.Code) + } + + if apiResponse.Credential.CredentialSubject.Tables == nil { + return nil, errors.New("policy response contains no tables data") + } + + // Map to your existing response structure + result := GetPolicyDetailsResponse{ + Code: apiResponse.Code, + Message: apiResponse.Message, + DatabaseName: apiResponse.Credential.CredentialSubject.DatabaseName, + Tables: apiResponse.Credential.CredentialSubject.Tables, + FieldMasking: apiResponse.Credential.CredentialSubject.FieldMasking, + Privilege: apiResponse.Credential.CredentialSubject.Privilege, } return &result, nil } -func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName string, host string, WalletUserID int, IssuerId int, TableName string, Fields string, Privlege string, policyID uuid.UUID) (bool, error) { +func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName string, host string, + WalletUserID int, IssuerId int, TableName string, Fields string, Privlege string, + policyID uuid.UUID, policyDetails *GetPolicyDetailsResponse) (bool, error) { + + // Validate policy details + if policyDetails == nil { + return false, errors.New("policy details cannot be nil") + } + + if len(policyDetails.Tables) == 0 { + return false, errors.New("no tables found in policy details") + } + + if len(policyDetails.Privilege) == 0 { + return false, errors.New("no privileges found in policy details") + } //Rotate the Credentials for the DB User in the Database //Step1 : Generate a Random Password for the DB User password, err := GenerateRandomPassword(16) @@ -312,12 +389,6 @@ func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName orgId, _ := strconv.Atoi(Config.OrgID) tenantId, _ := strconv.Atoi(Config.TenantID) - policyDetails, err := FetchPolicyDetails(orgId, tenantId, policyID) - if err != nil { - log.Printf("Error while fetching policy details: %v", err) - return false, err - } - // Populate Tables, FieldMasking, and Privilege from the policy details tables := policyDetails.Tables fieldMasking := policyDetails.FieldMasking From 2d7dd2eaad889c796b044b317e93e38100ebdfe6 Mon Sep 17 00:00:00 2001 From: satyam1023 Date: Mon, 21 Apr 2025 17:55:52 +0530 Subject: [PATCH 4/4] unmarshalling the json and then populating --- src/pkg/checkout.go | 95 ++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 52 deletions(-) diff --git a/src/pkg/checkout.go b/src/pkg/checkout.go index 6297725..e37a12f 100644 --- a/src/pkg/checkout.go +++ b/src/pkg/checkout.go @@ -70,39 +70,42 @@ type GetPolicyDetails struct { PolicyID uuid.UUID `json:"policyId"` } type GetPolicyDetailsResponse struct { - Code int `json:"code"` - Message string `json:"message"` - DatabaseName string `json:"database_name"` // Consistent with CreateDatabaseCredentialRequestDto + Code int `json:"code"` + Status string `json:"status"` + Message string `json:"message"` + Data PolicyJSON `json:"data"` +} + +type PolicyJSON struct { + PolicyName string `json:"policyName" binding:"required"` + PolicyType string `json:"policyType" binding:"required"` + Endpoints Endpoints `json:"endpoints,omitempty"` + Domain Domain `json:"domain,omitempty"` + AD AD `json:"ad,omitempty"` + ADGroupInfra AdGroupPolicy `json:"infra,omitempty"` + Networks RadiusNetwork `json:"networks,omitempty"` + Dit Dit `json:"dit,omitempty"` + ServiceAccount ServiceAccount `json:"serviceaccount,omitempty"` + Database Database `json:"database,omitempty"` + Permissions Permission `json:"permissions"` +} + +type Database struct { + DatabaseName string `json:"database_name"` Tables []string `json:"tables"` FieldMasking map[string][]string `json:"field_masking"` + User string `json:"user"` Privilege []string `json:"privilege"` } -type PolicyAPIResponse struct { - IsValid bool `json:"isValid"` - Message string `json:"message"` - Status string `json:"status"` - Code int `json:"code"` - RequestID string `json:"requestId"` - Credential struct { - Context []string `json:"@context"` - CredentialSubject struct { - CredentialType string `json:"credentialType"` - DatabaseName string `json:"databaseName"` - FieldMasking map[string][]string `json:"fieldMasking"` - Host string `json:"host"` - ID string `json:"id"` - Password string `json:"password"` - Privilege []string `json:"privilege"` - Schema string `json:"schema"` - Tables []string `json:"tables"` - User string `json:"user"` - } `json:"credentialSubject"` - ExpirationDate string `json:"expirationDate"` - ID string `json:"id"` - IssuanceDate string `json:"issuanceDate"` - Issuer string `json:"issuer"` - } `json:"credential"` -} + +type Endpoints struct{} // Placeholder for missing struct +type Domain struct{} // Placeholder for missing struct +type AD struct{} // Placeholder for missing struct +type AdGroupPolicy struct{} // Placeholder for missing struct +type RadiusNetwork struct{} // Placeholder for missing struct +type Dit struct{} // Placeholder for missing struct +type ServiceAccount struct{} // Placeholder for missing struct +type Permission struct{} // Placeholder for missing struct func PollCheckoutJob(db *sql.DB, dbName string, Config DBConfig) error { @@ -172,7 +175,7 @@ func PollCheckoutJob(db *sql.DB, dbName string, Config DBConfig) error { continue } log.Printf("Policy details retrieved - Tables: %v, FieldMasking: %v, Privileges: %v", - policyDetails.Tables, policyDetails.FieldMasking, policyDetails.Privilege) + policyDetails.Data.Database.Tables, policyDetails.Data.Database.FieldMasking, policyDetails.Data.Database.Privilege) fmt.Println("Policy details:", policyDetails) @@ -230,7 +233,6 @@ func PollCheckoutJob(db *sql.DB, dbName string, Config DBConfig) error { func FetchPolicyDetails(orgID int, tenantID int, policyID uuid.UUID) (*GetPolicyDetailsResponse, error) { url := "https://prod.api.authnull.com/api/v1/policyService/getPolicyDetails" - // Prepare the payload payload := GetPolicyDetails{ OrgId: orgID, TenantId: tenantID, @@ -265,31 +267,21 @@ func FetchPolicyDetails(orgID int, tenantID int, policyID uuid.UUID) (*GetPolicy return nil, fmt.Errorf("failed to read response body: %w", err) } - // Parse the full response - var apiResponse PolicyAPIResponse + // Parse the response + var apiResponse GetPolicyDetailsResponse if err := json.Unmarshal(body, &apiResponse); err != nil { return nil, fmt.Errorf("failed to parse policy response: %w", err) } - if !apiResponse.IsValid || apiResponse.Code != 200 { + if apiResponse.Code != 200 { return nil, fmt.Errorf("invalid policy response: %s (code: %d)", apiResponse.Message, apiResponse.Code) } - if apiResponse.Credential.CredentialSubject.Tables == nil { + if apiResponse.Data.Database.Tables == nil { return nil, errors.New("policy response contains no tables data") } - // Map to your existing response structure - result := GetPolicyDetailsResponse{ - Code: apiResponse.Code, - Message: apiResponse.Message, - DatabaseName: apiResponse.Credential.CredentialSubject.DatabaseName, - Tables: apiResponse.Credential.CredentialSubject.Tables, - FieldMasking: apiResponse.Credential.CredentialSubject.FieldMasking, - Privilege: apiResponse.Credential.CredentialSubject.Privilege, - } - - return &result, nil + return &apiResponse, nil } func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName string, host string, @@ -301,11 +293,11 @@ func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName return false, errors.New("policy details cannot be nil") } - if len(policyDetails.Tables) == 0 { + if len(policyDetails.Data.Database.Tables) == 0 { return false, errors.New("no tables found in policy details") } - if len(policyDetails.Privilege) == 0 { + if len(policyDetails.Data.Database.Privilege) == 0 { return false, errors.New("no privileges found in policy details") } //Rotate the Credentials for the DB User in the Database @@ -389,10 +381,9 @@ func GenerateCredentials(db *sql.DB, Config DBConfig, dbName string, dbUserName orgId, _ := strconv.Atoi(Config.OrgID) tenantId, _ := strconv.Atoi(Config.TenantID) - // Populate Tables, FieldMasking, and Privilege from the policy details - tables := policyDetails.Tables - fieldMasking := policyDetails.FieldMasking - privilege := policyDetails.Privilege + tables := policyDetails.Data.Database.Tables + fieldMasking := policyDetails.Data.Database.FieldMasking + privilege := policyDetails.Data.Database.Privilege //Step3 : Call Create Database Credential API //Create the request body databaseCredentialRequest := CreateDatabaseCredentialRequestDto{