From d036a8b68ac9d75eb803d1247facd74f24607b57 Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Sun, 27 Oct 2024 12:14:09 +0300 Subject: [PATCH] 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"] +}