diff --git a/build/rofl/scheduler/domain_test.go b/build/rofl/scheduler/domain_test.go new file mode 100644 index 00000000..ac846888 --- /dev/null +++ b/build/rofl/scheduler/domain_test.go @@ -0,0 +1,65 @@ +package scheduler + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/rofl" + "github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/roflmarket" + "github.com/oasisprotocol/oasis-sdk/client-sdk/go/types" +) + +func testAppID(t *testing.T, raw string) rofl.AppID { + t.Helper() + + var appID rofl.AppID + require.NoError(t, appID.UnmarshalText([]byte(raw)), "app id must parse") + return appID +} + +func testInstance(t *testing.T, provider string, id string) *roflmarket.Instance { + t.Helper() + + var providerAddr types.Address + require.NoError(t, providerAddr.UnmarshalText([]byte(provider)), "provider address must parse") + + rawID, err := hex.DecodeString(id) + require.NoError(t, err, "instance id must parse") + require.Len(t, rawID, 8, "instance id must be 8 bytes") + + instance := &roflmarket.Instance{Provider: providerAddr} + copy(instance.ID[:], rawID) + return instance +} + +// TestDomainVerificationToken pins the derivation against a token that a live +// rofl-scheduler (v0.9.0) accepted, so any change here that breaks compatibility with +// the scheduler's Rust implementation shows up as a test failure. +func TestDomainVerificationToken(t *testing.T) { + instance := testInstance(t, "oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz", "0000000000000634") + deployedApp := testAppID(t, "rofl1qrmnjkx47f4tcfvfclnrtj2rad82akeum5jcpe8y") + + require.Equal(t, + "ofdkQl2NWpILtYBJBQC+rfQj68oyKgfkuu0PyJlKGYk=", + DomainVerificationToken(instance, deployedApp, "api.testnet.privana.finance"), + ) +} + +// TestDomainVerificationTokenBoundToDeployedApp ensures the token is bound to the app +// deployed on the machine. Deriving it from the provider's scheduler app instead +// yields a token the scheduler will never verify. +func TestDomainVerificationTokenBoundToDeployedApp(t *testing.T) { + instance := testInstance(t, "oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz", "0000000000000634") + deployedApp := testAppID(t, "rofl1qrmnjkx47f4tcfvfclnrtj2rad82akeum5jcpe8y") + schedulerApp := testAppID(t, "rofl1qrqw99h0f7az3hwt2cl7yeew3wtz0fxunu7luyfg") + + const domain = "api.testnet.privana.finance" + + require.NotEqual(t, + DomainVerificationToken(instance, deployedApp, domain), + DomainVerificationToken(instance, schedulerApp, domain), + "token must change with the app it is derived from", + ) +} diff --git a/cmd/rofl/machine/show.go b/cmd/rofl/machine/show.go index eb87f391..05e65566 100644 --- a/cmd/rofl/machine/show.go +++ b/cmd/rofl/machine/show.go @@ -128,7 +128,7 @@ func prettyPrintMachine(mCfg *machineCfg, out *machineShowOutput) { fmt.Printf("Proxy:\n") fmt.Printf(" Domain: %s\n", proxyDomain) - prettyPrintMachinePorts(mCfg.ExtraCfg, out.Replica.App, out.Machine, proxyDomain) + prettyPrintMachinePorts(mCfg.ExtraCfg, out.Machine, proxyDomain) } } @@ -209,7 +209,7 @@ func prettyPrintMachine(mCfg *machineCfg, out *machineShowOutput) { } } -func prettyPrintMachinePorts(extraCfg *roflCmdBuild.AppExtraConfig, appID rofl.AppID, insDsc *roflmarket.Instance, domain string) { +func prettyPrintMachinePorts(extraCfg *roflCmdBuild.AppExtraConfig, insDsc *roflmarket.Instance, domain string) { if extraCfg == nil || len(extraCfg.Ports) == 0 { return } @@ -223,12 +223,18 @@ func prettyPrintMachinePorts(extraCfg *roflCmdBuild.AppExtraConfig, appID rofl.A default: fmt.Printf(" %s (%s): https://%s\n", p.Port, p.ServiceName, p.CustomDomain) - domainToken := scheduler.DomainVerificationToken(insDsc, appID, p.CustomDomain) addrs, err := net.LookupHost(genericDomain) if err == nil { fmt.Printf(" * Point A record of your domain to: %s\n", addrs[0]) } - fmt.Printf(" * Add TXT record to your domain: oasis-rofl-verification=%s\n", domainToken) + + switch insDsc.Deployment { + case nil: + fmt.Printf(" * Deploy the app to obtain the TXT record for your domain\n") + default: + domainToken := scheduler.DomainVerificationToken(insDsc, insDsc.Deployment.AppID, p.CustomDomain) + fmt.Printf(" * Add TXT record to your domain: oasis-rofl-verification=%s\n", domainToken) + } } if i < len(extraCfg.Ports)-1 {