Skip to content

Always return plain text from auth/login API endpoint#941

Merged
rogerfar merged 1 commit intorogerfar:mainfrom
ALenfant:fix_login_format
Mar 1, 2026
Merged

Always return plain text from auth/login API endpoint#941
rogerfar merged 1 commit intorogerfar:mainfrom
ALenfant:fix_login_format

Conversation

@ALenfant
Copy link
Contributor

@ALenfant ALenfant commented Mar 1, 2026

Summary

  • Force /api/v2/auth/login to return text/plain bodies (Ok./Fails.)
  • Ignore Accept-driven JSON serialization for this endpoint to match qBittorrent behavior

This has the same behavior as the official qBittorrent API and removes an issue preventing to log in with qBitcontroller: fixes #872

Why

qBitController expects exact unquoted Ok. from login. With JSON negotiation, ASP.NET can return "Ok.", which causes unknown login response errors.

This was tested on my side and confirmed: the official qBittorrent implementation never returns a JSON string, always plain text, regardless of the Accept header.

Scope

  • server/RdtClient.Web/Controllers/QBittorrentController.cs only

Validation

  • Manual validation path: POST /api/v2/auth/login with Accept: application/json should still return plain text Ok./Fails. (unquoted).

@qodo-code-review
Copy link
Contributor

Review Summary by Qodo

Force qB auth/login endpoint to return plain text

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Force /api/v2/auth/login to return plain text responses
• Replace Ok() with Content() for explicit text/plain content type
• Ensures compatibility with qBitController login validation
• Prevents JSON serialization of login response strings
Diagram
flowchart LR
  A["AuthLogin endpoint"] -->|"Changed from Ok()"| B["Content with text/plain"]
  B -->|"Returns unquoted"| C["Ok. or Fails."]
  C -->|"Compatible with"| D["qBitController"]
Loading

Grey Divider

File Changes

1. server/RdtClient.Web/Controllers/QBittorrentController.cs 🐞 Bug fix +5/-5

Replace Ok() with Content() for plain text responses

• Replaced all four Ok() return statements in AuthLogin method with Content() calls
• Explicitly set content type to text/plain for all login responses
• Ensures responses are returned as unquoted plain text strings
• Fixed newline at end of file

server/RdtClient.Web/Controllers/QBittorrentController.cs


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Mar 1, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Remediation recommended

1. No regression test added 🐞 Bug ⛯ Reliability
Description
The PR intentionally hard-codes the login response to text/plain with exact bodies ("Ok."/"Fails."),
but there is no automated test ensuring this contract (including when clients send Accept:
application/json). Without coverage, this endpoint’s format can be unintentionally reverted in
future refactors and break clients again.
Code

server/RdtClient.Web/Controllers/QBittorrentController.cs[R27-42]

+            return Content("Ok.", "text/plain");
        }

        if (String.IsNullOrWhiteSpace(request.UserName) || String.IsNullOrEmpty(request.Password))
        {
-            return Ok("Fails.");
+            return Content("Fails.", "text/plain");
        }

        var result = await qBittorrent.AuthLogin(request.UserName, request.Password);

        if (result)
        {
-            return Ok("Ok.");
+            return Content("Ok.", "text/plain");
        }

-        return Ok("Fails.");
+        return Content("Fails.", "text/plain");
Evidence
The login endpoint now returns Content("Ok.", "text/plain") / Content("Fails.", "text/plain"), which
is a very specific client-facing contract. The repository’s existing test project is scoped to the
service layer (RdtClient.Service.Test references only RdtClient.Service), indicating there’s
currently no web/API-level test coverage to lock this behavior in.

server/RdtClient.Web/Controllers/QBittorrentController.cs[14-52]
server/RdtClient.Service.Test/RdtClient.Service.Test.csproj[34-36]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`/api/v2/auth/login` now intentionally returns exact plain-text bodies (`Ok.`/`Fails.`) with `text/plain`. This is a client-sensitive contract and should be protected by automated tests so future refactors don’t accidentally reintroduce content negotiation/JSON string quoting.

### Issue Context
The controller explicitly returns `Content("Ok.", "text/plain")` / `Content("Fails.", "text/plain")` for both GET and POST handlers.

### Fix Focus Areas
- server/RdtClient.Web/Controllers/QBittorrentController.cs[14-52]

### Suggested implementation outline
- Add a new test project for the web layer (e.g., `server/RdtClient.Web.Test`) using `Microsoft.AspNetCore.Mvc.Testing`.
- Write tests that call:
 - `GET /api/v2/auth/login?username=...&password=...` with header `Accept: application/json`
 - `POST /api/v2/auth/login` form-encoded with header `Accept: application/json`
- Assert:
 - status code is 200
 - response `Content-Type` starts with `text/plain`
 - response body is exactly `Ok.` (or `Fails.` for invalid credentials/empty params).
- Keep test credentials deterministic by configuring the in-memory identity store / test auth setup for the WebApplicationFactory.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@ALenfant ALenfant mentioned this pull request Mar 1, 2026
@ALenfant ALenfant changed the title Fix qB auth/login to always return plain text Always return plain text from auth/login API endpoint Mar 1, 2026
@rogerfar rogerfar merged commit 7ec977b into rogerfar:main Mar 1, 2026
1 check passed
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.

qBitControler

2 participants