Enable fh to generate and revoke device tokens#215
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughA new token subcommand has been added to the FlakeHub CLI, enabling device token generation for authentication. The implementation includes a token module with CLI command handling, a generic POST helper for API requests, token request/response types, and integration into the main command dispatcher. Changes
Sequence DiagramsequenceDiagram
participant CLI as CLI Parser
participant Handler as TokenSubcommand Handler
participant Client as FlakeHubClient
participant API as Remote API
CLI->>Handler: execute(api_addr, org, description)
Handler->>Client: generate_device_token(api_addr, org, description)
Client->>Client: construct TokenRequest
Client->>API: POST /token with TokenRequest
API-->>Client: TokenResponse {token, actor_id}
Client->>Client: extract token field
Client-->>Handler: Result<String>
Handler->>Handler: print token to stdout
Handler-->>CLI: ExitCode::SUCCESS
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/cli/cmd/mod.rs`:
- Around line 347-359: The post function currently deserializes the response
directly which hides HTTP error statuses; modify async fn post<In,Out> to fetch
the response with client.post(...).send().await?, inspect the response status
(e.g., response.status().is_success() or response.error_for_status()), and only
call response.json::<Out>().await when successful; on non-success, read the
response body (as text) and return an FhError that includes the HTTP status and
body to mirror how metadata/resolve/auth_status handle errors (referencing the
post function, make_base_client, and FhError).
🧹 Nitpick comments (1)
src/cli/cmd/mod.rs (1)
302-310:#[serde(skip_serializing)]is a no-op here.
TokenResponseonly derivesDeserialize, so a serialization-related attribute onactor_idhas no effect. If the intent is to ignoreactor_idduring deserialization when it's missing, you'd want#[serde(default)]; otherwise the attribute can simply be removed to avoid confusion.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@flake.nix`:
- Line 122: Replace the deprecated pkgs.nixfmt-rfc-style reference with the
unified nixfmt package so both the formatter configuration and the check script
use the same name; specifically, change the formatter declaration that currently
uses pkgs.nixfmt-rfc-style to use nixfmt and ensure runtimeInputs (runtimeInputs
= [ nixfmt ]) and any other references to the formatter/check tooling all point
to nixfmt to keep names consistent.
🧹 Nitpick comments (2)
src/cli/cmd/mod.rs (2)
302-310:#[serde(skip_serializing)]has no effect on aDeserialize-only struct.
TokenResponseonly derivesDeserialize, soskip_serializingonactor_idis a no-op. If the intent is to ignoreactor_idduring deserialization, this attribute won't do that (and you'd wantskip_deserializingor just leave it as-is since you destructure with..). If the intent is just documentation that you don't use the field, the#[allow(dead_code)]already communicates that.Suggested cleanup
#[derive(Deserialize)] struct TokenResponse { token: String, // We don't need this yet but we may eventually #[allow(dead_code)] - #[serde(skip_serializing)] actor_id: String, }
292-319:create_tokenreturnscolor_eyre::ResultwhilepostreturnsResult<_, FhError>.This is fine since
FhErrorcan convert intocolor_eyre::Reportvia?, but note the inconsistency: mostFlakeHubClientmethods that callgetreturnResult<_, FhError>, whilecreate_tokenreturnscolor_eyre::Result. Consider aligning the return type for consistency with the rest of the client API, unless you plan to add richer error context here later.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/cli/cmd/mod.rs (1)
440-458:⚠️ Potential issue | 🔴 Critical
#[cfg(test)]onmake_base_clientremoves it from non-test builds — this is the root cause of every pipeline failure.The function is gated with
#[cfg(test)](line 440), so it doesn't exist in release/debug builds. Every call site (lines 182, 223, 251, 328, 351) fails withcannot find function make_base_client. The cascading unused-import errors forACCEPT,Client,HeaderMap,HeaderValuefollow from the same cause.The intent is clearly to skip the auth-token file read during tests. Remove
#[cfg(test)]from the function and keep only the inner#[cfg(not(test))]gate.Proposed fix
-#[cfg(test)] async fn make_base_client(authenticated: bool) -> Result<Client, FhError> { let mut headers = HeaderMap::new(); headers.insert(ACCEPT, HeaderValue::from_static("application/json"));
🧹 Nitpick comments (1)
src/cli/cmd/mod.rs (1)
297-310:#[serde(skip_serializing)]is a no-op on aDeserialize-only struct.
TokenResponsederives onlyDeserialize, soskip_serializingonactor_idhas no effect. If you want to document that the field is intentionally unused, the existing#[allow(dead_code)]already does that.Proposed cleanup
#[derive(Deserialize)] struct TokenResponse { token: String, // We don't need this yet but we may eventually #[allow(dead_code)] - #[serde(skip_serializing)] actor_id: String, }
This reverts commit 2021191.
This PR adds an
fh token device create --org <org> --description <description>command that enables generating coarse-grained device tokens for FlakeHub. It also enables revoking tokens.Summary by CodeRabbit