Global organization route prefix
What does this MR do and why?
This MR will dynamically route any path received with a URL path of /o/my-org/<some-path> to a path of <some-path>. The X-Gitlab-Organization-ID header will be set as the ID of the Organization with the matching my-org path.
This work is essentially behind the organization_scoped_paths feature flag which dictates the value returned by some_organization.scoped_paths?.
Until this MR all Organization scoped routes had to be manually added to config/routes/organizations.rb. With this MR, we create a catch all style route to avoid the need for manual routes. For the sake of keeping this MR smaller, existing manual routes will be removed in a follow up as they are using organization_* URL helpers that need to be replace by their global counter parts. E.g. organization_projects_path goes to projects_path.
The request flow starts at the Organization catch all route and is passed to !209311 (diffs).
We introduce lib/gitlab/middleware/organization_routing.rb which is the core of this MR. Our catch all route directs requests to this class. The class does two key things:
- Set the
HTTP_X_GITLAB_ORGANIZATION_IDheader from the organization path in/o/my-org-path/.... This defines the Organization context for the request. - Determine the appropriate controller/action to call within
dispatch_with_organization_context. We do this by setting the URL path to the non-scoped path, e.g./o/my-org/projectsto/projectsand then ask the Rails routes to return the endpoint.
A facility to capture requests made in specs was added with spec/support/shared_contexts/http_request_capture.rb. This was created to support spec/support/shared_contexts/current_organization_context.rb which aligns scoped URL helpers in specs with the URL helpers used by the response generating code. Otherwise URL helpers will operate in different Organization contexts.
There's a collection of miscellaneous changes:
- We had to replace hard coded paths with URL helpers so we could intercept the calls and scope the path appropriately.
- We remove
:with_organization_url_helpersmetadata from specs because we blanket install these in !209311 (diffs). These helpers ensure that Organization scoped helpers (viaapp/helpers/routing/organizations_helper.rb) operate the same way in both the code and specs by ensuringCurrent.organizationis set appropriately. - Removed spec contexts related to
'when current Organization does not have scoped paths'because we spec the URL helpers separately, and in other specs we simply test for path equivalence over specific path values.
References
- Current Organization context
- Organization path scope
- Organization context resolution
- Organizations blueprint
How to set up and validate locally
You will need to enable the following feature flags:
Feature.enable :organization_switching
Feature.enable :ui_for_organizations
Feature.enable :organization_scoped_paths
Then create an Organization via the + menu item.
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.