diff --git a/src/Sql/Sql/ChangeLog.md b/src/Sql/Sql/ChangeLog.md index 3423013a399d..f694251715cb 100644 --- a/src/Sql/Sql/ChangeLog.md +++ b/src/Sql/Sql/ChangeLog.md @@ -29,6 +29,7 @@ - `Disable-AzSqlInstanceDatabaseSensitivityRecommendation` * Removed client-side validation of 'RetentionDays' parameter from cmdlet `Set-AzSqlDatabaseBackupShortTermRetentionPolicy` * Auditing to a storage account in Vnet, fixing a bug when creating a Storage Blob Data Contributor role. +* Allow Azure Active Directory applications to be set as SQL Server Azure Active Directory admin. ## Version 2.6.0 * Added cmdlets `Get-AzSqlInstanceOperation` and `Stop-AzSqlInstanceOperation` diff --git a/src/Sql/Sql/Properties/Resources.Designer.cs b/src/Sql/Sql/Properties/Resources.Designer.cs index 20786e1127aa..fc40503d5aa4 100644 --- a/src/Sql/Sql/Properties/Resources.Designer.cs +++ b/src/Sql/Sql/Properties/Resources.Designer.cs @@ -60,6 +60,24 @@ internal Resources() { } } + /// + /// Looks up a localized string similar to Azure Active Directory application with the display name '{0}' was found. Display Name provided does not match with application display name '{1}'. Please provide right display name that names with display name of the application. To get the application id use Get-AzADApplication -SearchString "{0}" or Get-AzADApplication -SearchString "{1}".. + /// + internal static string ADApplicationDisplayNameMismatch { + get { + return ResourceManager.GetString("ADApplicationDisplayNameMismatch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to More than one Azure Active Directory application with the display name '{0}' was found. Please provide an Azure Active Directory application id of the application to select the correct application. To get the application id use Get-AzADApplication -SearchString "{0}". + /// + internal static string ADApplicationMoreThanOneFound { + get { + return ResourceManager.GetString("ADApplicationMoreThanOneFound", resourceCulture); + } + } + /// /// Looks up a localized string similar to Adding Storage Blob Data Contributor role for storage account {0} is forbidden. /// @@ -69,6 +87,15 @@ internal static string AddingStorageBlobDataContributorRoleForStorageAccountIsFo } } + /// + /// Looks up a localized string similar to Azure Active Directory application and group with same display name '{0}' was found. Please provide an Azure Active Directory application id of the application or object id of the group to select the correct application. To get the application id use Get-AzADApplication -SearchString "{0}" or to get object id use Get-AzADGroup -SearchString "{0}".. + /// + internal static string ADDuplicateGroupAndApplicationFound { + get { + return ResourceManager.GetString("ADDuplicateGroupAndApplicationFound", resourceCulture); + } + } + /// /// Looks up a localized string similar to More than one Active Directory group with the display name '{0}' was found. Please provide an Azure Active Directory object id to select the correct group. To get the object id use Get-AzADGroup -SearchString "{0}". /// @@ -79,7 +106,7 @@ internal static string ADGroupMoreThanOneFound { } /// - /// Looks up a localized string similar to Cannot find the Azure Active Directory object '{0}'. Please make sure that the user or group you are authorizing is registered in the current subscription's Azure Active directory. To get a list of Azure Active Directory groups use Get-AzADGroup, or to get a list of Azure Active Directory users use Get-AzADUser.. + /// Looks up a localized string similar to Cannot find the Azure Active Directory object '{0}'. Please make sure that the user or group or application you are authorizing is registered in the current subscription's Azure Active directory. To get a list of Azure Active Directory groups use Get-AzADGroup, or to get a list of Azure Active Directory users use Get-AzADUser or to get a list of Azure Active Directory applications use Get-AzADApplication.. /// internal static string ADObjectNotFound { get { diff --git a/src/Sql/Sql/Properties/Resources.resx b/src/Sql/Sql/Properties/Resources.resx index 82c753b04ee6..a115f7681c2d 100644 --- a/src/Sql/Sql/Properties/Resources.resx +++ b/src/Sql/Sql/Properties/Resources.resx @@ -121,11 +121,20 @@ More than one Active Directory group with the display name '{0}' was found. Please provide an Azure Active Directory object id to select the correct group. To get the object id use Get-AzADGroup -SearchString "{0}" - Cannot find the Azure Active Directory object '{0}'. Please make sure that the user or group you are authorizing is registered in the current subscription's Azure Active directory. To get a list of Azure Active Directory groups use Get-AzADGroup, or to get a list of Azure Active Directory users use Get-AzADUser. + Cannot find the Azure Active Directory object '{0}'. Please make sure that the user or group or application you are authorizing is registered in the current subscription's Azure Active directory. To get a list of Azure Active Directory groups use Get-AzADGroup, or to get a list of Azure Active Directory users use Get-AzADUser or to get a list of Azure Active Directory applications use Get-AzADApplication. More than one Azure Active Directory user with the display name '{0}' was found. Please provide an Azure Active Directory object id to select the correct user. To get the object id use Get-AzADUser -SearchString "{0}" + + More than one Azure Active Directory application with the display name '{0}' was found. Please provide an Azure Active Directory application id of the application to select the correct application. To get the application id use Get-AzADApplication -SearchString "{0}" + + + Azure Active Directory application with the display name '{0}' was found. Display Name provided does not match with application display name '{1}'. Please provide right display name that names with display name of the application. To get the application id use Get-AzADApplication -SearchString "{0}" or Get-AzADApplication -SearchString "{1}". + + + Azure Active Directory application and group with same display name '{0}' was found. Please provide an Azure Active Directory application id of the application or object id of the group to select the correct application. To get the application id use Get-AzADApplication -SearchString "{0}" or to get object id use Get-AzADGroup -SearchString "{0}". + Database with name: '{0}' already exists in server '{1}'. diff --git a/src/Sql/Sql/ServerActiveDirectoryAdministrator/Services/AzureSqlServerActiveDirectoryAdministratorAdapter.cs b/src/Sql/Sql/ServerActiveDirectoryAdministrator/Services/AzureSqlServerActiveDirectoryAdministratorAdapter.cs index d3dafde0de59..c0beba0e34e7 100644 --- a/src/Sql/Sql/ServerActiveDirectoryAdministrator/Services/AzureSqlServerActiveDirectoryAdministratorAdapter.cs +++ b/src/Sql/Sql/ServerActiveDirectoryAdministrator/Services/AzureSqlServerActiveDirectoryAdministratorAdapter.cs @@ -16,6 +16,8 @@ using Microsoft.Azure.Commands.Sql.ServerActiveDirectoryAdministrator.Model; using Microsoft.Azure.Management.Sql.Models; using Microsoft.Azure.Graph.RBAC.Version1_6.ActiveDirectory; +using Microsoft.Azure.Graph.RBAC.Version1_6.Models; +using Microsoft.Rest.Azure.OData; using System; using System.Collections.Generic; using System.Linq; @@ -178,8 +180,9 @@ protected ServerAzureADAdministrator GetActiveDirectoryInformation(string displa // Check for a Azure Active Directory group. Recommended to always use group. IEnumerable groupList = null; + PSADGroup group = null; - var filter = new ADObjectFilterOptions() + var filter = new ADObjectFilterOptions() { Id = (objectId != null && objectId != Guid.Empty) ? objectId.ToString() : null, SearchString = displayName, @@ -197,15 +200,66 @@ protected ServerAzureADAdministrator GetActiveDirectoryInformation(string displa else if (groupList.Count() == 1) { // Only one group was found. Get the group display name and object id - var group = groupList.First(); + group = groupList.First(); // Only support Security Groups if (group.SecurityEnabled.HasValue && !group.SecurityEnabled.Value) { throw new ArgumentException(string.Format(Microsoft.Azure.Commands.Sql.Properties.Resources.InvalidADGroupNotSecurity, displayName)); } + } + + // Lookup for applications + ODataQuery odataQueryFilter; + + if ((objectId != null && objectId != Guid.Empty)) + { + var applicationIdString = objectId.ToString(); + odataQueryFilter = new Rest.Azure.OData.ODataQuery(a => a.AppId == applicationIdString); + } + else + { + odataQueryFilter = new Rest.Azure.OData.ODataQuery(a => a.DisplayName == displayName); + } + var applicationList = ActiveDirectoryClient.GetApplicationWithFilters(odataQueryFilter); + + // No application was found + if (applicationList == null || applicationList.Count() == 0) + { + throw new ArgumentException(string.Format(Microsoft.Azure.Commands.Sql.Properties.Resources.ADObjectNotFound, displayName)); + } + else if (applicationList.Count() > 1) + { + // More than one application was found. + throw new ArgumentException(string.Format(Microsoft.Azure.Commands.Sql.Properties.Resources.ADApplicationMoreThanOneFound, displayName)); + } + else if (applicationList.Count() == 1) + { + // Only one user was found. Get the user display name and object id + PSADApplication app = applicationList.First(); + if (displayName != null && string.CompareOrdinal(displayName, app.DisplayName) != 0) + { + throw new ArgumentException(string.Format(Microsoft.Azure.Commands.Sql.Properties.Resources.ADApplicationDisplayNameMismatch, displayName, app.DisplayName)); + } + + if (group != null) + { + throw new ArgumentException(string.Format(Microsoft.Azure.Commands.Sql.Properties.Resources.ADDuplicateGroupAndApplicationFound, displayName)); + } + + return new ServerAzureADAdministrator() + { + Login = displayName, + Sid = app.ApplicationId, + TenantId = tenantId, + AzureADOnlyAuthentication = isAzureADOnlyAuthentication, + }; + } + + if (group != null) + { return new ServerAzureADAdministrator() { Login = group.DisplayName, @@ -215,7 +269,7 @@ protected ServerAzureADAdministrator GetActiveDirectoryInformation(string displa }; } - // No group was found. Check for a user + // No group or application was found. Check for a user filter = new ADObjectFilterOptions() { Id = (objectId != null && objectId != Guid.Empty) ? objectId.ToString() : null, @@ -284,4 +338,4 @@ protected Guid GetTenantId() return tenantIdGuid; } } -} +} \ No newline at end of file