From 3871fdcdd4b4c121829ee8d27b0af6e22691b96b Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Thu, 24 Oct 2024 14:58:04 +0300 Subject: [PATCH 1/8] only allow deployments of verified users --- pkg/gridtypes/deployment.go | 64 +++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/pkg/gridtypes/deployment.go b/pkg/gridtypes/deployment.go index 71d10ef12..a9e1921ed 100644 --- a/pkg/gridtypes/deployment.go +++ b/pkg/gridtypes/deployment.go @@ -5,8 +5,11 @@ import ( "crypto/ed25519" "crypto/md5" "encoding/hex" + "encoding/json" "fmt" "io" + "net/http" + "time" sr25519 "github.com/ChainSafe/go-schnorrkel" "github.com/gtank/merlin" @@ -14,10 +17,8 @@ import ( "github.com/rs/zerolog/log" ) -var ( - // ErrWorkloadNotFound error - ErrWorkloadNotFound = fmt.Errorf("workload not found") -) +// ErrWorkloadNotFound error +var ErrWorkloadNotFound = fmt.Errorf("workload not found") const ( SignatureTypeEd25519 = "ed25519" @@ -32,8 +33,10 @@ type Verifier interface { Verify(msg []byte, sig []byte) bool } -type Ed25519VerifyingKey []byte -type Sr25519VerifyingKey []byte +type ( + Ed25519VerifyingKey []byte + Sr25519VerifyingKey []byte +) func (k Ed25519VerifyingKey) Verify(msg []byte, sig []byte) bool { return ed25519.Verify([]byte(k), msg, sig) @@ -385,6 +388,11 @@ func (d *Deployment) Sign(twin uint32, sk Signer) error { // Verify verifies user signatures is mainly used by the node // to verify that all attached signatures are valid. func (d *Deployment) Verify(getter KeyGetter) error { + // make sure the account used is verified + if getTwinVerificationState(d.TwinID) != "VERIFIED" { + return fmt.Errorf("user is not verified") + } + message, err := d.ChallengeHash() if err != nil { return err @@ -617,7 +625,6 @@ func (d *Deployment) Upgrade(n *Deployment) ([]UpgradeOp, error) { wl, OpUpdate, }) - } // other wise. we leave it untouched } @@ -665,3 +672,46 @@ func (o JobOperation) String() string { return "unknown" } } + +// getTwinVerificationState make sure the account used is verified we have the user public key in bytes(pkBytes) +func getTwinVerificationState(twinID uint32) (status string) { + verificationServiceURL := "https://kyc1.gent01.dev.grid.tf/api/v1/status" + status = "FAILED" + + request, err := http.NewRequest(http.MethodGet, verificationServiceURL, nil) + if err != nil { + return + } + + q := request.URL.Query() + q.Set("twinID", fmt.Sprint(twinID)) + request.URL.RawQuery = q.Encode() + + cl := &http.Client{ + Timeout: 10 * time.Second, + } + + response, err := cl.Do(request) + if err != nil { + return + } + defer response.Body.Close() + + body, err := io.ReadAll(response.Body) + if err != nil { + return + } + + bodyMap := map[string]string{} + err = json.Unmarshal(body, &bodyMap) + if err != nil { + return + } + + if response.StatusCode != http.StatusOK { + log.Error().Msgf("failed to verify user status: %s", bodyMap["error"]) + return + } + + return bodyMap["status"] +} From d036a8b68ac9d75eb803d1247facd74f24607b57 Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Sun, 27 Oct 2024 12:14:09 +0300 Subject: [PATCH 2/8] use kyc url retrieved from stack information --- pkg/environment/environment.go | 5 ++ pkg/gridtypes/deployment.go | 64 +++---------------- pkg/provision/engine.go | 108 +++++++++++++++++++++++++++------ 3 files changed, 101 insertions(+), 76 deletions(-) diff --git a/pkg/environment/environment.go b/pkg/environment/environment.go index 50fca3f6f..9a2c086d8 100644 --- a/pkg/environment/environment.go +++ b/pkg/environment/environment.go @@ -50,6 +50,7 @@ type Environment struct { RelayURL []string ActivationURL []string GraphQL []string + KycURL string // private vlan to join // if set, zos will use this as its priv vlan @@ -124,6 +125,7 @@ var ( "https://graphql.dev.grid.tf/graphql", "https://graphql.02.dev.grid.tf/graphql", }, + KycURL: "https://kyc1.gent01.dev.grid.tf", } envTest = Environment{ @@ -146,6 +148,7 @@ var ( "https://graphql.test.grid.tf/graphql", "https://graphql.02.test.grid.tf/graphql", }, + KycURL: "", } envQA = Environment{ @@ -168,6 +171,7 @@ var ( "https://graphql.qa.grid.tf/graphql", "https://graphql.02.qa.grid.tf/graphql", }, + KycURL: "", } envProd = Environment{ @@ -193,6 +197,7 @@ var ( "https://graphql.grid.tf/graphql", "https://graphql.02.grid.tf/graphql", }, + KycURL: "", } ) diff --git a/pkg/gridtypes/deployment.go b/pkg/gridtypes/deployment.go index a9e1921ed..71d10ef12 100644 --- a/pkg/gridtypes/deployment.go +++ b/pkg/gridtypes/deployment.go @@ -5,11 +5,8 @@ import ( "crypto/ed25519" "crypto/md5" "encoding/hex" - "encoding/json" "fmt" "io" - "net/http" - "time" sr25519 "github.com/ChainSafe/go-schnorrkel" "github.com/gtank/merlin" @@ -17,8 +14,10 @@ import ( "github.com/rs/zerolog/log" ) -// ErrWorkloadNotFound error -var ErrWorkloadNotFound = fmt.Errorf("workload not found") +var ( + // ErrWorkloadNotFound error + ErrWorkloadNotFound = fmt.Errorf("workload not found") +) const ( SignatureTypeEd25519 = "ed25519" @@ -33,10 +32,8 @@ type Verifier interface { Verify(msg []byte, sig []byte) bool } -type ( - Ed25519VerifyingKey []byte - Sr25519VerifyingKey []byte -) +type Ed25519VerifyingKey []byte +type Sr25519VerifyingKey []byte func (k Ed25519VerifyingKey) Verify(msg []byte, sig []byte) bool { return ed25519.Verify([]byte(k), msg, sig) @@ -388,11 +385,6 @@ func (d *Deployment) Sign(twin uint32, sk Signer) error { // Verify verifies user signatures is mainly used by the node // to verify that all attached signatures are valid. func (d *Deployment) Verify(getter KeyGetter) error { - // make sure the account used is verified - if getTwinVerificationState(d.TwinID) != "VERIFIED" { - return fmt.Errorf("user is not verified") - } - message, err := d.ChallengeHash() if err != nil { return err @@ -625,6 +617,7 @@ func (d *Deployment) Upgrade(n *Deployment) ([]UpgradeOp, error) { wl, OpUpdate, }) + } // other wise. we leave it untouched } @@ -672,46 +665,3 @@ func (o JobOperation) String() string { return "unknown" } } - -// getTwinVerificationState make sure the account used is verified we have the user public key in bytes(pkBytes) -func getTwinVerificationState(twinID uint32) (status string) { - verificationServiceURL := "https://kyc1.gent01.dev.grid.tf/api/v1/status" - status = "FAILED" - - request, err := http.NewRequest(http.MethodGet, verificationServiceURL, nil) - if err != nil { - return - } - - q := request.URL.Query() - q.Set("twinID", fmt.Sprint(twinID)) - request.URL.RawQuery = q.Encode() - - cl := &http.Client{ - Timeout: 10 * time.Second, - } - - response, err := cl.Do(request) - if err != nil { - return - } - defer response.Body.Close() - - body, err := io.ReadAll(response.Body) - if err != nil { - return - } - - bodyMap := map[string]string{} - err = json.Unmarshal(body, &bodyMap) - if err != nil { - return - } - - if response.StatusCode != http.StatusOK { - log.Error().Msgf("failed to verify user status: %s", bodyMap["error"]) - return - } - - return bodyMap["status"] -} diff --git a/pkg/provision/engine.go b/pkg/provision/engine.go index 42a4a2d36..cdfbced9b 100644 --- a/pkg/provision/engine.go +++ b/pkg/provision/engine.go @@ -3,7 +3,11 @@ package provision import ( "context" "encoding/hex" + "encoding/json" "fmt" + "io" + "net/http" + "net/url" "os" "path/filepath" "sort" @@ -14,6 +18,7 @@ import ( "github.com/rs/zerolog/log" substrate "github.com/threefoldtech/tfchain/clients/tfchain-client-go" "github.com/threefoldtech/zos/pkg" + "github.com/threefoldtech/zos/pkg/environment" "github.com/threefoldtech/zos/pkg/gridtypes" "github.com/threefoldtech/zos/pkg/gridtypes/zos" "github.com/threefoldtech/zos/pkg/stubs" @@ -108,21 +113,23 @@ type NativeEngine struct { queue *dque.DQue - //options + // options // janitor Janitor twins Twins admins Twins order []gridtypes.WorkloadType typeIndex map[gridtypes.WorkloadType]int rerunAll bool - //substrate specific attributes + // substrate specific attributes nodeID uint32 substrateGateway *stubs.SubstrateGatewayStub callback Callback } -var _ Engine = (*NativeEngine)(nil) -var _ pkg.Provision = (*NativeEngine)(nil) +var ( + _ Engine = (*NativeEngine)(nil) + _ pkg.Provision = (*NativeEngine)(nil) +) type withUserKeyGetter struct { g Twins @@ -199,14 +206,19 @@ func (n *nullKeyGetter) GetKey(id uint32) ([]byte, error) { return nil, fmt.Errorf("null user key getter") } -type engineKey struct{} -type deploymentKey struct{} -type deploymentValue struct { - twin uint32 - deployment uint64 -} -type contractKey struct{} -type rentKey struct{} +type ( + engineKey struct{} + deploymentKey struct{} + deploymentValue struct { + twin uint32 + deployment uint64 + } +) + +type ( + contractKey struct{} + rentKey struct{} +) // GetEngine gets engine from context func GetEngine(ctx context.Context) Engine { @@ -498,7 +510,7 @@ func (e *NativeEngine) Run(root context.Context) error { ctx, err = e.validate(ctx, &job.Target, job.Op == opProvisionNoValidation) if err != nil { l.Error().Err(err).Msg("contact validation fails") - //job.Target.SetError(err) + // job.Target.SetError(err) if err := e.storage.Error(job.Target.TwinID, job.Target.ContractID, err); err != nil { l.Error().Err(err).Msg("failed to set deployment global error") } @@ -718,7 +730,7 @@ func (e *NativeEngine) installWorkload(ctx context.Context, wl *gridtypes.Worklo // if it has been deleted, error state, we do nothing. // otherwise, we-reinstall it if current.Result.State.IsAny(gridtypes.StateDeleted, gridtypes.StateError) { - //nothing to do! + // nothing to do! return nil } } @@ -797,7 +809,7 @@ func (e *NativeEngine) lockWorkload(ctx context.Context, wl *gridtypes.WorkloadW return errors.Wrapf(err, "failed to get last transaction for '%s'", wl.ID.String()) } else { if !current.Result.State.IsOkay() { - //nothing to do! it's either in error state or something else. + // nothing to do! it's either in error state or something else. return nil } } @@ -857,7 +869,6 @@ func (e *NativeEngine) uninstallDeployment(ctx context.Context, dl *gridtypes.De Uint64("contract", dl.ContractID). Msg("failed to delete deployment") } - } func getMountSize(wl *gridtypes.Workload) (gridtypes.Unit, error) { @@ -985,11 +996,11 @@ func (e *NativeEngine) DecommissionCached(id string, reason string) error { if wl.Result.State == gridtypes.StateDeleted || wl.Result.State == gridtypes.StateError { - //nothing to do! + // nothing to do! return nil } - //to bad we have to repeat this here + // to bad we have to repeat this here ctx := context.WithValue(context.Background(), engineKey{}, e) ctx = withDeployment(ctx, twin, dlID) @@ -1012,6 +1023,11 @@ func (n *NativeEngine) CreateOrUpdate(twin uint32, deployment gridtypes.Deployme return fmt.Errorf("twin id mismatch (deployment: %d, message: %d)", deployment.TwinID, twin) } + // make sure the account used is verified + if getTwinVerificationState(twin) != "VERIFIED" { + return fmt.Errorf("user is not verified") + } + if err := deployment.Verify(n.twins); err != nil { return err } @@ -1028,7 +1044,6 @@ func (n *NativeEngine) CreateOrUpdate(twin uint32, deployment gridtypes.Deployme } return action(ctx, deployment) - } func (n *NativeEngine) Get(twin uint32, contractID uint64) (gridtypes.Deployment, error) { @@ -1041,6 +1056,7 @@ func (n *NativeEngine) Get(twin uint32, contractID uint64) (gridtypes.Deployment return deployment, nil } + func (n *NativeEngine) List(twin uint32) ([]gridtypes.Deployment, error) { deploymentIDs, err := n.storage.ByTwin(twin) if err != nil { @@ -1059,6 +1075,7 @@ func (n *NativeEngine) List(twin uint32) ([]gridtypes.Deployment, error) { } return deployments, nil } + func (n *NativeEngine) Changes(twin uint32, contractID uint64) ([]gridtypes.Workload, error) { changes, err := n.storage.Changes(twin, contractID) if errors.Is(err, ErrDeploymentNotExists) { @@ -1068,6 +1085,7 @@ func (n *NativeEngine) Changes(twin uint32, contractID uint64) ([]gridtypes.Work } return changes, nil } + func (n *NativeEngine) ListPublicIPs() ([]string, error) { // for efficiency this method should just find out configured public Ips. // but currently the only way to do this is by scanning the nft rules @@ -1110,6 +1128,7 @@ func (n *NativeEngine) ListPublicIPs() ([]string, error) { return ips, nil } + func (n *NativeEngine) ListPrivateIPs(twin uint32, network gridtypes.Name) ([]string, error) { deployments, err := n.List(twin) if err != nil { @@ -1162,3 +1181,54 @@ func (e *NativeEngine) GetWorkloadStatus(id string) (gridtypes.ResultState, bool return wl.Result.State, true, nil } + +// getTwinVerificationState make sure the account used is verified we have the user public key in bytes(pkBytes) +func getTwinVerificationState(twinID uint32) (status string) { + status = "FAILED" + env, err := environment.Get() + if err != nil { + return + } + + verificationServiceURL, err := url.JoinPath(env.KycURL, "/api/v1/status") + if err != nil { + return + } + + request, err := http.NewRequest(http.MethodGet, verificationServiceURL, nil) + if err != nil { + return + } + + q := request.URL.Query() + q.Set("twin_id", fmt.Sprint(twinID)) + request.URL.RawQuery = q.Encode() + + cl := &http.Client{ + Timeout: 10 * time.Second, + } + + response, err := cl.Do(request) + if err != nil { + return + } + defer response.Body.Close() + + body, err := io.ReadAll(response.Body) + if err != nil { + return + } + + bodyMap := map[string]string{} + err = json.Unmarshal(body, &bodyMap) + if err != nil { + return + } + + if response.StatusCode != http.StatusOK { + log.Error().Msgf("failed to verify user status: %s", bodyMap["error"]) + return + } + + return bodyMap["status"] +} From d14cc3ae10dfb1c4dade667cfc0bbb6bec1778c8 Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Sun, 27 Oct 2024 13:51:22 +0300 Subject: [PATCH 3/8] fix response struct --- pkg/environment/environment.go | 4 ++-- pkg/provision/engine.go | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/pkg/environment/environment.go b/pkg/environment/environment.go index 9a2c086d8..eaa545079 100644 --- a/pkg/environment/environment.go +++ b/pkg/environment/environment.go @@ -125,7 +125,7 @@ var ( "https://graphql.dev.grid.tf/graphql", "https://graphql.02.dev.grid.tf/graphql", }, - KycURL: "https://kyc1.gent01.dev.grid.tf", + KycURL: "", } envTest = Environment{ @@ -197,7 +197,7 @@ var ( "https://graphql.grid.tf/graphql", "https://graphql.02.grid.tf/graphql", }, - KycURL: "", + KycURL: "https://kyc1.gent01.dev.grid.tf", } ) diff --git a/pkg/provision/engine.go b/pkg/provision/engine.go index cdfbced9b..42acfaa0c 100644 --- a/pkg/provision/engine.go +++ b/pkg/provision/engine.go @@ -1185,10 +1185,7 @@ func (e *NativeEngine) GetWorkloadStatus(id string) (gridtypes.ResultState, bool // getTwinVerificationState make sure the account used is verified we have the user public key in bytes(pkBytes) func getTwinVerificationState(twinID uint32) (status string) { status = "FAILED" - env, err := environment.Get() - if err != nil { - return - } + env := environment.MustGet() verificationServiceURL, err := url.JoinPath(env.KycURL, "/api/v1/status") if err != nil { @@ -1219,16 +1216,22 @@ func getTwinVerificationState(twinID uint32) (status string) { return } - bodyMap := map[string]string{} - err = json.Unmarshal(body, &bodyMap) + var result struct { + Result struct { + Status string `json:"status"` + } `json:"result"` + Error string `json:"error"` + } + + err = json.Unmarshal(body, &result) if err != nil { return } if response.StatusCode != http.StatusOK { - log.Error().Msgf("failed to verify user status: %s", bodyMap["error"]) + log.Error().Msgf("failed to verify user status: %s", result.Error) return } - return bodyMap["status"] + return result.Result.Status } From 591810ad780e0056d4fecf4fbf33c96a3c23bc17 Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Sun, 27 Oct 2024 14:39:51 +0300 Subject: [PATCH 4/8] skip verification check if no kyc url exisits --- pkg/provision/engine.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/provision/engine.go b/pkg/provision/engine.go index 42acfaa0c..7a8f484ac 100644 --- a/pkg/provision/engine.go +++ b/pkg/provision/engine.go @@ -1192,6 +1192,10 @@ func getTwinVerificationState(twinID uint32) (status string) { return } + if len(verificationServiceURL) == 0 { + return "VERIFIED" + } + request, err := http.NewRequest(http.MethodGet, verificationServiceURL, nil) if err != nil { return From bb430a7a241904a7c5090260e3b37cb57eae8eb6 Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Wed, 30 Oct 2024 13:05:39 +0300 Subject: [PATCH 5/8] add all supported kyc instances --- pkg/environment/environment.go | 8 ++++---- pkg/provision/engine.go | 10 +++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/pkg/environment/environment.go b/pkg/environment/environment.go index eaa545079..9fc7de8cb 100644 --- a/pkg/environment/environment.go +++ b/pkg/environment/environment.go @@ -125,7 +125,7 @@ var ( "https://graphql.dev.grid.tf/graphql", "https://graphql.02.dev.grid.tf/graphql", }, - KycURL: "", + KycURL: "https://kyc.dev.grid.tf", } envTest = Environment{ @@ -148,7 +148,7 @@ var ( "https://graphql.test.grid.tf/graphql", "https://graphql.02.test.grid.tf/graphql", }, - KycURL: "", + KycURL: "https://kyc.test.grid.tf", } envQA = Environment{ @@ -171,7 +171,7 @@ var ( "https://graphql.qa.grid.tf/graphql", "https://graphql.02.qa.grid.tf/graphql", }, - KycURL: "", + KycURL: "https://kyc.qa.grid.tf", } envProd = Environment{ @@ -197,7 +197,7 @@ var ( "https://graphql.grid.tf/graphql", "https://graphql.02.grid.tf/graphql", }, - KycURL: "https://kyc1.gent01.dev.grid.tf", + KycURL: "https://kyc.grid.tf", } ) diff --git a/pkg/provision/engine.go b/pkg/provision/engine.go index 7a8f484ac..3243b51aa 100644 --- a/pkg/provision/engine.go +++ b/pkg/provision/engine.go @@ -1024,7 +1024,7 @@ func (n *NativeEngine) CreateOrUpdate(twin uint32, deployment gridtypes.Deployme } // make sure the account used is verified - if getTwinVerificationState(twin) != "VERIFIED" { + if getTwinVerificationStatus(twin) != "VERIFIED" { return fmt.Errorf("user is not verified") } @@ -1182,8 +1182,8 @@ func (e *NativeEngine) GetWorkloadStatus(id string) (gridtypes.ResultState, bool return wl.Result.State, true, nil } -// getTwinVerificationState make sure the account used is verified we have the user public key in bytes(pkBytes) -func getTwinVerificationState(twinID uint32) (status string) { +// getTwinVerificationStatus make sure the account used is verified we have the user public key in bytes(pkBytes) +func getTwinVerificationStatus(twinID uint32) (status string) { status = "FAILED" env := environment.MustGet() @@ -1192,10 +1192,6 @@ func getTwinVerificationState(twinID uint32) (status string) { return } - if len(verificationServiceURL) == 0 { - return "VERIFIED" - } - request, err := http.NewRequest(http.MethodGet, verificationServiceURL, nil) if err != nil { return From 14c974766e349fa5c19f90f88dafd5d4f457e45c Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Wed, 30 Oct 2024 13:19:55 +0300 Subject: [PATCH 6/8] retry to verify twin before failing the deployments --- pkg/provision/engine.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/provision/engine.go b/pkg/provision/engine.go index 3243b51aa..49d977017 100644 --- a/pkg/provision/engine.go +++ b/pkg/provision/engine.go @@ -13,6 +13,7 @@ import ( "sort" "time" + "github.com/cenkalti/backoff/v3" "github.com/joncrlsn/dque" "github.com/pkg/errors" "github.com/rs/zerolog/log" @@ -1024,8 +1025,15 @@ func (n *NativeEngine) CreateOrUpdate(twin uint32, deployment gridtypes.Deployme } // make sure the account used is verified - if getTwinVerificationStatus(twin) != "VERIFIED" { - return fmt.Errorf("user is not verified") + check := func() error { + if getTwinVerificationStatus(twin) != "VERIFIED" { + return fmt.Errorf("user is not verified") + } + return nil + } + + if err := backoff.Retry(check, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 5)); err != nil { + return err } if err := deployment.Verify(n.twins); err != nil { From 33fa7e3396eeccedc391cd5842dc16dfe3fa293d Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Wed, 30 Oct 2024 13:50:27 +0300 Subject: [PATCH 7/8] update verifiction function to return bool representing verification status --- pkg/provision/engine.go | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/pkg/provision/engine.go b/pkg/provision/engine.go index 49d977017..fe13cbebb 100644 --- a/pkg/provision/engine.go +++ b/pkg/provision/engine.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "encoding/json" "fmt" - "io" "net/http" "net/url" "os" @@ -1026,7 +1025,7 @@ func (n *NativeEngine) CreateOrUpdate(twin uint32, deployment gridtypes.Deployme // make sure the account used is verified check := func() error { - if getTwinVerificationStatus(twin) != "VERIFIED" { + if !isTwinVerified(twin) { return fmt.Errorf("user is not verified") } return nil @@ -1190,9 +1189,9 @@ func (e *NativeEngine) GetWorkloadStatus(id string) (gridtypes.ResultState, bool return wl.Result.State, true, nil } -// getTwinVerificationStatus make sure the account used is verified we have the user public key in bytes(pkBytes) -func getTwinVerificationStatus(twinID uint32) (status string) { - status = "FAILED" +// isTwinVerified make sure the account used is verified +func isTwinVerified(twinID uint32) (verified bool) { + const verifiedStatus = "VERIFIED" env := environment.MustGet() verificationServiceURL, err := url.JoinPath(env.KycURL, "/api/v1/status") @@ -1219,27 +1218,17 @@ func getTwinVerificationStatus(twinID uint32) (status string) { } defer response.Body.Close() - body, err := io.ReadAll(response.Body) - if err != nil { + if response.StatusCode != http.StatusOK { + log.Error().Msg("failed to get user status") return } - var result struct { - Result struct { - Status string `json:"status"` - } `json:"result"` - Error string `json:"error"` - } + var result struct{ Result struct{ Status string } } - err = json.Unmarshal(body, &result) + err = json.NewDecoder(response.Body).Decode(&result) if err != nil { return } - if response.StatusCode != http.StatusOK { - log.Error().Msgf("failed to verify user status: %s", result.Error) - return - } - - return result.Result.Status + return result.Result.Status == verifiedStatus } From 9ce51912ffeb984546dd9794dc9d5283c7253b4a Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Wed, 30 Oct 2024 16:18:27 +0300 Subject: [PATCH 8/8] return error from isTwinVerified --- pkg/provision/engine.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pkg/provision/engine.go b/pkg/provision/engine.go index fe13cbebb..9842b5307 100644 --- a/pkg/provision/engine.go +++ b/pkg/provision/engine.go @@ -1025,8 +1025,10 @@ func (n *NativeEngine) CreateOrUpdate(twin uint32, deployment gridtypes.Deployme // make sure the account used is verified check := func() error { - if !isTwinVerified(twin) { - return fmt.Errorf("user is not verified") + if ok, err := isTwinVerified(twin); err != nil { + return err + } else if !ok { + return fmt.Errorf("user with twin id %d is not verified", twin) } return nil } @@ -1190,7 +1192,7 @@ func (e *NativeEngine) GetWorkloadStatus(id string) (gridtypes.ResultState, bool } // isTwinVerified make sure the account used is verified -func isTwinVerified(twinID uint32) (verified bool) { +func isTwinVerified(twinID uint32) (verified bool, err error) { const verifiedStatus = "VERIFIED" env := environment.MustGet() @@ -1219,8 +1221,7 @@ func isTwinVerified(twinID uint32) (verified bool) { defer response.Body.Close() if response.StatusCode != http.StatusOK { - log.Error().Msg("failed to get user status") - return + return verified, errors.New("failed to get twin verification status") } var result struct{ Result struct{ Status string } } @@ -1230,5 +1231,5 @@ func isTwinVerified(twinID uint32) (verified bool) { return } - return result.Result.Status == verifiedStatus + return result.Result.Status == verifiedStatus, nil }