Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

now only ever publishes 1 initialized event #58

Merged
merged 2 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/globalservice/event_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ func handleEventPut(srv *GlobalService) func(m *nats.Msg) {
}
}

// NOTE: this is safe to publish now because we're no longer writing multiple initialized events
func (srv *GlobalService) publishSynadiaHubAutoShare(targetKey string) error {
slog.Info("Detected Natster initialized event, auto-sharing synadia hub.")
subject := fmt.Sprintf("natster.events.%s.%s.synadiahub.%s",
Expand Down
20 changes: 19 additions & 1 deletion internal/globalservice/whoami.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package globalservice
import (
"context"
"log/slog"
"time"

"github.com/nats-io/nats.go"
"github.com/nats-io/nats.go/jetstream"
"github.com/nats-io/nkeys"
"github.com/synadia-io/control-plane-sdk-go/syncp"
"github.com/synadia-labs/natster/internal/models"
Expand All @@ -16,15 +18,31 @@ func handleWhoAmi(srv *GlobalService) func(m *nats.Msg) {
oauth, err := srv.GetOAuthIdForAccount(accountKey)
if err != nil {
slog.Error("Failed to query OAuth ID for account", err)
_ = m.Respond(models.NewApiResultFail("Not Found", 404))
_ = m.Respond(models.NewApiResultFail("Internal server error", 500))
return
}
js, _ := jetstream.New(srv.nc)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

kv, err := js.KeyValue(ctx, accountProjectionBucketName)
if err != nil {
slog.Error("Failed to get key value store", slog.Any("error", err))
_ = m.Respond(models.NewApiResultFail("Internal server error", 500))
return
}
initialized := int64(0)
act, err := loadAccount(kv, accountKey)
if err == nil {
initialized = act.InitializedAt
}
// Note: a non-error but nil oauth is valid - just means it hasn't been context
// bound yet

resp := models.WhoamiResponse{
AccountKey: accountKey,
OAuthIdentity: oauth,
Initialized: initialized,
}
_ = m.Respond(models.NewApiResultPass(resp))
}
Expand Down
1 change: 1 addition & 0 deletions internal/models/global_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type CatalogShareSummary struct {
type WhoamiResponse struct {
AccountKey string `json:"account_key"`
OAuthIdentity *string `json:"oauth_id,omitempty"`
Initialized int64 `json:"initialized"`
}

type ContextQueryResponse struct {
Expand Down
5 changes: 5 additions & 0 deletions natster/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ func ShareCatalog(ctx *fisk.ParseContext) error {
if err != nil {
return err
}
if nctx.AccountPublicKey == ShareOpts.AccountKey {
fmt.Println("You cannot share catalogs with yourself.")
return nil
}

client, err := globalservice.NewClientWithCredsPath(nctx.CredsPath)
if err != nil {
slog.Error(
Expand Down
13 changes: 11 additions & 2 deletions natster/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path"
"time"

"github.com/choria-io/fisk"
"github.com/jedib0t/go-pretty/v6/table"
Expand All @@ -23,15 +24,23 @@ func DisplayContext(ctx *fisk.ParseContext) error {
}

idString := "(unlinked)"
initializedOn := "(never)"
whoami, _ := client.Whoami()

if whoami != nil && whoami.OAuthIdentity != nil {
idString = *whoami.OAuthIdentity
if whoami != nil {
if whoami.OAuthIdentity != nil {
idString = *whoami.OAuthIdentity
}
if whoami.Initialized > 0 {
t := time.Unix(whoami.Initialized, 0)
initializedOn = t.Format("2006-01-02 15:04:05")
}
}

t := newTableWriter(ctxx.AccountName, "cyan")
w := t.writer
w.AppendRow(table.Row{"Account", ctxx.AccountPublicKey})
w.AppendRow(table.Row{"Initialized At", initializedOn})
w.AppendRow(table.Row{"Synadia Cloud Team", ctxx.TeamID})
w.AppendRow(table.Row{"Synadia Cloud System", ctxx.SystemID})
w.AppendRow(table.Row{"Synadia Cloud User", ctxx.UserID})
Expand Down
29 changes: 20 additions & 9 deletions natster/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"os"
"path"
"time"

"github.com/AlecAivazis/survey/v2"
"github.com/choria-io/fisk"
Expand Down Expand Up @@ -185,19 +186,29 @@ func InitNatster(ctx *fisk.ParseContext) error {
return err
}
globalClient := globalservice.NewClient(conn)
data, _ := json.Marshal(models.NatsterInitializedEvent{
AccountId: newCtx.AccountID,
AccountName: newCtx.AccountName,
AccountKey: newCtx.AccountPublicKey,
})
err = globalClient.PublishEvent(models.NatsterInitializedEventType, "none", "none", data)
whoami, err := globalClient.Whoami()
if err != nil {
fmt.Printf("Failed to contact Natster global service to post initialization event: %s", err)
return err
fmt.Println("There was a problem querying the global service. You may need to re-run `init`")
} else {
if whoami.Initialized == 0 {
data, _ := json.Marshal(models.NatsterInitializedEvent{
AccountId: newCtx.AccountID,
AccountName: newCtx.AccountName,
AccountKey: newCtx.AccountPublicKey,
})
err = globalClient.PublishEvent(models.NatsterInitializedEventType, "none", "none", data)
if err != nil {
fmt.Printf("Failed to contact Natster global service to post initialization event: %s", err)
return err
}
} else {
t := time.Unix(whoami.Initialized, 0)
fmt.Printf("Note: this account was previously initialized on %s\n", t.Format("2006-01-02 15:04:05"))
}
}

fmt.Printf("Congratulations! Your account (%s) is ready to serve Natster catalogs!\n", accountName)
fmt.Println("You can now use `natster catalog serve` to host a media catalog and `natster catalog share` to share with friends.")
fmt.Println("To get started, you'll want to do the following:\n1. `natster catalog new` to create a catalog\n2. `natster catalog serve` to host the media catalog\n3. `natster catalog share` to share with friends.")

return nil
}
Expand Down
Loading