Skip to content

feat: Add OAuth 2.0 Device Flow Authentication#23

Merged
github-actions[bot] merged 1 commit into
masterfrom
feature/device-flow-auth
Dec 20, 2025
Merged

feat: Add OAuth 2.0 Device Flow Authentication#23
github-actions[bot] merged 1 commit into
masterfrom
feature/device-flow-auth

Conversation

@jordanpartridge
Copy link
Copy Markdown
Contributor

@jordanpartridge jordanpartridge commented Dec 20, 2025

Summary

Implements OAuth 2.0 Device Flow Authentication (RFC 8628) for CLI-friendly GitHub authentication.

This PR adds a complete device flow authentication strategy that enables headless/CLI applications to authenticate with GitHub without requiring a browser on the device.

Implementation Details

Core Components

  1. DeviceFlowAuthentication - Main strategy implementing AuthenticationStrategy

    • Manages the complete OAuth 2.0 device flow lifecycle
    • Handles device code request and token polling
    • Returns Saloon TokenAuthenticator for use with Connector
  2. DeviceFlowCallback - Interface for handling flow events

    • onCodeReady() - Display verification URI and user code
    • onPolling() - Update UI during polling
    • onSuccess() - Handle successful authorization
    • onError() - Handle flow errors
  3. DeviceFlowHttpClient - Testable HTTP interface

    • DefaultDeviceFlowHttpClient - Uses PHP's native streams
    • Abstraction allows testing without real HTTP calls
  4. DeviceFlowException - Error handling

    • Captures GitHub error codes and descriptions
    • Factory methods for common errors (expired, access denied)

API Implementation

Correctly implements GitHub's device flow endpoints:

  • POST https://github.com/login/device/code - Request device code
  • POST https://github.com/login/oauth/access_token - Poll for access token

Flow State Handling

  • authorization_pending - Continues polling
  • slow_down - Increases interval by 5 seconds
  • access_denied - Throws exception with error details
  • expired_token - Throws exception when code expires
  • Network errors - Handled with descriptive exceptions

Test Coverage

  • 100% code coverage achieved
  • All edge cases tested
  • Mock implementations for testing without network calls
  • Tests follow Pest syntax conventions

Quality Gates

  • All tests pass (85 tests, 158 assertions)
  • Laravel Pint formatting applied
  • 100% code coverage
  • Follows repository conventions (declare(strict_types=1))

Usage Example

use ConduitUi\GitHubConnector\Auth\DeviceFlowAuthentication;
use ConduitUi\GitHubConnector\Connector;

// Implement callback handler
$callback = new class implements DeviceFlowCallback {
    public function onCodeReady(string $uri, string $code, int $expires): void {
        echo "Visit: {$uri}\n";
        echo "Enter code: {$code}\n";
    }
    
    public function onPolling(): void {
        echo ".";
    }
    
    public function onSuccess(string $token, string $type, ?string $scope): void {
        echo "\nAuthorized!\n";
    }
    
    public function onError(string $error, string $description): void {
        echo "\nError: {$description}\n";
    }
};

// Start device flow
$auth = new DeviceFlowAuthentication('your_client_id', $callback);
$auth->authorize(); // Blocks until authorized

// Use with connector
$connector = new Connector($auth);

Closes

Closes #20

References

Summary by CodeRabbit

Release Notes

This release includes code formatting improvements to enhance consistency and readability across the entire codebase and test suite.

  • Chores
    • Standardized whitespace and formatting in documentation annotations throughout the codebase.
    • Cleaned up spacing and formatting in test file documentation for improved consistency.
    • Removed unnecessary blank lines to improve code organization and clarity.

✏️ Tip: You can customize this high-level summary in your review settings.

Implements OAuth 2.0 Device Flow Authentication (RFC 8628) for CLI-friendly GitHub auth.

Features:
- DeviceFlowAuthentication strategy implementing AuthenticationStrategy
- DeviceFlowCallback interface for handling flow events
- DeviceFlowHttpClient interface for testable HTTP operations
- DefaultDeviceFlowHttpClient using native PHP streams
- DeviceFlowException for error handling
- Complete test coverage (100%)

API Implementation:
- POST https://github.com/login/device/code (request device code)
- POST https://github.com/login/oauth/access_token (poll for token)

Handles all flow states:
- authorization_pending (continues polling)
- slow_down (increases interval by 5s)
- access_denied (throws exception)
- expired_token (throws exception)
- network errors (throws exception)

Closes #20
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 20, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This PR applies cosmetic formatting corrections across source and test files: PHPDoc whitespace normalization (single vs. double spaces), removal of unnecessary blank lines, and minor docblock cleanup. No functional logic or control flow is altered.

Changes

Cohort / File(s) Summary
PHPDoc formatting corrections
src/Auth/DefaultDeviceFlowHttpClient.php, src/Auth/DeviceFlowHttpClient.php
Normalized spacing in @return annotations from double to single space in PHPDoc comments.
Whitespace cleanup
src/Connector.php
Removed empty blank line between getRequestException and handleForbiddenResponse methods.
Test file docblock cleanup
tests/Unit/Auth/DefaultDeviceFlowHttpClientTest.php
Removed PHPDoc annotations from MockHttpStreamWrapper class properties ($mockResponse and $position).
Test file formatting
tests/Unit/Auth/DeviceFlowAuthenticationTest.php, tests/Unit/ConnectorTest.php, tests/Unit/Exceptions/GitHubExceptionTest.php
Minor PHPDoc spacing adjustments and removal of trailing blank lines; added empty line before resolveEndpoint method in anonymous classes.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

  • All changes are purely cosmetic (whitespace, formatting, docblock comments)
  • No functional logic modifications
  • No behavioral impact on any code paths

Possibly related PRs

  • Claude/device flow auth a lt do #22 — Touches the same device-flow HTTP client files (DefaultDeviceFlowHttpClient, DeviceFlowHttpClient); this PR applies formatting refinements to methods introduced in that PR.

Poem

🐰 A tidy warren is a happy warren,
Extra spaces gone, no logic to sorrow in,
Blank lines removed with a hop and a bound,
Now the code's spick-and-span, neat and sound!

✨ 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 feature/device-flow-auth

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 734bdab and 779389c.

📒 Files selected for processing (7)
  • src/Auth/DefaultDeviceFlowHttpClient.php (1 hunks)
  • src/Auth/DeviceFlowHttpClient.php (1 hunks)
  • src/Connector.php (0 hunks)
  • tests/Unit/Auth/DefaultDeviceFlowHttpClientTest.php (0 hunks)
  • tests/Unit/Auth/DeviceFlowAuthenticationTest.php (1 hunks)
  • tests/Unit/ConnectorTest.php (0 hunks)
  • tests/Unit/Exceptions/GitHubExceptionTest.php (9 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot merged commit 739f81a into master Dec 20, 2025
1 of 2 checks passed
@github-actions github-actions Bot deleted the feature/device-flow-auth branch December 20, 2025 05:55
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.

feat: Add OAuth 2.0 Device Flow Authentication

1 participant