Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage Health Check: Check for presence of an OIDC IdP #17884

Merged
merged 3 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,26 @@ def validate

private

def sso_misconfigured
return None() unless @storage.authenticate_via_idp?

openid_connect_idp_absent
end

def openid_connect_idp_absent
return None() if OpenIDConnect::Provider.any?

Some(ConnectionValidation.new(type: :error,
error_code: :oidc_provider_missing,
timestamp: Time.current,
description: I18n.t("storages.health.connection_validation.oidc_provider_missing")))
end

def has_base_configuration_error?
host_url_not_found
.or { missing_dependencies }
.or { version_mismatch }
.or { sso_misconfigured }
.or { with_unexpected_content }
.or { capabilities_request_failed_with_unknown_error }
end
Expand Down
1 change: 1 addition & 0 deletions modules/storages/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ en:
host_not_found: No Nextcloud server found at the configured host url. Please check the configuration.
missing_dependencies: 'A required dependency is missing on the file storage. Please add the following dependency: %{dependency}.'
not_configured: The connection could not be validated. Please finish configuration first.
oidc_provider_missing: There is no OpenID Connect Identity Provider configured.
placeholder: Check your connection against the server.
subtitle: Connection validation
tenant_id_wrong: The configured directory (tenant) id is invalid. Please check the configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,31 @@
end
end

context "when OpenID Connect is enabled" do
let(:storage) { create(:nextcloud_storage_configured, :oidc_enabled) }
let(:app_version) { Storages::SemanticVersion.parse("2.6.3") }
let(:capabilities_response) do
ServiceResult.success(result: Storages::NextcloudCapabilities.new(
app_enabled?: true,
app_version:,
group_folder_enabled?: false,
group_folder_version: nil
))
end

it "succeeds when a provider is available" do
create(:oidc_provider)

expect(subject.type).to eq(:healthy)
end

it "errors if no Provider is available" do
mereghost marked this conversation as resolved.
Show resolved Hide resolved
expect(subject.type).to eq(:error)
expect(subject.error_code).to eq(:oidc_provider_missing)
expect(subject.description).to eq(I18n.t("storages.health.connection_validation.oidc_provider_missing"))
end
end

private

def build_failure(code:, payload:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@
context "when the authentication method is oauth2_sso" do
let(:authentication_method) { "oauth2_sso" }

before { storage.nextcloud_audience = "valid_audience" }

it { is_expected.to be_valid }
end

Expand Down
7 changes: 6 additions & 1 deletion modules/storages/spec/factories/storage_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,12 @@
provider_type { Storages::Storage::PROVIDER_TYPE_NEXTCLOUD }
sequence(:host) { |n| "https://host#{n}.example.com/" }
authentication_method { "two_way_oauth2" }
nextcloud_audience { "nextcloud" }
nextcloud_audience { nil }

trait :oidc_enabled do
Copy link
Contributor

Choose a reason for hiding this comment

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

🟢 Naming nit: I'd repeat the sso terminology here, especially since the authentication method does not try to imply OIDC

Suggested change
trait :oidc_enabled do
trait :sso_authentication do
Suggested change
trait :oidc_enabled do
trait :sso_enabled do

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmmmmm... I'm starting to wonder if going with SSO won't be a mistake as we have other SSO solutions supported on OpenProject, like SAML.

Copy link
Contributor

Choose a reason for hiding this comment

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

To be fair, that's why it was called oauth2_sso and not sso alone :D

I see what you mean, but right now it sounds as likely to me that adding OIDC to names is a mistake, as it could be that dropping OIDC is a mistake.

I.e. the implementation could develop to be super duper tightly coupled to OIDC and we'd need to do something entirely different for SAML. Or the implementation develops in a direction where the storage just cares about the thing being "some kind of SSO", but which kind exactly is not important.

Right now we don't know, so we only guess which name will be better. I am mostly advocating for having the term "SSO" included, because the distinguishing factor between the solutions we have today, is that one is SSO and the other is not SSO. Whether or not we qualify the term "SSO" with OIDC, I have less strong feelings about, because we don't know how that will develop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

audience and authentication_method are already pretty tied to OIDC as is implementation wise and we have no plans in the short/medium term of supporting anything else than OIDC for this.

We could even extend this trait to supply a OpenIDConnect::Provider (which I think I'll need down the line).

Copy link
Contributor

Choose a reason for hiding this comment

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

oidc_sso_enabled?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. I'll change it on the next PR unless this CI run fails. XD

nextcloud_audience { "nextcloud" }
authentication_method { "oauth2_sso" }
end

trait :as_automatically_managed do
automatic_management_enabled { true }
Expand Down