Skip to content

Commit c146220

Browse files
authored
Merge pull request #19 from threefoldtech/only-allow-deployments-of-verified-users
only allow deployments of verified users
2 parents 97a38e0 + ef7a9ed commit c146220

File tree

2 files changed

+95
-19
lines changed

2 files changed

+95
-19
lines changed

pkg/environment/environment.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type Environment struct {
4949
RelayURL []string
5050
ActivationURL string
5151
GraphQL string
52+
KycURL string
5253

5354
// private vlan to join
5455
// if set, zos will use this as its priv vlan
@@ -116,6 +117,7 @@ var (
116117
FlistURL: "redis://hub.grid.tf:9900",
117118
BinRepo: "tf-zos-v3-bins.dev",
118119
GraphQL: "https://graphql.dev.grid.tf/graphql",
120+
KycURL: "https://kyc.dev.grid.tf",
119121
}
120122

121123
envTest = Environment{
@@ -131,6 +133,7 @@ var (
131133
FlistURL: "redis://hub.grid.tf:9900",
132134
BinRepo: "tf-zos-v3-bins.test",
133135
GraphQL: "https://graphql.test.grid.tf/graphql",
136+
KycURL: "https://kyc.test.grid.tf",
134137
}
135138

136139
envQA = Environment{
@@ -146,6 +149,7 @@ var (
146149
FlistURL: "redis://hub.grid.tf:9900",
147150
BinRepo: "tf-zos-v3-bins.qanet",
148151
GraphQL: "https://graphql.qa.grid.tf/graphql",
152+
KycURL: "https://kyc.qa.grid.tf",
149153
}
150154

151155
envProd = Environment{
@@ -164,6 +168,7 @@ var (
164168
FlistURL: "redis://hub.grid.tf:9900",
165169
BinRepo: "tf-zos-v3-bins",
166170
GraphQL: "https://graphql.grid.tf/graphql",
171+
KycURL: "https://kyc.grid.tf",
167172
}
168173
)
169174

pkg/provision/engine.go

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,22 @@ package provision
33
import (
44
"context"
55
"encoding/hex"
6+
"encoding/json"
67
"fmt"
8+
"net/http"
9+
"net/url"
710
"os"
811
"path/filepath"
912
"sort"
1013
"time"
1114

15+
"github.com/cenkalti/backoff/v3"
1216
"github.com/joncrlsn/dque"
1317
"github.com/pkg/errors"
1418
"github.com/rs/zerolog/log"
1519
substrate "github.com/threefoldtech/tfchain/clients/tfchain-client-go"
1620
"github.com/threefoldtech/zos4/pkg"
21+
"github.com/threefoldtech/zos4/pkg/environment"
1722
"github.com/threefoldtech/zos4/pkg/gridtypes"
1823
"github.com/threefoldtech/zos4/pkg/gridtypes/zos"
1924
"github.com/threefoldtech/zos4/pkg/stubs"
@@ -108,21 +113,23 @@ type NativeEngine struct {
108113

109114
queue *dque.DQue
110115

111-
//options
116+
// options
112117
// janitor Janitor
113118
twins Twins
114119
admins Twins
115120
order []gridtypes.WorkloadType
116121
typeIndex map[gridtypes.WorkloadType]int
117122
rerunAll bool
118-
//substrate specific attributes
123+
// substrate specific attributes
119124
nodeID uint32
120125
substrateGateway *stubs.SubstrateGatewayStub
121126
callback Callback
122127
}
123128

124-
var _ Engine = (*NativeEngine)(nil)
125-
var _ pkg.Provision = (*NativeEngine)(nil)
129+
var (
130+
_ Engine = (*NativeEngine)(nil)
131+
_ pkg.Provision = (*NativeEngine)(nil)
132+
)
126133

127134
type withUserKeyGetter struct {
128135
g Twins
@@ -199,14 +206,19 @@ func (n *nullKeyGetter) GetKey(id uint32) ([]byte, error) {
199206
return nil, fmt.Errorf("null user key getter")
200207
}
201208

202-
type engineKey struct{}
203-
type deploymentKey struct{}
204-
type deploymentValue struct {
205-
twin uint32
206-
deployment uint64
207-
}
208-
type contractKey struct{}
209-
type rentKey struct{}
209+
type (
210+
engineKey struct{}
211+
deploymentKey struct{}
212+
deploymentValue struct {
213+
twin uint32
214+
deployment uint64
215+
}
216+
)
217+
218+
type (
219+
contractKey struct{}
220+
rentKey struct{}
221+
)
210222

211223
// GetEngine gets engine from context
212224
func GetEngine(ctx context.Context) Engine {
@@ -498,7 +510,7 @@ func (e *NativeEngine) Run(root context.Context) error {
498510
ctx, err = e.validate(ctx, &job.Target, job.Op == opProvisionNoValidation)
499511
if err != nil {
500512
l.Error().Err(err).Msg("contact validation fails")
501-
//job.Target.SetError(err)
513+
// job.Target.SetError(err)
502514
if err := e.storage.Error(job.Target.TwinID, job.Target.ContractID, err); err != nil {
503515
l.Error().Err(err).Msg("failed to set deployment global error")
504516
}
@@ -718,7 +730,7 @@ func (e *NativeEngine) installWorkload(ctx context.Context, wl *gridtypes.Worklo
718730
// if it has been deleted, error state, we do nothing.
719731
// otherwise, we-reinstall it
720732
if current.Result.State.IsAny(gridtypes.StateDeleted, gridtypes.StateError) {
721-
//nothing to do!
733+
// nothing to do!
722734
return nil
723735
}
724736
}
@@ -797,7 +809,7 @@ func (e *NativeEngine) lockWorkload(ctx context.Context, wl *gridtypes.WorkloadW
797809
return errors.Wrapf(err, "failed to get last transaction for '%s'", wl.ID.String())
798810
} else {
799811
if !current.Result.State.IsOkay() {
800-
//nothing to do! it's either in error state or something else.
812+
// nothing to do! it's either in error state or something else.
801813
return nil
802814
}
803815
}
@@ -857,7 +869,6 @@ func (e *NativeEngine) uninstallDeployment(ctx context.Context, dl *gridtypes.De
857869
Uint64("contract", dl.ContractID).
858870
Msg("failed to delete deployment")
859871
}
860-
861872
}
862873

863874
func getMountSize(wl *gridtypes.Workload) (gridtypes.Unit, error) {
@@ -985,11 +996,11 @@ func (e *NativeEngine) DecommissionCached(id string, reason string) error {
985996

986997
if wl.Result.State == gridtypes.StateDeleted ||
987998
wl.Result.State == gridtypes.StateError {
988-
//nothing to do!
999+
// nothing to do!
9891000
return nil
9901001
}
9911002

992-
//to bad we have to repeat this here
1003+
// to bad we have to repeat this here
9931004
ctx := context.WithValue(context.Background(), engineKey{}, e)
9941005
ctx = withDeployment(ctx, twin, dlID)
9951006

@@ -1012,6 +1023,20 @@ func (n *NativeEngine) CreateOrUpdate(twin uint32, deployment gridtypes.Deployme
10121023
return fmt.Errorf("twin id mismatch (deployment: %d, message: %d)", deployment.TwinID, twin)
10131024
}
10141025

1026+
// make sure the account used is verified
1027+
check := func() error {
1028+
if ok, err := isTwinVerified(twin); err != nil {
1029+
return err
1030+
} else if !ok {
1031+
return fmt.Errorf("user with twin id %d is not verified", twin)
1032+
}
1033+
return nil
1034+
}
1035+
1036+
if err := backoff.Retry(check, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 5)); err != nil {
1037+
return err
1038+
}
1039+
10151040
if err := deployment.Verify(n.twins); err != nil {
10161041
return err
10171042
}
@@ -1028,7 +1053,6 @@ func (n *NativeEngine) CreateOrUpdate(twin uint32, deployment gridtypes.Deployme
10281053
}
10291054

10301055
return action(ctx, deployment)
1031-
10321056
}
10331057

10341058
func (n *NativeEngine) Get(twin uint32, contractID uint64) (gridtypes.Deployment, error) {
@@ -1041,6 +1065,7 @@ func (n *NativeEngine) Get(twin uint32, contractID uint64) (gridtypes.Deployment
10411065

10421066
return deployment, nil
10431067
}
1068+
10441069
func (n *NativeEngine) List(twin uint32) ([]gridtypes.Deployment, error) {
10451070
deploymentIDs, err := n.storage.ByTwin(twin)
10461071
if err != nil {
@@ -1059,6 +1084,7 @@ func (n *NativeEngine) List(twin uint32) ([]gridtypes.Deployment, error) {
10591084
}
10601085
return deployments, nil
10611086
}
1087+
10621088
func (n *NativeEngine) Changes(twin uint32, contractID uint64) ([]gridtypes.Workload, error) {
10631089
changes, err := n.storage.Changes(twin, contractID)
10641090
if errors.Is(err, ErrDeploymentNotExists) {
@@ -1068,6 +1094,7 @@ func (n *NativeEngine) Changes(twin uint32, contractID uint64) ([]gridtypes.Work
10681094
}
10691095
return changes, nil
10701096
}
1097+
10711098
func (n *NativeEngine) ListPublicIPs() ([]string, error) {
10721099
// for efficiency this method should just find out configured public Ips.
10731100
// but currently the only way to do this is by scanning the nft rules
@@ -1110,6 +1137,7 @@ func (n *NativeEngine) ListPublicIPs() ([]string, error) {
11101137

11111138
return ips, nil
11121139
}
1140+
11131141
func (n *NativeEngine) ListPrivateIPs(twin uint32, network gridtypes.Name) ([]string, error) {
11141142
deployments, err := n.List(twin)
11151143
if err != nil {
@@ -1162,3 +1190,46 @@ func (e *NativeEngine) GetWorkloadStatus(id string) (gridtypes.ResultState, bool
11621190

11631191
return wl.Result.State, true, nil
11641192
}
1193+
1194+
// isTwinVerified make sure the account used is verified
1195+
func isTwinVerified(twinID uint32) (verified bool, err error) {
1196+
const verifiedStatus = "VERIFIED"
1197+
env := environment.MustGet()
1198+
1199+
verificationServiceURL, err := url.JoinPath(env.KycURL, "/api/v1/status")
1200+
if err != nil {
1201+
return
1202+
}
1203+
1204+
request, err := http.NewRequest(http.MethodGet, verificationServiceURL, nil)
1205+
if err != nil {
1206+
return
1207+
}
1208+
1209+
q := request.URL.Query()
1210+
q.Set("twin_id", fmt.Sprint(twinID))
1211+
request.URL.RawQuery = q.Encode()
1212+
1213+
cl := &http.Client{
1214+
Timeout: 10 * time.Second,
1215+
}
1216+
1217+
response, err := cl.Do(request)
1218+
if err != nil {
1219+
return
1220+
}
1221+
defer response.Body.Close()
1222+
1223+
if response.StatusCode != http.StatusOK {
1224+
return verified, errors.New("failed to get twin verification status")
1225+
}
1226+
1227+
var result struct{ Result struct{ Status string } }
1228+
1229+
err = json.NewDecoder(response.Body).Decode(&result)
1230+
if err != nil {
1231+
return
1232+
}
1233+
1234+
return result.Result.Status == verifiedStatus, nil
1235+
}

0 commit comments

Comments
 (0)