From 34544f229286be319ab6e7dba595f2c1e66e67ee Mon Sep 17 00:00:00 2001
From: SmithThe4th <gsmith@bitwarden.com>
Date: Fri, 17 Feb 2023 13:19:21 -0500
Subject: [PATCH] [SG-1082]-Defect-Update stored procedure to properly
 determine is SSO is available (#2715)

* Fixed SsoAvailble bug by using the enabled column from SsoConfig table, updated the existing query for EF Core

* Added no tracking to ef query since it is read only
---
 .../OrganizationDomainSsoDetailsData.cs       |  2 +-
 .../OrganizationDomainRepository.cs           | 45 ++++++++-----------
 ...ganizationDomainSsoDetails_ReadByEmail.sql |  4 +-
 ...2-16_FixSsoAvailableOrganizationDomain.sql | 31 +++++++++++++
 4 files changed, 54 insertions(+), 28 deletions(-)
 create mode 100644 util/Migrator/DbScripts/2023-02-16_FixSsoAvailableOrganizationDomain.sql

diff --git a/src/Core/Models/Data/Organizations/OrganizationDomainSsoDetailsData.cs b/src/Core/Models/Data/Organizations/OrganizationDomainSsoDetailsData.cs
index 66b6081f1d..1a87db792e 100644
--- a/src/Core/Models/Data/Organizations/OrganizationDomainSsoDetailsData.cs
+++ b/src/Core/Models/Data/Organizations/OrganizationDomainSsoDetailsData.cs
@@ -10,7 +10,7 @@ public class OrganizationDomainSsoDetailsData
     public bool SsoAvailable { get; set; }
     public string OrganizationIdentifier { get; set; }
     public bool SsoRequired { get; set; }
-    public PolicyType PolicyType { get; set; }
+    public PolicyType? PolicyType { get; set; }
     public DateTime? VerifiedDate { get; set; }
     public bool OrganizationEnabled { get; set; }
 }
diff --git a/src/Infrastructure.EntityFramework/Repositories/OrganizationDomainRepository.cs b/src/Infrastructure.EntityFramework/Repositories/OrganizationDomainRepository.cs
index daafd7c958..1f3cd375e5 100644
--- a/src/Infrastructure.EntityFramework/Repositories/OrganizationDomainRepository.cs
+++ b/src/Infrastructure.EntityFramework/Repositories/OrganizationDomainRepository.cs
@@ -74,32 +74,25 @@ public class OrganizationDomainRepository : Repository<Core.Entities.Organizatio
 
         using var scope = ServiceScopeFactory.CreateScope();
         var dbContext = GetDatabaseContext(scope);
-        var ssoDetails = await dbContext.Organizations
-            .Join(dbContext.OrganizationDomains, o => o.Id, od => od.OrganizationId,
-                (organization, domain) => new { resOrganization = organization, resDomain = domain })
-            .Join(dbContext.Policies, o => o.resOrganization.Id, p => p.OrganizationId,
-                (combinedOrgDomain, policy)
-                    => new
-                    {
-                        Organization = combinedOrgDomain.resOrganization,
-                        Domain = combinedOrgDomain.resDomain,
-                        Policy = policy
-                    })
-            .Select(x => new OrganizationDomainSsoDetailsData
-            {
-                OrganizationId = x.Organization.Id,
-                OrganizationName = x.Organization.Name,
-                SsoAvailable = x.Organization.UseSso,
-                OrganizationIdentifier = x.Organization.Identifier,
-                SsoRequired = x.Policy.Enabled,
-                VerifiedDate = x.Domain.VerifiedDate,
-                PolicyType = x.Policy.Type,
-                DomainName = x.Domain.DomainName,
-                OrganizationEnabled = x.Organization.Enabled
-            })
-            .Where(y => y.DomainName == domainName
-                        && y.OrganizationEnabled == true
-                        && y.PolicyType.Equals(PolicyType.RequireSso))
+        var ssoDetails = await (from o in dbContext.Organizations
+                                from od in o.Domains
+                                join s in dbContext.SsoConfigs on o.Id equals s.OrganizationId into sJoin
+                                from s in sJoin.DefaultIfEmpty()
+                                join p in dbContext.Policies.Where(p => p.Type == PolicyType.RequireSso) on o.Id
+                                    equals p.OrganizationId into pJoin
+                                from p in pJoin.DefaultIfEmpty()
+                                where od.DomainName == domainName && o.Enabled
+                                select new OrganizationDomainSsoDetailsData
+                                {
+                                    OrganizationId = o.Id,
+                                    OrganizationName = o.Name,
+                                    SsoAvailable = o.SsoConfigs.Any(sc => sc.Enabled),
+                                    SsoRequired = p != null && p.Enabled,
+                                    OrganizationIdentifier = o.Identifier,
+                                    VerifiedDate = od.VerifiedDate,
+                                    PolicyType = p.Type,
+                                    DomainName = od.DomainName
+                                })
             .AsNoTracking()
             .SingleOrDefaultAsync();
 
diff --git a/src/Sql/dbo/Stored Procedures/OrganizationDomainSsoDetails_ReadByEmail.sql b/src/Sql/dbo/Stored Procedures/OrganizationDomainSsoDetails_ReadByEmail.sql
index 0a2964d655..b1e4ae7679 100644
--- a/src/Sql/dbo/Stored Procedures/OrganizationDomainSsoDetails_ReadByEmail.sql	
+++ b/src/Sql/dbo/Stored Procedures/OrganizationDomainSsoDetails_ReadByEmail.sql	
@@ -11,7 +11,7 @@ BEGIN
     SELECT
         O.Id AS OrganizationId,
         O.[Name] AS OrganizationName,
-        O.UseSso AS SsoAvailable,
+        S.Enabled AS SsoAvailable,
         P.Enabled AS SsoRequired,
         O.Identifier AS OrganizationIdentifier,
         OD.VerifiedDate,
@@ -23,6 +23,8 @@ BEGIN
         ON O.Id = OD.OrganizationId
     LEFT JOIN [dbo].[PolicyView] P
         ON O.Id = P.OrganizationId
+    LEFT JOIN [dbo].[Ssoconfig] S
+        ON O.Id = S.OrganizationId
     WHERE OD.DomainName = @Domain
     AND O.Enabled = 1
     AND (P.Id is NULL OR (P.Id IS NOT NULL AND P.[Type] = 4)) -- SSO Type
diff --git a/util/Migrator/DbScripts/2023-02-16_FixSsoAvailableOrganizationDomain.sql b/util/Migrator/DbScripts/2023-02-16_FixSsoAvailableOrganizationDomain.sql
new file mode 100644
index 0000000000..97a9a227a8
--- /dev/null
+++ b/util/Migrator/DbScripts/2023-02-16_FixSsoAvailableOrganizationDomain.sql
@@ -0,0 +1,31 @@
+CREATE OR ALTER PROCEDURE [dbo].[OrganizationDomainSsoDetails_ReadByEmail]
+    @Email NVARCHAR(256)
+AS
+BEGIN
+    SET NOCOUNT ON
+        
+    DECLARE @Domain NVARCHAR(256)
+
+SELECT @Domain = SUBSTRING(@Email, CHARINDEX( '@', @Email) + 1, LEN(@Email))
+
+SELECT
+    O.Id AS OrganizationId,
+    O.[Name] AS OrganizationName,
+    S.Enabled AS SsoAvailable,
+    P.Enabled AS SsoRequired,
+    O.Identifier AS OrganizationIdentifier,
+    OD.VerifiedDate,
+    P.[Type] AS PolicyType,
+    OD.DomainName
+FROM
+    [dbo].[OrganizationView] O
+    INNER JOIN [dbo].[OrganizationDomainView] OD
+ON O.Id = OD.OrganizationId
+    LEFT JOIN [dbo].[PolicyView] P
+    ON O.Id = P.OrganizationId
+    LEFT JOIN [dbo].[Ssoconfig] S
+    ON O.Id = S.OrganizationId
+WHERE OD.DomainName = @Domain
+  AND O.Enabled = 1
+  AND (P.Id is NULL OR (P.Id IS NOT NULL AND P.[Type] = 4)) -- SSO Type
+END    
\ No newline at end of file