Skip to content

Remove browser flow as auth method#36

Open
carole-lavillonniere wants to merge 3 commits intomainfrom
carole/drg-530
Open

Remove browser flow as auth method#36
carole-lavillonniere wants to merge 3 commits intomainfrom
carole/drg-530

Conversation

@carole-lavillonniere
Copy link
Collaborator

  • Remove browser flow auth method, keep device flow only
  • Improve the UI for authentication

Reasons for removing browser flow:

  • It feels less modern and secure to users
  • It is less secure
  • It's hard to know when to fallback to device flow
  • Handling 2 login methods makes the code more complicated

Output (still no TUI):

> lstk
No existing credentials found. Please log in:

Visit https://app.localstack.cloud/auth/request/d5c86cf0-106a-4262-ab80-1e04e86f2c36

Verification code: 4437

Open browser now? [Y/n]

Waiting for authentication (Press [ENTER] when complete)

Checking if auth request is confirmed...
Auth request confirmed, exchanging for token...
Fetching license token...
Login successful.
Pulling localstack/localstack-pro:latest...
  latest: Pulling from localstack/localstack-pro
  : Digest: sha256:88b567c4aaf0d0a7743862b8e12847cafbdc81947cb5857409bb916c5072ba1b
  : Status: Image is up to date for localstack/localstack-pro:latest
localstack-aws: validating license (4.13.2.dev114)
Starting localstack-aws...
Waiting for localstack-aws to be ready...
localstack-aws ready (containerId: d0eda21dfa56)

@carole-lavillonniere
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@carole-lavillonniere carole-lavillonniere marked this pull request as ready for review February 16, 2026 15:28
@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

📝 Walkthrough

Walkthrough

📝 Walkthrough

Renames the browser-based login provider to a generic login provider, replaces the callback-server device flow with an interactive console/browser-driven flow, updates tests to match the new flow, and removes the integration test that exercised the old browser callback flow. Token storage behavior remains exercised by tests.

Changes

Cohort / File(s) Summary
Auth core
internal/auth/auth.go, internal/auth/auth_test.go
Renamed field browserLoginlogin, updated initialization to use newLoginProvider and updated tests to wire login.
Login flow implementation
internal/auth/login.go
Replaced callback-server device flow with loginProvider interactive flow: builds auth request, prints URL/code, optionally opens browser, reads console confirmation, completes auth via token exchange; removed callback server and related logic; renamed constructors/methods accordingly.
Integration tests
test/integration/login_test.go, removed test/integration/login_browser_flow_test.go
Updated device-flow tests to new login flow (renamed tests, changed stdin interactions and expected output). Deleted older browser-callback integration test that simulated HTTP callback.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant CLI
participant Login as LoginProvider
participant Platform as PlatformAPI
participant Browser
participant Keyring
CLI->>Login: start Login(ctx)
Login->>Platform: CreateAuthRequest()
Platform-->>Login: auth request (URL, user_code, request_id)
Login-->>CLI: print URL and code, prompt to open browser
CLI->>Browser: open URL (user visits web app)
Browser->>Platform: user authenticates & confirms request
Platform-->>Login: request confirmed
Login->>Platform: Exchange request_id for token
Platform-->>Login: access token
Login->>Keyring: store token
Login-->>CLI: "Login successful"

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • silv-io
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main change: removing browser flow authentication in favor of device flow only.
Description check ✅ Passed The description clearly explains what is being removed (browser flow auth), what is being kept (device flow), and provides concrete reasons and example output.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch carole/drg-530

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@internal/auth/login.go`:
- Around line 49-61: The code ignores errors from reader.ReadString and
browser.OpenURL; update the interactive flow in the function that constructs
reader and uses authURL (the reader variable, browser.OpenURL call, and
subsequent reader.ReadString before output.EmitLog) to check and handle errors:
capture and handle the first ReadString error (treat io.EOF as empty response
and return or log a user-facing message for non-interactive shells), check the
error returned by browser.OpenURL and emit a warning via output.EmitLog (using
l.sink) if it fails, and also handle the second ReadString error before polling
for auth status so the function fails fast with a clear log rather than silently
continuing.
🧹 Nitpick comments (1)
test/integration/login_test.go (1)

99-108: Consider removing fixed sleeps; stdin buffering already handles ordering.

Fixed sleeps add flakiness and latency. Writing to stdin immediately should still work and speeds the test.

♻️ Suggested cleanup
-	// Wait for instructions
-	time.Sleep(100 * time.Millisecond)
@@
-	// Wait a bit for browser to open
-	time.Sleep(100 * time.Millisecond)
@@
-	// Wait for instructions to be printed
-	time.Sleep(100 * time.Millisecond)
@@
-	// Wait a bit for browser to open
-	time.Sleep(100 * time.Millisecond)

Also applies to: 167-176

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/integration/login_test.go (1)

116-121: Remove duplicate assertions.

Lines 119-120 are redundant:

  • "Auth request confirmed" is a substring of "Auth request confirmed, exchanging for token" (already asserted on line 117)
  • "Fetching license token" is asserted twice (lines 118 and 120)
♻️ Proposed fix to remove duplicates
 		// Should complete authentication successfully
 		assert.Contains(t, output, "Checking if auth request is confirmed")
 		assert.Contains(t, output, "Auth request confirmed, exchanging for token")
 		assert.Contains(t, output, "Fetching license token")
-		assert.Contains(t, output, "Auth request confirmed")
-		assert.Contains(t, output, "Fetching license token")
 		assert.Contains(t, output, "Login successful")

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/integration/login_test.go (1)

67-130: Trim self-explanatory comments in the new interaction steps.

The new inline comments mostly restate the code; consider removing them or replacing with rationale that isn’t obvious from the code itself.

🧹 Suggested cleanup
-	// Simulate answering "Y" to open browser
 	_, err = stdinPipe.Write([]byte("Y\n"))
 	require.NoError(t, err)

-	// Simulate pressing ENTER after completing auth in browser
 	_, err = stdinPipe.Write([]byte("\n"))
 	require.NoError(t, err)

 	select {
 	case out := <-outputCh:
 		output := string(out)
-		// Should show instructions
 		assert.Contains(t, output, "Verification code:")
 		assert.Contains(t, output, "TEST123")
 		assert.Contains(t, output, "Open browser now? [Y/n]")
 		assert.Contains(t, output, "Waiting for authentication (Press [ENTER] when complete)")
-		// Should complete authentication successfully
 		assert.Contains(t, output, "Checking if auth request is confirmed")
 		assert.Contains(t, output, "Auth request confirmed, exchanging for token")
 		assert.Contains(t, output, "Fetching license token")
 		assert.Contains(t, output, "Login successful")
-	// Simulate answering "Y" to open browser
 	_, err = stdinPipe.Write([]byte("Y\n"))
 	require.NoError(t, err)

-	// Simulate pressing ENTER after "completing" auth in browser
 	_, err = stdinPipe.Write([]byte("\n"))
 	require.NoError(t, err)

 	select {
 	case out := <-outputCh:
 		output := string(out)
 		assert.Contains(t, output, "Verification code:")
 		assert.Contains(t, output, "Open browser now? [Y/n]")
 		assert.Contains(t, output, "Waiting for authentication (Press [ENTER] when complete)")
-		// Should attempt authentication but fail because request not confirmed
 		assert.Contains(t, output, "Checking if auth request is confirmed")
 		assert.Contains(t, output, "auth request not confirmed")

As per coding guidelines, "Avoid adding comments for self-explanatory code; only comment when the 'why' isn't obvious from the code itself".

Also applies to: 132-185

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/integration/login_test.go` around lines 67 - 130, In TestLoginSuccess,
remove or shorten the self-explanatory inline comments that merely restate the
code (e.g., comments around licenseToken/env check, mockServer creation, stdin
handling, output assertions) and replace any that remain with brief rationale
explaining non-obvious intent; focus on keeping clarifying comments for why we
manipulate stdinPipe, the purpose of
envWithout("LOCALSTACK_AUTH_TOKEN")/createMockAPIServer, or timing choices for
context.WithTimeout, but delete comments that repeat what functions like
cleanup(), createMockAPIServer, exec.CommandContext, stdinPipe.Write, and the
assert.Contains checks already express.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/integration/login_test.go`:
- Around line 67-130: In TestLoginSuccess, remove or shorten the
self-explanatory inline comments that merely restate the code (e.g., comments
around licenseToken/env check, mockServer creation, stdin handling, output
assertions) and replace any that remain with brief rationale explaining
non-obvious intent; focus on keeping clarifying comments for why we manipulate
stdinPipe, the purpose of
envWithout("LOCALSTACK_AUTH_TOKEN")/createMockAPIServer, or timing choices for
context.WithTimeout, but delete comments that repeat what functions like
cleanup(), createMockAPIServer, exec.CommandContext, stdinPipe.Write, and the
assert.Contains checks already express.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant