Skip to content

feat(apps): add MantisHub connector - #467

Open
biztex wants to merge 2 commits into
onecli:mainfrom
biztex:feat/mantishub-connector
Open

feat(apps): add MantisHub connector#467
biztex wants to merge 2 commits into
onecli:mainfrom
biztex:feat/mantishub-connector

Conversation

@biztex

@biztex biztex commented Jul 30, 2026

Copy link
Copy Markdown

I have read the CONTRIBUTING.md file.

YES

What kind of change does this PR introduce?

Feature — a new app connector. Closes #298.

Note for @johnnyfish: you mentioned in the issue you'd wire this up once the two open questions were answered — both were (raw token, no Bearer prefix; MantisHub is *.mantishub.io only). Since some time has passed I went ahead and built it; if you already have a build in flight I'm happy to close this in its favor.

Stacked on #466 — the first commit here is #466's AuthStrategy::Header addition, which this connector needs (raw token in a named header). Only the second commit (feat(apps): add MantisHub connector) is new; it becomes a one-commit rebase once #466 lands.

What is the current behavior?

MantisHub is not in the catalog. Its REST API authenticates with an API token sent raw in the Authorization header — no Bearer prefix — on per-customer hosts (<name>.mantishub.io), which needs both the raw-header strategy from #466 and per-tenant host gating.

What is the new behavior?

A MantisHub connector:

  • Connection: API token + MantisHub host (acme.mantishub.io), following the JFrog Artifactory two-field shape. The gateway injects the raw token via AuthStrategy::Header { name: "authorization" } on HostPattern::Suffix(".mantishub.io"), gated to the connection's stored host with credential_host_field — a token can never leak to another tenant on the shared suffix (same protection as JFrog).
  • Metadata: best-effort GET /api/rest/users/me against the stored host (validated against the *.mantishub.io shape before any fetch); falls back to echoing the host.
  • Permission catalog: read tools for issues, projects, filters, users, and config; write tools for managing issues (notes, tags, attachments, relationships) and projects. MantisBT's REST API is GET vs POST/PATCH/DELETE, so both umbrellas are true supersets — verified by the wildcard-coverage suites (190 apps tests pass locally).
  • Gateway tests mirror the JFrog suite: suffix matching, no false positives on the bare suffix, raw-header injection, and the credential host gate.

Additional context

  • Per the issue thread, MantisHub itself only uses *.mantishub.io, so that suffix is the whole surface. Self-hosted MantisBT on arbitrary domains (also raised in the thread) is deliberately out of scope until a user-supplied-host pattern exists (feat(gateway): add HostPattern::Env for self-hosted connector hosts #374 proposes HostPattern::Env); the connector is ready to grow that second host rule when it does.
  • Icon note: MantisBT isn't in Simple Icons, so the icon is a neutral mantis-silhouette mark in the same 24×24 monochrome style as the other catalog icons — happy to swap in an official asset if there's one with clear licensing.

biztex added 2 commits July 30, 2026 17:52
Testiny's REST API (app.testiny.io/api/v1) authenticates with an API
key sent raw in the X-Api-Key header - no Bearer prefix - which no
existing AuthStrategy covers. Add a generic Header variant that injects
the credential into a provider-named header, and use it for the Testiny
provider. The variant also unblocks other raw-header providers (e.g.
MantisHub's raw Authorization token, onecli#298).

The permission catalog mirrors Testiny's uniform CRUD: per-entity read
and write tools for projects, test cases and folders, test runs, test
plans, milestones, and comments, plus the POST /find query endpoints as
a read tool. The finds travel as POST, so the GET-only read wildcard is
deliberately not a superset (Jira JQL precedent); the write wildcard
gates every mutating method under /api/v1/* and is a true superset.

Closes onecli#422
MantisHub is hosted MantisBT on per-customer hosts (<name>.mantishub.io)
whose REST API takes an API token raw in the Authorization header - no
scheme prefix - exactly the shape the AuthStrategy::Header variant
introduced for Testiny covers. Injection is gated to the connection's
stored host via credential_host_field (the JFrog pattern), so a token
never leaks to another tenant on the shared suffix.

The permission catalog covers issues (incl. notes, tags, attachments,
relationships), projects, filters, users, and config, with read and
write umbrellas that are true supersets of their groups.

Self-hosted MantisBT on arbitrary domains is out of scope until a
user-supplied-host pattern lands (see onecli#374); *.mantishub.io is the
whole MantisHub surface per the issue thread.

Closes onecli#298
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.

App request: MantisHub

1 participant