Sijin T V activity https://gitlab.com/sijintv 2026-03-18T04:19:14Z tag:gitlab.com,2026-03-18:5215621289 Sijin T V commented on merge request !227392 at GitLab.org / GitLab 2026-03-18T04:19:14Z sijintv Sijin T V

@idurham Thanks for the detailed review and suggestions. I have made the changes. Can you please have another look?

tag:gitlab.com,2026-03-18:5215612144 Sijin T V commented on merge request !227392 at GitLab.org / GitLab 2026-03-18T04:14:22Z sijintv Sijin T V

@GitLabDuo Can you please take a look at this MR once again?

tag:gitlab.com,2026-03-18:5215601500 Sijin T V pushed to project branch add-oauth-applications-api at GitLab Community / GitLab.org / GitLab Community Fork 2026-03-18T04:07:43Z sijintv Sijin T V

Sijin T V (cffbf796) at 18 Mar 04:07

Address GitLab Duo review comments on User Applications API

tag:gitlab.com,2026-03-18:5215572423 Sijin T V commented on merge request !227392 at GitLab.org / GitLab 2026-03-18T03:52:22Z sijintv Sijin T V

@GitLabDuo I initially applied this change by editing

openapi_v3.yaml directly, but it turns out the file is fully auto-generated via bin/rake gitlab:openapi:v3:generate — any manual edits are overwritten on regeneration. The nullable: true on required path parameters is emitted automatically by Grape's OpenAPI generator and isn't configurable per-parameter in the DSL. This is a known quirk/limitation of the Grape swagger generation layer, not something specific to this endpoint.

tag:gitlab.com,2026-03-18:5215570559 Sijin T V pushed to project branch add-oauth-applications-api at GitLab Community / GitLab.org / GitLab Community Fork 2026-03-18T03:50:52Z sijintv Sijin T V

Sijin T V (c30b3551) at 18 Mar 03:50

Apply 20 suggestion(s) to 2 file(s)

tag:gitlab.com,2026-03-18:5215552971 Sijin T V commented on merge request !227392 at GitLab.org / GitLab 2026-03-18T03:37:28Z sijintv Sijin T V

@GitLabDuo I initially applied this change, but it was caught by GitLab's own pre-commit RuboCop cop: Cop/AvoidReturnFromBlocks, which explicitly requires break instead of return inside blocks (including Grape route handlers). So break is actually the correct pattern for this codebase.

tag:gitlab.com,2026-03-18:5215504927 Sijin T V pushed to project branch add-oauth-applications-api at GitLab Community / GitLab.org / GitLab Community Fork 2026-03-18T03:06:22Z sijintv Sijin T V

Sijin T V (88040831) at 18 Mar 03:06

Fix permissions CI check by adding granular access token authorization

... and 597 more commits

tag:gitlab.com,2026-03-17:5214807925 Sijin T V commented on merge request !227380 at GitLab.org / GitLab 2026-03-17T21:26:27Z sijintv Sijin T V

@victorprete This is ready for review.

tag:gitlab.com,2026-03-17:5214776417 Sijin T V commented on merge request !227380 at GitLab.org / GitLab 2026-03-17T21:17:24Z sijintv Sijin T V

@GitLabDuo Session cleanup already handled correctly — can you please verify?

session[:invite_email] is cleared immediately upon successful signup via session.delete(:invite_email) in registered_with_invite_email? (registrations_controller.rb#L307):

def registered_with_invite_email?
  invite_email = session.delete(:invite_email)  # deletes and reads atomically
  sign_up_params[:email] == invite_email
end
strong_memoize_attr :registered_with_invite_email?

session.delete both reads and removes the key in one call. This method is invoked during the create action (via build_params at line 290), so the session key is gone as soon as a user successfully signs up. The strong_memoize_attr ensures .delete only runs once per request. No reuse is possible after signup.

tag:gitlab.com,2026-03-17:5214755432 Sijin T V pushed to project branch 15059-allow-signup-if-invited at GitLab Community / GitLab.org / GitLab Community Fork 2026-03-17T21:10:44Z sijintv Sijin T V

Sijin T V (41f09f2c) at 17 Mar 21:10

Add unit tests for Member.has_pending_invite_for_email?

... and 2 more commits

tag:gitlab.com,2026-03-17:5214695167 Sijin T V commented on merge request !227380 at GitLab.org / GitLab 2026-03-17T20:48:53Z sijintv Sijin T V

@GitLabDuo I have made the required changes. Can you review once again?

tag:gitlab.com,2026-03-17:5214611543 Sijin T V pushed to project branch 15059-allow-signup-if-invited at GitLab Community / GitLab.org / GitLab Community Fork 2026-03-17T20:21:31Z sijintv Sijin T V

Sijin T V (3e03efe9) at 17 Mar 20:21

Add explanatory comment to UsersController#exists spec regarding se...

... and 521 more commits

tag:gitlab.com,2026-03-17:5214572907 Sijin T V pushed to project branch 15059-allow-signup-if-invited at GitLab Community / GitLab.org / GitLab Community Fork 2026-03-17T20:09:19Z sijintv Sijin T V

Sijin T V (cd0aff0a) at 17 Mar 20:09

Add explanatory comment to UsersController#exists spec regarding se...

... and 2 more commits

tag:gitlab.com,2026-03-17:5213642718 Sijin T V commented on merge request !227380 at GitLab.org / GitLab 2026-03-17T15:52:48Z sijintv Sijin T V

@GitLabDuo What about

Member.with_case_insensitive_invite_emails([session[:invite_email]]).not_accepted_invitations.exists?

tag:gitlab.com,2026-03-17:5213621522 Sijin T V commented on merge request !227380 at GitLab.org / GitLab 2026-03-17T15:48:16Z sijintv Sijin T V

@victorprete I will finish the recommended changes requested by Gitlab Duo first. I will respond here once thats done and ready for the review.

tag:gitlab.com,2026-03-17:5213577056 Sijin T V commented on merge request !227380 at GitLab.org / GitLab 2026-03-17T15:38:07Z sijintv Sijin T V

@GitLabDuo what do you think about return if session[:invite_email].present? && Member.with_case_insensitive_invite_emails([session[:invite_email]]).any?

tag:gitlab.com,2026-03-15:5205145280 Sijin T V pushed to project branch add-oauth-applications-api at GitLab Community / GitLab.org / GitLab Community Fork 2026-03-15T10:57:07Z sijintv Sijin T V

Sijin T V (c33d3aa6) at 15 Mar 10:57

Fix permissions CI check by adding granular access token authorization

tag:gitlab.com,2026-03-15:5205114024 Sijin T V opened merge request !227392: Add User Applications REST API at GitLab.org / GitLab 2026-03-15T10:23:16Z sijintv Sijin T V

What does this MR do and why?

This Merge Request adds the User Applications REST API, fulfilling the requirements described in #23054.

It introduces a set of CRUD endpoints located at /api/v4/user/applications that allow users to manage their instance-level OAuth applications. This is designed to enable programmatic management of user-owned OAuth applications, which proves extremely useful for dynamically deploying and un-deploying Review Apps without having to employ insecure wildcard redirect URIs.

Specifically, it creates the following endpoints:

  1. POST /api/v4/user/applications: Creates an application, exclusively returning the secret during this action.
  2. GET /api/v4/user/applications: Lists all applications owned by the authenticated user.
  3. GET /api/v4/user/applications/:id: Retrieves a specific application.
  4. PUT /api/v4/user/applications/:id: Updates an existing application (e.g. modifying the redirect_uri).
  5. DELETE /api/v4/user/applications/:id: Removes the application.

Security Considerations

The implementation follows strict security best practices regarding credential exposure and bounded context:

  • Secret Exclusivity: In accordance with OAuth 2.0 best practices, the application secret is explicitly and exclusively returned only on the POST create event. Subsequent GET or PUT requests will never expose the secret.
  • Targeting Wildcards: The primary motivation for this API is to give developers a programmatic way to provision dynamic redirect_uri targets (such as ephemeral Review Apps). This eliminates the insecure practice of users resorting to wildcard redirect URIs to handle dynamic domains.
  • Authorization Enforcement: The endpoint exclusively operates within the strict boundary of the current_user. The Authn::UserApplicationsFinder inherently scopes all GET, PUT, and DELETE requests to only OAuth Applications owned by the authenticated user, completely preventing Insecure Direct Object Reference (IDOR) or cross-user data leakage.
  • Confidentiality Awareness: The endpoints explicitly support defining whether an OAuth application is confidential or public (e.g. for SPAs or Native apps), ensuring the system handles the client appropriately during the OAuth flow.

Database Queries

The User Applications API executes standard CRUD operations on the oauth_applications table, scoped to the current user. Here are the query execution plans:

1. Read (Finder)

EXPLAIN SELECT "oauth_applications".* FROM "oauth_applications" WHERE "oauth_applications"."owner_id" = 1 AND "oauth_applications"."owner_type" = 'User' AND "oauth_applications"."id" = 1 LIMIT 1;
 Limit  (cost=0.15..2.17 rows=1 width=237)
   ->  Index Scan using index_oauth_applications_on_owner_id_and_owner_type on oauth_applications  (cost=0.15..2.17 rows=1 width=237)
         Index Cond: ((owner_id = 1) AND ((owner_type)::text = 'User'::text))
         Filter: (id = 1)

2. Create (POST)

EXPLAIN INSERT INTO "oauth_applications" ("name", "uid", "secret", "redirect_uri", "scopes", "created_at", "updated_at", "owner_id", "owner_type", "confidential") VALUES ('test', 'uid', 'secret', 'url', 'api', NOW(), NOW(), 1, 'User', true) RETURNING "id";
 Insert on oauth_applications  (cost=0.00..0.02 rows=1 width=237)
   ->  Result  (cost=0.00..0.02 rows=1 width=237)

3. Update (PUT)

EXPLAIN UPDATE "oauth_applications" SET "name" = 'test2', "updated_at" = NOW() WHERE "oauth_applications"."id" = 1;
 Update on oauth_applications  (cost=0.15..2.17 rows=0 width=0)
   ->  Index Scan using oauth_applications_pkey on oauth_applications  (cost=0.15..2.17 rows=1 width=46)
         Index Cond: (id = 1)

4. Delete (DELETE)

EXPLAIN DELETE FROM "oauth_applications" WHERE "oauth_applications"."id" = 1;
 Delete on oauth_applications  (cost=0.15..2.17 rows=0 width=0)
   ->  Index Scan using oauth_applications_pkey on oauth_applications  (cost=0.15..2.17 rows=1 width=6)
         Index Cond: (id = 1)

References

Screenshots or screen recordings

The API returns standard GitLab API JSON shapes, and correctly provisions the underlying Authn::OauthApplication record associated with the user.

Browser Dev Tools Verification
api_success_verification

How to set up and validate locally

  1. Ensure your GDK is up and running.

  2. Open your browser developer console while authenticated as any user (e.g. root) on the GitLab dashboard.

  3. Execute the following fetch command to provision an application:

    const csrf = document.querySelector('meta[name="csrf-token"]').content;
    fetch('/api/v4/user/applications', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': csrf
      },
      body: JSON.stringify({
        name: 'Browser UI Test App',
        redirect_uri: 'http://localhost/callback',
        scopes: 'api',
        confidential: false
      })
    }).then(r => r.json()).then(console.log);
  4. Verify that the response returns a success with the secret and an application_id.

  5. You can assert the creation of the Application by checking your /-/profile/applications interface.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

tag:gitlab.com,2026-03-15:5205091887 Sijin T V pushed new project branch add-oauth-applications-api at GitLab Community / GitLab.org / GitLab Community Fork 2026-03-15T09:59:16Z sijintv Sijin T V

Sijin T V (2d95327b) at 15 Mar 09:59

Add User Applications REST API