Skip to content

feat: add new endpoint to retrieve member by external id#526

Open
smarcet wants to merge 1 commit intomainfrom
feature/get-member-by-external-id-endpoint
Open

feat: add new endpoint to retrieve member by external id#526
smarcet wants to merge 1 commit intomainfrom
feature/get-member-by-external-id-endpoint

Conversation

@smarcet
Copy link
Copy Markdown
Collaborator

@smarcet smarcet commented Apr 10, 2026

GET /api/v1/members/external/{external_id}

Summary by CodeRabbit

  • New Features
    • Added a protected API endpoint to retrieve members by external identifier with role-based access control (SuperAdmins, Administrators, SummitAdministrators).
    • Includes comprehensive OpenAPI documentation and database seeding configuration for proper integration and endpoint discoverability.
    • Uses OAuth2 authorization scope for secure member data access.

GET /api/v1/members/external/{external_id}
@smarcet smarcet requested a review from romanetar April 10, 2026 20:37
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

📝 Walkthrough

Walkthrough

A new OAuth2-protected API endpoint is added to retrieve members by external ID. The implementation includes a controller method, database migration, seeder configuration, and route definition with appropriate authorization constraints.

Changes

Cohort / File(s) Summary
API Controller & Routing
app/Http/Controllers/Apis/Protected/Main/OAuth2MembersApiController.php, routes/api_v1.php
Added getMemberByIdExternalId() controller method with OpenAPI documentation and new GET route for /api/v1/members/external/{external_id} protected by auth.user middleware.
Database & Seed Configuration
database/migrations/config/Version20260410172200.php, database/seeders/ApiEndpointsSeeder.php
Added Doctrine migration to seed the new endpoint with ReadMemberData scope and authorization for SuperAdmins, Administrators, and SummitAdministrators; updated seeder to include get-member-by-external-id endpoint entry.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • romanetar

Poem

🐰 A rabbit hops with glee so bright,
A new endpoint shines in the night!
External IDs now find their way,
Through OAuth's gates, hip-hop hooray! 🔐
Migrations dance, seeders align,
This member lookup code's divine! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and concisely describes the primary change: adding a new endpoint to retrieve members by external ID, which is the core functionality across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/get-member-by-external-id-endpoint

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
Copy link
Copy Markdown

📘 OpenAPI / Swagger preview

➡️ https://OpenStackweb.github.io/summit-api/openapi/pr-526/

This page is automatically updated on each push to this PR.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/Http/Controllers/Apis/Protected/Main/OAuth2MembersApiController.php`:
- Around line 539-544: The code is serializing a fetched member with
SerializerRegistry::SerializerType_Private which exposes self-profile fields;
change the serializer to use the public/admin policy instead (e.g., replace
SerializerRegistry::SerializerType_Private with
SerializerRegistry::SerializerType_Public to match getById) in
OAuth2MembersApiController where getSerializer($member, ...) is called so
cross-member lookups don't use private serialization.

In `@routes/api_v1.php`:
- Around line 27-30: The route parameter {external_id} is unconstrained and
should be limited to digits to reject invalid paths before controller handling;
update the routing to add a numeric where constraint (e.g. apply
where('external_id', '[0-9]+') either on the inner Route::group for the
'{external_id}' prefix or chain ->where(...) on the Route::get) so that
OAuth2MembersApiController@getMemberByIdExternalId only receives numeric
external_id values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c306c054-d5b7-4f23-b045-04aee98eedbe

📥 Commits

Reviewing files that changed from the base of the PR and between 6439c0a and cfb34dd.

📒 Files selected for processing (4)
  • app/Http/Controllers/Apis/Protected/Main/OAuth2MembersApiController.php
  • database/migrations/config/Version20260410172200.php
  • database/seeders/ApiEndpointsSeeder.php
  • routes/api_v1.php

Comment on lines +539 to +544
return $this->ok(SerializerRegistry::getInstance()->getSerializer($member, SerializerRegistry::SerializerType_Private)->serialize
(
SerializerUtils::getExpand(),
SerializerUtils::getFields(),
SerializerUtils::getRelations()
));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use admin/public serialization policy, not private serialization, for cross-member lookup.

This endpoint fetches another member record, but it currently serializes with SerializerType_Private (self-profile level). That is inconsistent with getById and can overexpose member fields.

Suggested change
-            return $this->ok(SerializerRegistry::getInstance()->getSerializer($member, SerializerRegistry::SerializerType_Private)->serialize
+            return $this->ok(SerializerRegistry::getInstance()->getSerializer($member, SerializerRegistry::SerializerType_Admin)->serialize
             (
                 SerializerUtils::getExpand(),
                 SerializerUtils::getFields(),
                 SerializerUtils::getRelations()
             ));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return $this->ok(SerializerRegistry::getInstance()->getSerializer($member, SerializerRegistry::SerializerType_Private)->serialize
(
SerializerUtils::getExpand(),
SerializerUtils::getFields(),
SerializerUtils::getRelations()
));
return $this->ok(SerializerRegistry::getInstance()->getSerializer($member, SerializerRegistry::SerializerType_Admin)->serialize
(
SerializerUtils::getExpand(),
SerializerUtils::getFields(),
SerializerUtils::getRelations()
));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Http/Controllers/Apis/Protected/Main/OAuth2MembersApiController.php`
around lines 539 - 544, The code is serializing a fetched member with
SerializerRegistry::SerializerType_Private which exposes self-profile fields;
change the serializer to use the public/admin policy instead (e.g., replace
SerializerRegistry::SerializerType_Private with
SerializerRegistry::SerializerType_Public to match getById) in
OAuth2MembersApiController where getSerializer($member, ...) is called so
cross-member lookups don't use private serialization.

Comment on lines +27 to +30
Route::group(['prefix' => 'external'], function () {
Route::group(['prefix' => '{external_id}'], function () {
Route::get('', ['middleware' => 'auth.user', 'uses' => 'OAuth2MembersApiController@getMemberByIdExternalId']);
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Constrain external_id to numeric values at the routing boundary.

{external_id} is currently unconstrained. Add a where clause so invalid path values are rejected before hitting the controller.

Suggested change
-    Route::group(['prefix' => '{external_id}'], function () {
+    Route::group(['prefix' => '{external_id}', 'where' => ['external_id' => '[0-9]+']], function () {
         Route::get('',  ['middleware' => 'auth.user', 'uses' => 'OAuth2MembersApiController@getMemberByIdExternalId']);
     });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Route::group(['prefix' => 'external'], function () {
Route::group(['prefix' => '{external_id}'], function () {
Route::get('', ['middleware' => 'auth.user', 'uses' => 'OAuth2MembersApiController@getMemberByIdExternalId']);
});
Route::group(['prefix' => 'external'], function () {
Route::group(['prefix' => '{external_id}', 'where' => ['external_id' => '[0-9]+']], function () {
Route::get('', ['middleware' => 'auth.user', 'uses' => 'OAuth2MembersApiController@getMemberByIdExternalId']);
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@routes/api_v1.php` around lines 27 - 30, The route parameter {external_id} is
unconstrained and should be limited to digits to reject invalid paths before
controller handling; update the routing to add a numeric where constraint (e.g.
apply where('external_id', '[0-9]+') either on the inner Route::group for the
'{external_id}' prefix or chain ->where(...) on the Route::get) so that
OAuth2MembersApiController@getMemberByIdExternalId only receives numeric
external_id values.

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.

1 participant