Skip to content

Commit

Permalink
send auth to version check, if logged in
Browse files Browse the repository at this point in the history
  • Loading branch information
aybabtme committed Sep 27, 2024
1 parent 6bfd911 commit 08dcdbc
Show file tree
Hide file tree
Showing 11 changed files with 312 additions and 717 deletions.
8 changes: 6 additions & 2 deletions cmd/humanlog/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ func ensureLoggedIn(
Title("You're logged out. Would you like to login?").
Affirmative("Yes!").
Negative("No.").
Value(&confirms).Run()
Value(&confirms).
WithTheme(huh.ThemeBase16()).
Run()
if !confirms {
return nil, fmt.Errorf("aborting")
}
Expand All @@ -71,7 +73,9 @@ func ensureLoggedIn(
Title("Your session has expired. Would you like to login again?").
Affirmative("Yes!").
Negative("No.").
Value(&confirms).Run()
Value(&confirms).
WithTheme(huh.ThemeBase16()).
Run()
if !confirms {
return nil, fmt.Errorf("aborting")
}
Expand Down
51 changes: 23 additions & 28 deletions cmd/humanlog/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"net/url"
"os"
"os/signal"
"runtime"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -201,6 +200,24 @@ func newApp() *cli.App {
promptedToUpdate *semver.Version
updateRes <-chan *checkForUpdateRes
apiURL = "https://api.humanlog.io"

getCtx = func(*cli.Context) context.Context { return ctx }
getLogger = func(*cli.Context) *slog.Logger { return slog.New(slog.NewJSONHandler(os.Stderr, nil)) }
getCfg = func(*cli.Context) *config.Config { return cfg }
getState = func(*cli.Context) *state.State { return statefile }
getTokenSource = func(*cli.Context) *auth.UserRefreshableTokenSource { return auth.NewRefreshableTokenSource() }
getAPIUrl = func(*cli.Context) string { log.Printf("using api at %q", apiURL); return apiURL }
getHTTPClient = func(*cli.Context) *http.Client {
u, _ := url.Parse(apiURL)
if host, _, _ := net.SplitHostPort(u.Host); host == "localhost" {
log.Printf("DEBUG: using localhost client")
return localhostHttpClient
}
return httpClient
}
getLocalhostHTTPClient = func(*cli.Context) *http.Client {
return localhostHttpClient
}
)

app.Before = func(c *cli.Context) error {
Expand Down Expand Up @@ -250,13 +267,9 @@ func newApp() *cli.App {
promptToUpdate(semverVersion, *statefile.LatestKnownVersion)
}
}

req := &checkForUpdateReq{
arch: runtime.GOARCH,
os: runtime.GOOS,
current: version,
}
updateRes = asyncCheckForUpdate(ctx, req, cfg, statefile, apiURL, httpClient)
ll := getLogger(c)
tokenSource := getTokenSource(c)
updateRes = asyncCheckForUpdate(ctx, ll, cfg, statefile, apiURL, httpClient, tokenSource)
}

return nil
Expand All @@ -280,27 +293,9 @@ func newApp() *cli.App {
}
return nil
}
var (
getCtx = func(*cli.Context) context.Context { return ctx }
getCfg = func(*cli.Context) *config.Config { return cfg }
getState = func(*cli.Context) *state.State { return statefile }
getTokenSource = func(*cli.Context) *auth.UserRefreshableTokenSource { return auth.NewRefreshableTokenSource() }
getAPIUrl = func(*cli.Context) string { log.Printf("using api at %q", apiURL); return apiURL }
getHTTPClient = func(*cli.Context) *http.Client {
u, _ := url.Parse(apiURL)
if host, _, _ := net.SplitHostPort(u.Host); host == "localhost" {
log.Printf("DEBUG: using localhost client")
return localhostHttpClient
}
return httpClient
}
getLocalhostHTTPClient = func(*cli.Context) *http.Client {
return localhostHttpClient
}
)
app.Commands = append(
app.Commands,
versionCmd(getCtx, getCfg, getState, getAPIUrl, getHTTPClient),
versionCmd(getCtx, getLogger, getCfg, getState, getTokenSource, getAPIUrl, getHTTPClient),
authCmd(getCtx, getCfg, getState, getTokenSource, getAPIUrl, getHTTPClient),
queryCmd(getCtx, getCfg, getState, getTokenSource, getAPIUrl, getHTTPClient),
gennyCmd(getCtx, getCfg, getState),
Expand Down Expand Up @@ -392,7 +387,7 @@ func newApp() *cli.App {
state := getState(cctx)
// TODO(antoine): all logs to a single location, right now there's code logging
// randomly everywhere
ll := slog.New(slog.NewJSONHandler(os.Stderr, nil))
ll := getLogger(cctx)
var machineID uint64
for state.MachineID == nil {
// no machine ID assigned, ensure machine gets onboarded via the loggin flow
Expand Down
23 changes: 16 additions & 7 deletions cmd/humanlog/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"log"
"log/slog"
"net/http"
"os"
"runtime"
Expand All @@ -19,6 +20,7 @@ import (
"github.com/humanlogio/humanlog/internal/pkg/config"
"github.com/humanlogio/humanlog/internal/pkg/selfupdate"
"github.com/humanlogio/humanlog/internal/pkg/state"
"github.com/humanlogio/humanlog/pkg/auth"
"github.com/mattn/go-isatty"
"github.com/urfave/cli"
)
Expand Down Expand Up @@ -93,8 +95,10 @@ const versionCmdName = "version"

func versionCmd(
getCtx func(cctx *cli.Context) context.Context,
getLogger func(cctx *cli.Context) *slog.Logger,
getCfg func(cctx *cli.Context) *config.Config,
getState func(cctx *cli.Context) *state.State,
getTokenSource func(cctx *cli.Context) *auth.UserRefreshableTokenSource,
getAPIUrl func(cctx *cli.Context) string,
getHTTPClient func(*cli.Context) *http.Client,
) cli.Command {
Expand All @@ -107,11 +111,13 @@ func versionCmd(
Usage: "checks whether a newer version is available",
Action: func(cctx *cli.Context) error {
ctx := getCtx(cctx)
ll := getLogger(cctx)
cfg := getCfg(cctx)
state := getState(cctx)
tokenSource := getTokenSource(cctx)
apiURL := getAPIUrl(cctx)
httpClient := getHTTPClient(cctx)
nextVersion, nextArtifact, hasUpdate, err := checkForUpdate(ctx, cfg, state, apiURL, httpClient)
nextVersion, nextArtifact, hasUpdate, err := checkForUpdate(ctx, ll, cfg, state, apiURL, httpClient, tokenSource)
if err != nil {
return err
}
Expand All @@ -135,11 +141,13 @@ func versionCmd(
Usage: "self-update to the latest version",
Action: func(cctx *cli.Context) error {
ctx := getCtx(cctx)
ll := getLogger(cctx)
cfg := getCfg(cctx)
state := getState(cctx)
tokenSource := getTokenSource(cctx)
apiURL := getAPIUrl(cctx)
httpClient := getHTTPClient(cctx)
_, _, hasUpdate, err := checkForUpdate(ctx, cfg, state, apiURL, httpClient)
_, _, hasUpdate, err := checkForUpdate(ctx, ll, cfg, state, apiURL, httpClient, tokenSource)
if err != nil {
return err
}
Expand All @@ -165,13 +173,14 @@ type checkForUpdateRes struct {
hasUpdate bool
}

func checkForUpdate(ctx context.Context, cfg *config.Config, state *state.State, apiURL string, httpClient *http.Client) (v *types.Version, a *types.VersionArtifact, hasUpdate bool, err error) {
func checkForUpdate(ctx context.Context, ll *slog.Logger, cfg *config.Config, state *state.State, apiURL string, httpClient *http.Client, tokenSource *auth.UserRefreshableTokenSource) (v *types.Version, a *types.VersionArtifact, hasUpdate bool, err error) {
currentSV, err := version.AsSemver()
if err != nil {
return nil, nil, false, err
}

updateClient := cliupdatev1connect.NewUpdateServiceClient(httpClient, apiURL)
var clOpts []connect.ClientOption
clOpts = append(clOpts, connect.WithInterceptors(auth.NewRefreshedUserAuthInterceptor(ll, tokenSource)))
updateClient := cliupdatev1connect.NewUpdateServiceClient(httpClient, apiURL, clOpts...)
res, err := updateClient.GetNextUpdate(ctx, connect.NewRequest(&cliupdatepb.GetNextUpdateRequest{
ProjectName: "humanlog",
CurrentVersion: version,
Expand All @@ -196,11 +205,11 @@ func checkForUpdate(ctx context.Context, cfg *config.Config, state *state.State,
return msg.NextVersion, msg.NextArtifact, currentSV.LT(nextSV), nil
}

func asyncCheckForUpdate(ctx context.Context, req *checkForUpdateReq, cfg *config.Config, state *state.State, apiURL string, httpClient *http.Client) <-chan *checkForUpdateRes {
func asyncCheckForUpdate(ctx context.Context, ll *slog.Logger, cfg *config.Config, state *state.State, apiURL string, httpClient *http.Client, tokenSource *auth.UserRefreshableTokenSource) <-chan *checkForUpdateRes {
out := make(chan *checkForUpdateRes, 1)
go func() {
defer close(out)
nextVersion, _, hasUpdate, err := checkForUpdate(ctx, cfg, state, apiURL, httpClient)
nextVersion, _, hasUpdate, err := checkForUpdate(ctx, ll, cfg, state, apiURL, httpClient, tokenSource)
if err != nil {
if errors.Is(errors.Unwrap(err), context.Canceled) {
return
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/charmbracelet/bubbletea v1.1.1
github.com/charmbracelet/huh v0.4.2
github.com/charmbracelet/lipgloss v0.13.0
github.com/charmbracelet/x/term v0.2.0
github.com/cli/safeexec v1.0.1
github.com/fatih/color v1.16.0
github.com/go-logfmt/logfmt v0.5.1
Expand All @@ -29,6 +30,8 @@ require (
github.com/urfave/cli v1.22.14
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
golang.org/x/net v0.23.0
golang.org/x/sync v0.8.0
golang.org/x/sys v0.25.0
gonum.org/v1/gonum v0.15.1
google.golang.org/protobuf v1.33.0
)
Expand All @@ -40,7 +43,6 @@ require (
github.com/catppuccin/go v0.2.0 // indirect
github.com/charmbracelet/x/ansi v0.3.1 // indirect
github.com/charmbracelet/x/exp/strings v0.0.0-20240524151031-ff83003bf67a // indirect
github.com/charmbracelet/x/term v0.2.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/danieljoos/wincred v1.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand All @@ -59,8 +61,6 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.18.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type State struct {

IngestionToken *typesv1.AccountToken `json:"ingestion_token,omitempty"`

// preferences set in the TUI when querying
CurrentOrgID *int64 `json:"current_org_id,omitempty"`
CurrentAccountID *int64 `json:"current_account_id,omitempty"`
CurrentMachineID *int64 `json:"current_machine_id,omitempty"`
Expand Down
13 changes: 10 additions & 3 deletions pkg/auth/token_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ func NewRefreshableTokenSource() *UserRefreshableTokenSource {

func (rts *UserRefreshableTokenSource) ClearToken(ctx context.Context) error {
ring, err := keyring.Open(keyring.Config{
ServiceName: KeyringName,
ServiceName: KeyringName,
KeychainSynchronizable: true,
})
if err != nil {
return fmt.Errorf("opening keyring: %v", err)
Expand All @@ -49,7 +50,10 @@ func (rts *UserRefreshableTokenSource) GetUserToken(ctx context.Context) (*types
return rts.ut, nil
}

ring, err := keyring.Open(keyring.Config{ServiceName: KeyringName})
ring, err := keyring.Open(keyring.Config{
ServiceName: KeyringName,
KeychainSynchronizable: true,
})
if err != nil {
return nil, fmt.Errorf("opening keyring: %v", err)
}
Expand Down Expand Up @@ -82,7 +86,10 @@ func (rts *UserRefreshableTokenSource) SetUserToken(ctx context.Context, userTok
if err != nil {
return fmt.Errorf("marshaling token to proto: %v", err)
}
ring, err := keyring.Open(keyring.Config{ServiceName: KeyringName})
ring, err := keyring.Open(keyring.Config{
ServiceName: KeyringName,
KeychainSynchronizable: true,
})
if err != nil {
return fmt.Errorf("opening keyring: %v", err)
}
Expand Down
Loading

0 comments on commit 08dcdbc

Please sign in to comment.