mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 00:22:50 -05:00
Revert filescoped (#2227)
* Revert "Add git blame entry (#2226)" This reverts commit239286737d
. * Revert "Turn on file scoped namespaces (#2225)" This reverts commit34fb4cca2a
.
This commit is contained in:
@ -10,215 +10,216 @@ using Bit.Core.Sso;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
|
||||
namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class OrganizationSsoRequestModel
|
||||
namespace Bit.Api.Models.Request.Organizations
|
||||
{
|
||||
[Required]
|
||||
public bool Enabled { get; set; }
|
||||
[Required]
|
||||
public SsoConfigurationDataRequest Data { get; set; }
|
||||
|
||||
public SsoConfig ToSsoConfig(Guid organizationId)
|
||||
public class OrganizationSsoRequestModel
|
||||
{
|
||||
return ToSsoConfig(new SsoConfig { OrganizationId = organizationId });
|
||||
[Required]
|
||||
public bool Enabled { get; set; }
|
||||
[Required]
|
||||
public SsoConfigurationDataRequest Data { get; set; }
|
||||
|
||||
public SsoConfig ToSsoConfig(Guid organizationId)
|
||||
{
|
||||
return ToSsoConfig(new SsoConfig { OrganizationId = organizationId });
|
||||
}
|
||||
|
||||
public SsoConfig ToSsoConfig(SsoConfig existingConfig)
|
||||
{
|
||||
existingConfig.Enabled = Enabled;
|
||||
var configurationData = Data.ToConfigurationData();
|
||||
existingConfig.SetData(configurationData);
|
||||
return existingConfig;
|
||||
}
|
||||
}
|
||||
|
||||
public SsoConfig ToSsoConfig(SsoConfig existingConfig)
|
||||
public class SsoConfigurationDataRequest : IValidatableObject
|
||||
{
|
||||
existingConfig.Enabled = Enabled;
|
||||
var configurationData = Data.ToConfigurationData();
|
||||
existingConfig.SetData(configurationData);
|
||||
return existingConfig;
|
||||
}
|
||||
}
|
||||
|
||||
public class SsoConfigurationDataRequest : IValidatableObject
|
||||
{
|
||||
public SsoConfigurationDataRequest() { }
|
||||
|
||||
[Required]
|
||||
public SsoType ConfigType { get; set; }
|
||||
|
||||
public bool KeyConnectorEnabled { get; set; }
|
||||
public string KeyConnectorUrl { get; set; }
|
||||
|
||||
// OIDC
|
||||
public string Authority { get; set; }
|
||||
public string ClientId { get; set; }
|
||||
public string ClientSecret { get; set; }
|
||||
public string MetadataAddress { get; set; }
|
||||
public OpenIdConnectRedirectBehavior RedirectBehavior { get; set; }
|
||||
public bool? GetClaimsFromUserInfoEndpoint { get; set; }
|
||||
public string AdditionalScopes { get; set; }
|
||||
public string AdditionalUserIdClaimTypes { get; set; }
|
||||
public string AdditionalEmailClaimTypes { get; set; }
|
||||
public string AdditionalNameClaimTypes { get; set; }
|
||||
public string AcrValues { get; set; }
|
||||
public string ExpectedReturnAcrValue { get; set; }
|
||||
|
||||
// SAML2 SP
|
||||
public Saml2NameIdFormat SpNameIdFormat { get; set; }
|
||||
public string SpOutboundSigningAlgorithm { get; set; }
|
||||
public Saml2SigningBehavior SpSigningBehavior { get; set; }
|
||||
public bool? SpWantAssertionsSigned { get; set; }
|
||||
public bool? SpValidateCertificates { get; set; }
|
||||
public string SpMinIncomingSigningAlgorithm { get; set; }
|
||||
|
||||
// SAML2 IDP
|
||||
public string IdpEntityId { get; set; }
|
||||
public Saml2BindingType IdpBindingType { get; set; }
|
||||
public string IdpSingleSignOnServiceUrl { get; set; }
|
||||
public string IdpSingleLogoutServiceUrl { get; set; }
|
||||
public string IdpArtifactResolutionServiceUrl { get => null; set { /*IGNORE*/ } }
|
||||
public string IdpX509PublicCert { get; set; }
|
||||
public string IdpOutboundSigningAlgorithm { get; set; }
|
||||
public bool? IdpAllowUnsolicitedAuthnResponse { get; set; }
|
||||
public bool? IdpDisableOutboundLogoutRequests { get; set; }
|
||||
public bool? IdpWantAuthnRequestsSigned { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext context)
|
||||
{
|
||||
var i18nService = context.GetService(typeof(II18nService)) as I18nService;
|
||||
|
||||
if (ConfigType == SsoType.OpenIdConnect)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Authority))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("AuthorityValidationError"),
|
||||
new[] { nameof(Authority) });
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ClientId))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("ClientIdValidationError"),
|
||||
new[] { nameof(ClientId) });
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ClientSecret))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("ClientSecretValidationError"),
|
||||
new[] { nameof(ClientSecret) });
|
||||
}
|
||||
}
|
||||
else if (ConfigType == SsoType.Saml2)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(IdpEntityId))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpEntityIdValidationError"),
|
||||
new[] { nameof(IdpEntityId) });
|
||||
}
|
||||
|
||||
if (!Uri.IsWellFormedUriString(IdpEntityId, UriKind.Absolute) && string.IsNullOrWhiteSpace(IdpSingleSignOnServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlValidationError"),
|
||||
new[] { nameof(IdpSingleSignOnServiceUrl) });
|
||||
}
|
||||
|
||||
if (InvalidServiceUrl(IdpSingleSignOnServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlInvalid"),
|
||||
new[] { nameof(IdpSingleSignOnServiceUrl) });
|
||||
}
|
||||
|
||||
if (InvalidServiceUrl(IdpSingleLogoutServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleLogoutServiceUrlInvalid"),
|
||||
new[] { nameof(IdpSingleLogoutServiceUrl) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(IdpX509PublicCert))
|
||||
{
|
||||
// Validate the certificate is in a valid format
|
||||
ValidationResult failedResult = null;
|
||||
try
|
||||
{
|
||||
var certData = CoreHelpers.Base64UrlDecode(StripPemCertificateElements(IdpX509PublicCert));
|
||||
new X509Certificate2(certData);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertInvalidFormatValidationError"),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
catch (CryptographicException cryptoEx)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertCryptographicExceptionValidationError", cryptoEx.Message),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertValidationError", ex.Message),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
if (failedResult != null)
|
||||
{
|
||||
yield return failedResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SsoConfigurationData ToConfigurationData()
|
||||
{
|
||||
return new SsoConfigurationData
|
||||
{
|
||||
ConfigType = ConfigType,
|
||||
KeyConnectorEnabled = KeyConnectorEnabled,
|
||||
KeyConnectorUrl = KeyConnectorUrl,
|
||||
Authority = Authority,
|
||||
ClientId = ClientId,
|
||||
ClientSecret = ClientSecret,
|
||||
MetadataAddress = MetadataAddress,
|
||||
GetClaimsFromUserInfoEndpoint = GetClaimsFromUserInfoEndpoint.GetValueOrDefault(),
|
||||
RedirectBehavior = RedirectBehavior,
|
||||
IdpEntityId = IdpEntityId,
|
||||
IdpBindingType = IdpBindingType,
|
||||
IdpSingleSignOnServiceUrl = IdpSingleSignOnServiceUrl,
|
||||
IdpSingleLogoutServiceUrl = IdpSingleLogoutServiceUrl,
|
||||
IdpArtifactResolutionServiceUrl = null,
|
||||
IdpX509PublicCert = StripPemCertificateElements(IdpX509PublicCert),
|
||||
IdpOutboundSigningAlgorithm = IdpOutboundSigningAlgorithm,
|
||||
IdpAllowUnsolicitedAuthnResponse = IdpAllowUnsolicitedAuthnResponse.GetValueOrDefault(),
|
||||
IdpDisableOutboundLogoutRequests = IdpDisableOutboundLogoutRequests.GetValueOrDefault(),
|
||||
IdpWantAuthnRequestsSigned = IdpWantAuthnRequestsSigned.GetValueOrDefault(),
|
||||
SpNameIdFormat = SpNameIdFormat,
|
||||
SpOutboundSigningAlgorithm = SpOutboundSigningAlgorithm ?? SamlSigningAlgorithms.Sha256,
|
||||
SpSigningBehavior = SpSigningBehavior,
|
||||
SpWantAssertionsSigned = SpWantAssertionsSigned.GetValueOrDefault(),
|
||||
SpValidateCertificates = SpValidateCertificates.GetValueOrDefault(),
|
||||
SpMinIncomingSigningAlgorithm = SpMinIncomingSigningAlgorithm,
|
||||
AdditionalScopes = AdditionalScopes,
|
||||
AdditionalUserIdClaimTypes = AdditionalUserIdClaimTypes,
|
||||
AdditionalEmailClaimTypes = AdditionalEmailClaimTypes,
|
||||
AdditionalNameClaimTypes = AdditionalNameClaimTypes,
|
||||
AcrValues = AcrValues,
|
||||
ExpectedReturnAcrValue = ExpectedReturnAcrValue,
|
||||
};
|
||||
}
|
||||
|
||||
private string StripPemCertificateElements(string certificateText)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(certificateText))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return Regex.Replace(certificateText,
|
||||
@"(((BEGIN|END) CERTIFICATE)|([\-\n\r\t\s\f]))",
|
||||
string.Empty,
|
||||
RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
||||
}
|
||||
|
||||
private bool InvalidServiceUrl(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!url.StartsWith("http://") && !url.StartsWith("https://"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return Regex.IsMatch(url, "[<>\"]");
|
||||
public SsoConfigurationDataRequest() { }
|
||||
|
||||
[Required]
|
||||
public SsoType ConfigType { get; set; }
|
||||
|
||||
public bool KeyConnectorEnabled { get; set; }
|
||||
public string KeyConnectorUrl { get; set; }
|
||||
|
||||
// OIDC
|
||||
public string Authority { get; set; }
|
||||
public string ClientId { get; set; }
|
||||
public string ClientSecret { get; set; }
|
||||
public string MetadataAddress { get; set; }
|
||||
public OpenIdConnectRedirectBehavior RedirectBehavior { get; set; }
|
||||
public bool? GetClaimsFromUserInfoEndpoint { get; set; }
|
||||
public string AdditionalScopes { get; set; }
|
||||
public string AdditionalUserIdClaimTypes { get; set; }
|
||||
public string AdditionalEmailClaimTypes { get; set; }
|
||||
public string AdditionalNameClaimTypes { get; set; }
|
||||
public string AcrValues { get; set; }
|
||||
public string ExpectedReturnAcrValue { get; set; }
|
||||
|
||||
// SAML2 SP
|
||||
public Saml2NameIdFormat SpNameIdFormat { get; set; }
|
||||
public string SpOutboundSigningAlgorithm { get; set; }
|
||||
public Saml2SigningBehavior SpSigningBehavior { get; set; }
|
||||
public bool? SpWantAssertionsSigned { get; set; }
|
||||
public bool? SpValidateCertificates { get; set; }
|
||||
public string SpMinIncomingSigningAlgorithm { get; set; }
|
||||
|
||||
// SAML2 IDP
|
||||
public string IdpEntityId { get; set; }
|
||||
public Saml2BindingType IdpBindingType { get; set; }
|
||||
public string IdpSingleSignOnServiceUrl { get; set; }
|
||||
public string IdpSingleLogoutServiceUrl { get; set; }
|
||||
public string IdpArtifactResolutionServiceUrl { get => null; set { /*IGNORE*/ } }
|
||||
public string IdpX509PublicCert { get; set; }
|
||||
public string IdpOutboundSigningAlgorithm { get; set; }
|
||||
public bool? IdpAllowUnsolicitedAuthnResponse { get; set; }
|
||||
public bool? IdpDisableOutboundLogoutRequests { get; set; }
|
||||
public bool? IdpWantAuthnRequestsSigned { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext context)
|
||||
{
|
||||
var i18nService = context.GetService(typeof(II18nService)) as I18nService;
|
||||
|
||||
if (ConfigType == SsoType.OpenIdConnect)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Authority))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("AuthorityValidationError"),
|
||||
new[] { nameof(Authority) });
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ClientId))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("ClientIdValidationError"),
|
||||
new[] { nameof(ClientId) });
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ClientSecret))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("ClientSecretValidationError"),
|
||||
new[] { nameof(ClientSecret) });
|
||||
}
|
||||
}
|
||||
else if (ConfigType == SsoType.Saml2)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(IdpEntityId))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpEntityIdValidationError"),
|
||||
new[] { nameof(IdpEntityId) });
|
||||
}
|
||||
|
||||
if (!Uri.IsWellFormedUriString(IdpEntityId, UriKind.Absolute) && string.IsNullOrWhiteSpace(IdpSingleSignOnServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlValidationError"),
|
||||
new[] { nameof(IdpSingleSignOnServiceUrl) });
|
||||
}
|
||||
|
||||
if (InvalidServiceUrl(IdpSingleSignOnServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlInvalid"),
|
||||
new[] { nameof(IdpSingleSignOnServiceUrl) });
|
||||
}
|
||||
|
||||
if (InvalidServiceUrl(IdpSingleLogoutServiceUrl))
|
||||
{
|
||||
yield return new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleLogoutServiceUrlInvalid"),
|
||||
new[] { nameof(IdpSingleLogoutServiceUrl) });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(IdpX509PublicCert))
|
||||
{
|
||||
// Validate the certificate is in a valid format
|
||||
ValidationResult failedResult = null;
|
||||
try
|
||||
{
|
||||
var certData = CoreHelpers.Base64UrlDecode(StripPemCertificateElements(IdpX509PublicCert));
|
||||
new X509Certificate2(certData);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertInvalidFormatValidationError"),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
catch (CryptographicException cryptoEx)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertCryptographicExceptionValidationError", cryptoEx.Message),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertValidationError", ex.Message),
|
||||
new[] { nameof(IdpX509PublicCert) });
|
||||
}
|
||||
if (failedResult != null)
|
||||
{
|
||||
yield return failedResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SsoConfigurationData ToConfigurationData()
|
||||
{
|
||||
return new SsoConfigurationData
|
||||
{
|
||||
ConfigType = ConfigType,
|
||||
KeyConnectorEnabled = KeyConnectorEnabled,
|
||||
KeyConnectorUrl = KeyConnectorUrl,
|
||||
Authority = Authority,
|
||||
ClientId = ClientId,
|
||||
ClientSecret = ClientSecret,
|
||||
MetadataAddress = MetadataAddress,
|
||||
GetClaimsFromUserInfoEndpoint = GetClaimsFromUserInfoEndpoint.GetValueOrDefault(),
|
||||
RedirectBehavior = RedirectBehavior,
|
||||
IdpEntityId = IdpEntityId,
|
||||
IdpBindingType = IdpBindingType,
|
||||
IdpSingleSignOnServiceUrl = IdpSingleSignOnServiceUrl,
|
||||
IdpSingleLogoutServiceUrl = IdpSingleLogoutServiceUrl,
|
||||
IdpArtifactResolutionServiceUrl = null,
|
||||
IdpX509PublicCert = StripPemCertificateElements(IdpX509PublicCert),
|
||||
IdpOutboundSigningAlgorithm = IdpOutboundSigningAlgorithm,
|
||||
IdpAllowUnsolicitedAuthnResponse = IdpAllowUnsolicitedAuthnResponse.GetValueOrDefault(),
|
||||
IdpDisableOutboundLogoutRequests = IdpDisableOutboundLogoutRequests.GetValueOrDefault(),
|
||||
IdpWantAuthnRequestsSigned = IdpWantAuthnRequestsSigned.GetValueOrDefault(),
|
||||
SpNameIdFormat = SpNameIdFormat,
|
||||
SpOutboundSigningAlgorithm = SpOutboundSigningAlgorithm ?? SamlSigningAlgorithms.Sha256,
|
||||
SpSigningBehavior = SpSigningBehavior,
|
||||
SpWantAssertionsSigned = SpWantAssertionsSigned.GetValueOrDefault(),
|
||||
SpValidateCertificates = SpValidateCertificates.GetValueOrDefault(),
|
||||
SpMinIncomingSigningAlgorithm = SpMinIncomingSigningAlgorithm,
|
||||
AdditionalScopes = AdditionalScopes,
|
||||
AdditionalUserIdClaimTypes = AdditionalUserIdClaimTypes,
|
||||
AdditionalEmailClaimTypes = AdditionalEmailClaimTypes,
|
||||
AdditionalNameClaimTypes = AdditionalNameClaimTypes,
|
||||
AcrValues = AcrValues,
|
||||
ExpectedReturnAcrValue = ExpectedReturnAcrValue,
|
||||
};
|
||||
}
|
||||
|
||||
private string StripPemCertificateElements(string certificateText)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(certificateText))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return Regex.Replace(certificateText,
|
||||
@"(((BEGIN|END) CERTIFICATE)|([\-\n\r\t\s\f]))",
|
||||
string.Empty,
|
||||
RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
||||
}
|
||||
|
||||
private bool InvalidServiceUrl(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!url.StartsWith("http://") && !url.StartsWith("https://"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return Regex.IsMatch(url, "[<>\"]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user