Skip to content

feat(sso): add provider detail endpoint DEV-2665 - #7496

Open
rajpatel24 wants to merge 4 commits into
mainfrom
dev-2665-provider-detail-endpoint
Open

feat(sso): add provider detail endpoint DEV-2665#7496
rajpatel24 wants to merge 4 commits into
mainfrom
dev-2665-provider-detail-endpoint

Conversation

@rajpatel24

Copy link
Copy Markdown
Contributor

📣 Summary

This PR adds a public API endpoint that resolves an SSO provider's URL identifier into its display name, so the upcoming React login screens can render the "Log in with …" page that Django templates render today.

📖 Description

This PR adds GET /api/v2/social-apps/<provider_id>/, which returns the provider_id and name for a configured Social Application.

Some organizations sign in through an SSO provider that is deliberately not shown on the public login page. Its Social Application has is_public unchecked, and they distribute a direct link to their own staff, for example: https://<kobo-server>/accounts/oidc/nca/login/. Only the nca part varies. Today, that URL renders a shared Django template titled "Log in with {{ SocialApp.name }}". The same template is used for every provider on every server.

The Authentication Redesign deletes that template and rebuilds the screen in the SPA. To render it at a route like #/login/oidc/<provider_id>, the frontend needs to turn provider_id into a display name and distinguish a real provider from a typo so it can show the appropriate 404. The frontend cannot read the database directly, so it needs this endpoint.

Nothing changes for users yet. The existing login pages are untouched.

👀 Preview steps

  1. ℹ️ Have a superuser account and be able to run manage.py.
  2. Create a hidden SSO provider (provision_server sets is_public=False):
./manage.py provision_server socialapp --provider openid_connect \
  --provider_id nca --name "Norwegian Church Aid" \
  --client_id test-client-id --secret test-secret
  1. Log out and open /accounts/login/.

  2. ℹ️ Notice that "Norwegian Church Aid" is not among the SSO buttons because the provider is hidden.

  3. Open /accounts/oidc/nca/login/.

  4. ℹ️ Notice that the "Log in with Norwegian Church Aid" page still renders unchanged.

  5. 🔴 On main: GET /api/v2/social-apps/nca/ -> 404, because the route does not exist.

  6. 🟢 On the PR: GET /api/v2/social-apps/nca/ -> 200 {"provider_id": "nca", "name": "Norwegian Church Aid"} even though the provider is hidden. That's the point of the endpoint.

  7. 🟢 GET /api/v2/social-apps/typo/ -> 404.

  8. 🟢 GET /api/v2/social-apps/ -> 404. There is deliberately no list endpoint.

  9. 🟢 Notice that the response has exactly two keys. It does not expose client_id, secret, or server_url.

@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds an anonymous API endpoint that resolves an SSO provider identifier to display-only provider data for the upcoming SPA login flow.

  • Adds explicit provider-detail routing, lookup behavior, serialization, and tests for public, hidden, unknown, ambiguous, fallback, and dotted provider identifiers.
  • Publishes the endpoint in both OpenAPI formats and regenerates the TypeScript model, React Query helper, and mock handler.
  • Keeps provider credentials and internal settings out of the response and intentionally provides no list endpoint.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains in the eligible follow-up review scope.

No blocking failure remains.

Sequence Diagram

sequenceDiagram
    participant SPA as React login screen
    participant API as SocialAppView
    participant Adapter as allauth adapter
    participant DB as SocialApp storage
    SPA->>API: "GET /api/v2/social-apps/{provider_id}/"
    API->>Adapter: get_app(request, provider_id)
    Adapter->>DB: Resolve configured provider
    alt Exactly one provider
        DB-->>Adapter: SocialApp
        Adapter-->>API: SocialApp
        API-->>SPA: "200 {provider_id, name}"
    else Missing or ambiguous
        API-->>SPA: 404 Not found
    end
Loading

Reviews (4): Last reviewed commit: "style: fix linting issues" | Re-trigger Greptile

@noliveleger
noliveleger self-requested a review August 27, 2026 12:31
Comment thread kobo/apps/accounts/views.py Outdated
# headless `auth/provider/redirect`, which the SPA posts to next. Both
# look providers up this way, so a 200 here means the redirect will work
try:
return get_socialaccount_adapter().get_app(self.request, provider_id)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You should call self.check_object_permissions(self.request, obj) even if it would do nothing special. Just as a safety guard if the permission classes is changed some day.
Or at least , leave a comment why you omitted. permission_classes is useless atm.

Comment thread kobo/apps/accounts/views.py Outdated
Comment on lines +201 to +202
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You can probably set it at the View level. No need to overload the parent for nothing. I think we do have some examples in the code.

@rajpatel24
rajpatel24 requested a review from noliveleger August 28, 2026 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants