Add securable search and permission setting to User Management (#2052)

This commit is contained in:
Hai Cao
2023-05-10 18:20:06 -07:00
committed by GitHub
parent c5bc4ebc92
commit d525e88672
38 changed files with 2981 additions and 168 deletions

View File

@@ -9877,6 +9877,582 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
public static string objectType_functionTable_plural
{
get
{
return Keys.GetString(Keys.objectType_functionTable_plural);
}
}
public static string objectType_externalDataSource_singular
{
get
{
return Keys.GetString(Keys.objectType_externalDataSource_singular);
}
}
public static string objectType_serverRole_singular
{
get
{
return Keys.GetString(Keys.objectType_serverRole_singular);
}
}
public static string objectType_xmlSchemaCollection_singular
{
get
{
return Keys.GetString(Keys.objectType_xmlSchemaCollection_singular);
}
}
public static string objectType_storedProcedure_plural
{
get
{
return Keys.GetString(Keys.objectType_storedProcedure_plural);
}
}
public static string objectType_endpoint_plural
{
get
{
return Keys.GetString(Keys.objectType_endpoint_plural);
}
}
public static string objectType_sequence_singular
{
get
{
return Keys.GetString(Keys.objectType_sequence_singular);
}
}
public static string objectType_userDefinedDataType_singular
{
get
{
return Keys.GetString(Keys.objectType_userDefinedDataType_singular);
}
}
public static string objectType_fullTextCatalog_plural
{
get
{
return Keys.GetString(Keys.objectType_fullTextCatalog_plural);
}
}
public static string objectType_credential_singular
{
get
{
return Keys.GetString(Keys.objectType_credential_singular);
}
}
public static string objectType_databaseRole_plural
{
get
{
return Keys.GetString(Keys.objectType_databaseRole_plural);
}
}
public static string objectType_endpoint_singular
{
get
{
return Keys.GetString(Keys.objectType_endpoint_singular);
}
}
public static string objectType_view_plural
{
get
{
return Keys.GetString(Keys.objectType_view_plural);
}
}
public static string objectType_assembly_singular
{
get
{
return Keys.GetString(Keys.objectType_assembly_singular);
}
}
public static string objectType_functionScalar_singular
{
get
{
return Keys.GetString(Keys.objectType_functionScalar_singular);
}
}
public static string objectType_server_plural
{
get
{
return Keys.GetString(Keys.objectType_server_plural);
}
}
public static string objectType_table_singular
{
get
{
return Keys.GetString(Keys.objectType_table_singular);
}
}
public static string objectType_serviceQueue_singular
{
get
{
return Keys.GetString(Keys.objectType_serviceQueue_singular);
}
}
public static string objectType_login_plural
{
get
{
return Keys.GetString(Keys.objectType_login_plural);
}
}
public static string objectType_storedProcedure_singular
{
get
{
return Keys.GetString(Keys.objectType_storedProcedure_singular);
}
}
public static string objectType_default_plural
{
get
{
return Keys.GetString(Keys.objectType_default_plural);
}
}
public static string objectType_symmetricKey_singular
{
get
{
return Keys.GetString(Keys.objectType_symmetricKey_singular);
}
}
public static string objectType_userDefinedTableType_singular
{
get
{
return Keys.GetString(Keys.objectType_userDefinedTableType_singular);
}
}
public static string objectType_functionInline_singular
{
get
{
return Keys.GetString(Keys.objectType_functionInline_singular);
}
}
public static string objectType_serverRole_plural
{
get
{
return Keys.GetString(Keys.objectType_serverRole_plural);
}
}
public static string objectType_agentjob_singular
{
get
{
return Keys.GetString(Keys.objectType_agentjob_singular);
}
}
public static string objectType_databaseRole_singular
{
get
{
return Keys.GetString(Keys.objectType_databaseRole_singular);
}
}
public static string objectType_synonym_singular
{
get
{
return Keys.GetString(Keys.objectType_synonym_singular);
}
}
public static string objectType_AvailabilityGroup_singular
{
get
{
return Keys.GetString(Keys.objectType_AvailabilityGroup_singular);
}
}
public static string objectType_externalFileFormat_plural
{
get
{
return Keys.GetString(Keys.objectType_externalFileFormat_plural);
}
}
public static string objectType_database_singular
{
get
{
return Keys.GetString(Keys.objectType_database_singular);
}
}
public static string objectType_symmetricKey_plural
{
get
{
return Keys.GetString(Keys.objectType_symmetricKey_plural);
}
}
public static string objectType_securityPolicy_singular
{
get
{
return Keys.GetString(Keys.objectType_securityPolicy_singular);
}
}
public static string objectType_externalFileFormat_singular
{
get
{
return Keys.GetString(Keys.objectType_externalFileFormat_singular);
}
}
public static string objectType_applicationRole_singular
{
get
{
return Keys.GetString(Keys.objectType_applicationRole_singular);
}
}
public static string objectType_assembly_plural
{
get
{
return Keys.GetString(Keys.objectType_assembly_plural);
}
}
public static string objectType_sequence_plural
{
get
{
return Keys.GetString(Keys.objectType_sequence_plural);
}
}
public static string objectType_userDefinedDataType_plural
{
get
{
return Keys.GetString(Keys.objectType_userDefinedDataType_plural);
}
}
public static string objectType_server_singular
{
get
{
return Keys.GetString(Keys.objectType_server_singular);
}
}
public static string objectType_aggregateFunction_singular
{
get
{
return Keys.GetString(Keys.objectType_aggregateFunction_singular);
}
}
public static string objectType_fullTextCatalog_singular
{
get
{
return Keys.GetString(Keys.objectType_fullTextCatalog_singular);
}
}
public static string objectType_certificate_plural
{
get
{
return Keys.GetString(Keys.objectType_certificate_plural);
}
}
public static string objectType_AvailabilityGroup_plural
{
get
{
return Keys.GetString(Keys.objectType_AvailabilityGroup_plural);
}
}
public static string objectType_database_plural
{
get
{
return Keys.GetString(Keys.objectType_database_plural);
}
}
public static string objectType_view_singular
{
get
{
return Keys.GetString(Keys.objectType_view_singular);
}
}
public static string objectType_schema_plural
{
get
{
return Keys.GetString(Keys.objectType_schema_plural);
}
}
public static string objectType_rule_plural
{
get
{
return Keys.GetString(Keys.objectType_rule_plural);
}
}
public static string objectType_certificate_singular
{
get
{
return Keys.GetString(Keys.objectType_certificate_singular);
}
}
public static string objectType_user_singular
{
get
{
return Keys.GetString(Keys.objectType_user_singular);
}
}
public static string objectType_agentjob_plural
{
get
{
return Keys.GetString(Keys.objectType_agentjob_plural);
}
}
public static string objectType_synonym_plural
{
get
{
return Keys.GetString(Keys.objectType_synonym_plural);
}
}
public static string objectType_aggregateFunction_plural
{
get
{
return Keys.GetString(Keys.objectType_aggregateFunction_plural);
}
}
public static string objectType_functionTable_singular
{
get
{
return Keys.GetString(Keys.objectType_functionTable_singular);
}
}
public static string objectType_rule_singular
{
get
{
return Keys.GetString(Keys.objectType_rule_singular);
}
}
public static string objectType_serviceQueue_plural
{
get
{
return Keys.GetString(Keys.objectType_serviceQueue_plural);
}
}
public static string objectType_asymmetricKey_plural
{
get
{
return Keys.GetString(Keys.objectType_asymmetricKey_plural);
}
}
public static string objectType_applicationRole_plural
{
get
{
return Keys.GetString(Keys.objectType_applicationRole_plural);
}
}
public static string objectType_extendedStoredProcedure_singular
{
get
{
return Keys.GetString(Keys.objectType_extendedStoredProcedure_singular);
}
}
public static string objectType_login_singular
{
get
{
return Keys.GetString(Keys.objectType_login_singular);
}
}
public static string objectType_functionInline_plural
{
get
{
return Keys.GetString(Keys.objectType_functionInline_plural);
}
}
public static string objectType_user_plural
{
get
{
return Keys.GetString(Keys.objectType_user_plural);
}
}
public static string objectType_externalDataSource_plural
{
get
{
return Keys.GetString(Keys.objectType_externalDataSource_plural);
}
}
public static string objectType_functionScalar_plural
{
get
{
return Keys.GetString(Keys.objectType_functionScalar_plural);
}
}
public static string objectType_table_plural
{
get
{
return Keys.GetString(Keys.objectType_table_plural);
}
}
public static string objectType_credential_plural
{
get
{
return Keys.GetString(Keys.objectType_credential_plural);
}
}
public static string objectType_schema_singular
{
get
{
return Keys.GetString(Keys.objectType_schema_singular);
}
}
public static string objectType_userDefinedTableType_plural
{
get
{
return Keys.GetString(Keys.objectType_userDefinedTableType_plural);
}
}
public static string objectType_securityPolicy_plural
{
get
{
return Keys.GetString(Keys.objectType_securityPolicy_plural);
}
}
public static string objectType_xmlSchemaCollection_plural
{
get
{
return Keys.GetString(Keys.objectType_xmlSchemaCollection_plural);
}
}
public static string objectType_extendedStoredProcedure_plural
{
get
{
return Keys.GetString(Keys.objectType_extendedStoredProcedure_plural);
}
}
public static string objectType_asymmetricKey_singular
{
get
{
return Keys.GetString(Keys.objectType_asymmetricKey_singular);
}
}
public static string objectType_default_singular
{
get
{
return Keys.GetString(Keys.objectType_default_singular);
}
}
public static string Permission_Alter
{
get
@@ -15159,6 +15735,222 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string ResetPasswordWhileUnlocking = "ResetPasswordWhileUnlocking";
public const string objectType_functionTable_plural = "objectType_functionTable_plural";
public const string objectType_externalDataSource_singular = "objectType_externalDataSource_singular";
public const string objectType_serverRole_singular = "objectType_serverRole_singular";
public const string objectType_xmlSchemaCollection_singular = "objectType_xmlSchemaCollection_singular";
public const string objectType_storedProcedure_plural = "objectType_storedProcedure_plural";
public const string objectType_endpoint_plural = "objectType_endpoint_plural";
public const string objectType_sequence_singular = "objectType_sequence_singular";
public const string objectType_userDefinedDataType_singular = "objectType_userDefinedDataType_singular";
public const string objectType_fullTextCatalog_plural = "objectType_fullTextCatalog_plural";
public const string objectType_credential_singular = "objectType_credential_singular";
public const string objectType_databaseRole_plural = "objectType_databaseRole_plural";
public const string objectType_endpoint_singular = "objectType_endpoint_singular";
public const string objectType_view_plural = "objectType_view_plural";
public const string objectType_assembly_singular = "objectType_assembly_singular";
public const string objectType_functionScalar_singular = "objectType_functionScalar_singular";
public const string objectType_server_plural = "objectType_server_plural";
public const string objectType_table_singular = "objectType_table_singular";
public const string objectType_serviceQueue_singular = "objectType_serviceQueue_singular";
public const string objectType_login_plural = "objectType_login_plural";
public const string objectType_storedProcedure_singular = "objectType_storedProcedure_singular";
public const string objectType_default_plural = "objectType_default_plural";
public const string objectType_symmetricKey_singular = "objectType_symmetricKey_singular";
public const string objectType_userDefinedTableType_singular = "objectType_userDefinedTableType_singular";
public const string objectType_functionInline_singular = "objectType_functionInline_singular";
public const string objectType_serverRole_plural = "objectType_serverRole_plural";
public const string objectType_agentjob_singular = "objectType_agentjob_singular";
public const string objectType_databaseRole_singular = "objectType_databaseRole_singular";
public const string objectType_synonym_singular = "objectType_synonym_singular";
public const string objectType_AvailabilityGroup_singular = "objectType_AvailabilityGroup_singular";
public const string objectType_externalFileFormat_plural = "objectType_externalFileFormat_plural";
public const string objectType_database_singular = "objectType_database_singular";
public const string objectType_symmetricKey_plural = "objectType_symmetricKey_plural";
public const string objectType_securityPolicy_singular = "objectType_securityPolicy_singular";
public const string objectType_externalFileFormat_singular = "objectType_externalFileFormat_singular";
public const string objectType_applicationRole_singular = "objectType_applicationRole_singular";
public const string objectType_assembly_plural = "objectType_assembly_plural";
public const string objectType_sequence_plural = "objectType_sequence_plural";
public const string objectType_userDefinedDataType_plural = "objectType_userDefinedDataType_plural";
public const string objectType_server_singular = "objectType_server_singular";
public const string objectType_aggregateFunction_singular = "objectType_aggregateFunction_singular";
public const string objectType_fullTextCatalog_singular = "objectType_fullTextCatalog_singular";
public const string objectType_certificate_plural = "objectType_certificate_plural";
public const string objectType_AvailabilityGroup_plural = "objectType_AvailabilityGroup_plural";
public const string objectType_database_plural = "objectType_database_plural";
public const string objectType_view_singular = "objectType_view_singular";
public const string objectType_schema_plural = "objectType_schema_plural";
public const string objectType_rule_plural = "objectType_rule_plural";
public const string objectType_certificate_singular = "objectType_certificate_singular";
public const string objectType_user_singular = "objectType_user_singular";
public const string objectType_agentjob_plural = "objectType_agentjob_plural";
public const string objectType_synonym_plural = "objectType_synonym_plural";
public const string objectType_aggregateFunction_plural = "objectType_aggregateFunction_plural";
public const string objectType_functionTable_singular = "objectType_functionTable_singular";
public const string objectType_rule_singular = "objectType_rule_singular";
public const string objectType_serviceQueue_plural = "objectType_serviceQueue_plural";
public const string objectType_asymmetricKey_plural = "objectType_asymmetricKey_plural";
public const string objectType_applicationRole_plural = "objectType_applicationRole_plural";
public const string objectType_extendedStoredProcedure_singular = "objectType_extendedStoredProcedure_singular";
public const string objectType_login_singular = "objectType_login_singular";
public const string objectType_functionInline_plural = "objectType_functionInline_plural";
public const string objectType_user_plural = "objectType_user_plural";
public const string objectType_externalDataSource_plural = "objectType_externalDataSource_plural";
public const string objectType_functionScalar_plural = "objectType_functionScalar_plural";
public const string objectType_table_plural = "objectType_table_plural";
public const string objectType_credential_plural = "objectType_credential_plural";
public const string objectType_schema_singular = "objectType_schema_singular";
public const string objectType_userDefinedTableType_plural = "objectType_userDefinedTableType_plural";
public const string objectType_securityPolicy_plural = "objectType_securityPolicy_plural";
public const string objectType_xmlSchemaCollection_plural = "objectType_xmlSchemaCollection_plural";
public const string objectType_extendedStoredProcedure_plural = "objectType_extendedStoredProcedure_plural";
public const string objectType_asymmetricKey_singular = "objectType_asymmetricKey_singular";
public const string objectType_default_singular = "objectType_default_singular";
public const string Permission_Alter = "Permission_Alter";

View File

@@ -5475,6 +5475,294 @@ The Query Processor estimates that implementing the following index could improv
<value>Reset password for the login while unlocking.</value>
<comment></comment>
</data>
<data name="objectType_functionTable_plural" xml:space="preserve">
<value>Table-valued functions</value>
<comment></comment>
</data>
<data name="objectType_externalDataSource_singular" xml:space="preserve">
<value>External Data Source</value>
<comment></comment>
</data>
<data name="objectType_serverRole_singular" xml:space="preserve">
<value>Server role</value>
<comment></comment>
</data>
<data name="objectType_xmlSchemaCollection_singular" xml:space="preserve">
<value>XML schema collection</value>
<comment></comment>
</data>
<data name="objectType_storedProcedure_plural" xml:space="preserve">
<value>Stored procedures</value>
<comment></comment>
</data>
<data name="objectType_endpoint_plural" xml:space="preserve">
<value>Endpoints</value>
<comment></comment>
</data>
<data name="objectType_sequence_singular" xml:space="preserve">
<value>Sequence</value>
<comment></comment>
</data>
<data name="objectType_userDefinedDataType_singular" xml:space="preserve">
<value>User-defined data type</value>
<comment></comment>
</data>
<data name="objectType_fullTextCatalog_plural" xml:space="preserve">
<value>Full-text catalogs</value>
<comment></comment>
</data>
<data name="objectType_credential_singular" xml:space="preserve">
<value>Credential</value>
<comment></comment>
</data>
<data name="objectType_databaseRole_plural" xml:space="preserve">
<value>Database roles</value>
<comment></comment>
</data>
<data name="objectType_endpoint_singular" xml:space="preserve">
<value>Endpoint</value>
<comment></comment>
</data>
<data name="objectType_view_plural" xml:space="preserve">
<value>Views</value>
<comment></comment>
</data>
<data name="objectType_assembly_singular" xml:space="preserve">
<value>Assembly</value>
<comment></comment>
</data>
<data name="objectType_functionScalar_singular" xml:space="preserve">
<value>Scalar function</value>
<comment></comment>
</data>
<data name="objectType_server_plural" xml:space="preserve">
<value>Servers</value>
<comment></comment>
</data>
<data name="objectType_table_singular" xml:space="preserve">
<value>Table</value>
<comment></comment>
</data>
<data name="objectType_serviceQueue_singular" xml:space="preserve">
<value>Queue</value>
<comment></comment>
</data>
<data name="objectType_login_plural" xml:space="preserve">
<value>Logins</value>
<comment></comment>
</data>
<data name="objectType_storedProcedure_singular" xml:space="preserve">
<value>Stored procedure</value>
<comment></comment>
</data>
<data name="objectType_default_plural" xml:space="preserve">
<value>Defaults</value>
<comment></comment>
</data>
<data name="objectType_symmetricKey_singular" xml:space="preserve">
<value>Symmetric key</value>
<comment></comment>
</data>
<data name="objectType_userDefinedTableType_singular" xml:space="preserve">
<value>User-defined table type</value>
<comment></comment>
</data>
<data name="objectType_functionInline_singular" xml:space="preserve">
<value>Inline function</value>
<comment></comment>
</data>
<data name="objectType_serverRole_plural" xml:space="preserve">
<value>Server roles</value>
<comment></comment>
</data>
<data name="objectType_agentjob_singular" xml:space="preserve">
<value>Agent job</value>
<comment></comment>
</data>
<data name="objectType_databaseRole_singular" xml:space="preserve">
<value>Database role</value>
<comment></comment>
</data>
<data name="objectType_synonym_singular" xml:space="preserve">
<value>Synonym</value>
<comment></comment>
</data>
<data name="objectType_AvailabilityGroup_singular" xml:space="preserve">
<value>Availability Group</value>
<comment></comment>
</data>
<data name="objectType_externalFileFormat_plural" xml:space="preserve">
<value>External File Formats</value>
<comment></comment>
</data>
<data name="objectType_database_singular" xml:space="preserve">
<value>Database</value>
<comment></comment>
</data>
<data name="objectType_symmetricKey_plural" xml:space="preserve">
<value>Symmetric keys</value>
<comment></comment>
</data>
<data name="objectType_securityPolicy_singular" xml:space="preserve">
<value>Security Policy</value>
<comment></comment>
</data>
<data name="objectType_externalFileFormat_singular" xml:space="preserve">
<value>External File Format</value>
<comment></comment>
</data>
<data name="objectType_applicationRole_singular" xml:space="preserve">
<value>Application role</value>
<comment></comment>
</data>
<data name="objectType_assembly_plural" xml:space="preserve">
<value>Assemblies</value>
<comment></comment>
</data>
<data name="objectType_sequence_plural" xml:space="preserve">
<value>Sequences</value>
<comment></comment>
</data>
<data name="objectType_userDefinedDataType_plural" xml:space="preserve">
<value>User-defined data types</value>
<comment></comment>
</data>
<data name="objectType_server_singular" xml:space="preserve">
<value>Server</value>
<comment></comment>
</data>
<data name="objectType_aggregateFunction_singular" xml:space="preserve">
<value>Aggregate function</value>
<comment></comment>
</data>
<data name="objectType_fullTextCatalog_singular" xml:space="preserve">
<value>Full-text catalog</value>
<comment></comment>
</data>
<data name="objectType_certificate_plural" xml:space="preserve">
<value>Certificates</value>
<comment></comment>
</data>
<data name="objectType_AvailabilityGroup_plural" xml:space="preserve">
<value>Availability Groups</value>
<comment></comment>
</data>
<data name="objectType_database_plural" xml:space="preserve">
<value>Databases</value>
<comment></comment>
</data>
<data name="objectType_view_singular" xml:space="preserve">
<value>View</value>
<comment></comment>
</data>
<data name="objectType_schema_plural" xml:space="preserve">
<value>Schemas</value>
<comment></comment>
</data>
<data name="objectType_rule_plural" xml:space="preserve">
<value>Rules</value>
<comment></comment>
</data>
<data name="objectType_certificate_singular" xml:space="preserve">
<value>Certificate</value>
<comment></comment>
</data>
<data name="objectType_user_singular" xml:space="preserve">
<value>User</value>
<comment></comment>
</data>
<data name="objectType_agentjob_plural" xml:space="preserve">
<value>Agent jobs</value>
<comment></comment>
</data>
<data name="objectType_synonym_plural" xml:space="preserve">
<value>Synonyms</value>
<comment></comment>
</data>
<data name="objectType_aggregateFunction_plural" xml:space="preserve">
<value>Aggregate functions</value>
<comment></comment>
</data>
<data name="objectType_functionTable_singular" xml:space="preserve">
<value>Table-valued function</value>
<comment></comment>
</data>
<data name="objectType_rule_singular" xml:space="preserve">
<value>Rule</value>
<comment></comment>
</data>
<data name="objectType_serviceQueue_plural" xml:space="preserve">
<value>Queues</value>
<comment></comment>
</data>
<data name="objectType_asymmetricKey_plural" xml:space="preserve">
<value>Asymmetric keys</value>
<comment></comment>
</data>
<data name="objectType_applicationRole_plural" xml:space="preserve">
<value>Application roles</value>
<comment></comment>
</data>
<data name="objectType_extendedStoredProcedure_singular" xml:space="preserve">
<value>Extended stored procedure</value>
<comment></comment>
</data>
<data name="objectType_login_singular" xml:space="preserve">
<value>Login</value>
<comment></comment>
</data>
<data name="objectType_functionInline_plural" xml:space="preserve">
<value>Inline functions</value>
<comment></comment>
</data>
<data name="objectType_user_plural" xml:space="preserve">
<value>Users</value>
<comment></comment>
</data>
<data name="objectType_externalDataSource_plural" xml:space="preserve">
<value>External Data Sources</value>
<comment></comment>
</data>
<data name="objectType_functionScalar_plural" xml:space="preserve">
<value>Scalar functions</value>
<comment></comment>
</data>
<data name="objectType_table_plural" xml:space="preserve">
<value>Tables</value>
<comment></comment>
</data>
<data name="objectType_credential_plural" xml:space="preserve">
<value>Credentials</value>
<comment></comment>
</data>
<data name="objectType_schema_singular" xml:space="preserve">
<value>Schema</value>
<comment></comment>
</data>
<data name="objectType_userDefinedTableType_plural" xml:space="preserve">
<value>User-defined table types</value>
<comment></comment>
</data>
<data name="objectType_securityPolicy_plural" xml:space="preserve">
<value>Security Policies</value>
<comment></comment>
</data>
<data name="objectType_xmlSchemaCollection_plural" xml:space="preserve">
<value>XML schema collections</value>
<comment></comment>
</data>
<data name="objectType_extendedStoredProcedure_plural" xml:space="preserve">
<value>Extended stored procedures</value>
<comment></comment>
</data>
<data name="objectType_asymmetricKey_singular" xml:space="preserve">
<value>Asymmetric key</value>
<comment></comment>
</data>
<data name="objectType_default_singular" xml:space="preserve">
<value>Default</value>
<comment></comment>
</data>
<data name="Permission_Alter" xml:space="preserve">
<value>Alter</value>
<comment></comment>

View File

@@ -2470,6 +2470,80 @@ ObjectNotRenamable(string urn) = The object could not be renamed. URN: '{0}'.
DefaultLanguagePlaceholder = <default>
ResetPasswordWhileUnlocking = Reset password for the login while unlocking.
#Search
objectType_functionTable_plural = Table-valued functions
objectType_externalDataSource_singular = External Data Source
objectType_serverRole_singular = Server role
objectType_xmlSchemaCollection_singular = XML schema collection
objectType_storedProcedure_plural = Stored procedures
objectType_endpoint_plural = Endpoints
objectType_sequence_singular = Sequence
objectType_userDefinedDataType_singular = User-defined data type
objectType_fullTextCatalog_plural = Full-text catalogs
objectType_credential_singular = Credential
objectType_databaseRole_plural = Database roles
objectType_endpoint_singular = Endpoint
objectType_view_plural = Views
objectType_assembly_singular = Assembly
objectType_functionScalar_singular = Scalar function
objectType_server_plural = Servers
objectType_table_singular = Table
objectType_serviceQueue_singular = Queue
objectType_login_plural = Logins
objectType_storedProcedure_singular = Stored procedure
objectType_default_plural = Defaults
objectType_symmetricKey_singular = Symmetric key
objectType_userDefinedTableType_singular = User-defined table type
objectType_functionInline_singular = Inline function
objectType_serverRole_plural = Server roles
objectType_agentjob_singular = Agent job
objectType_databaseRole_singular = Database role
objectType_synonym_singular = Synonym
objectType_AvailabilityGroup_singular = Availability Group
objectType_externalFileFormat_plural = External File Formats
objectType_database_singular = Database
objectType_symmetricKey_plural = Symmetric keys
objectType_securityPolicy_singular = Security Policy
objectType_externalFileFormat_singular = External File Format
objectType_applicationRole_singular = Application role
objectType_assembly_plural = Assemblies
objectType_sequence_plural = Sequences
objectType_userDefinedDataType_plural = User-defined data types
objectType_server_singular = Server
objectType_aggregateFunction_singular = Aggregate function
objectType_fullTextCatalog_singular = Full-text catalog
objectType_certificate_plural = Certificates
objectType_AvailabilityGroup_plural = Availability Groups
objectType_database_plural = Databases
objectType_view_singular = View
objectType_schema_plural = Schemas
objectType_rule_plural = Rules
objectType_certificate_singular = Certificate
objectType_user_singular = User
objectType_agentjob_plural = Agent jobs
objectType_synonym_plural = Synonyms
objectType_aggregateFunction_plural = Aggregate functions
objectType_functionTable_singular = Table-valued function
objectType_rule_singular = Rule
objectType_serviceQueue_plural = Queues
objectType_asymmetricKey_plural = Asymmetric keys
objectType_applicationRole_plural = Application roles
objectType_extendedStoredProcedure_singular = Extended stored procedure
objectType_login_singular = Login
objectType_functionInline_plural = Inline functions
objectType_user_plural = Users
objectType_externalDataSource_plural = External Data Sources
objectType_functionScalar_plural = Scalar functions
objectType_table_plural = Tables
objectType_credential_plural = Credentials
objectType_schema_singular = Schema
objectType_userDefinedTableType_plural = User-defined table types
objectType_securityPolicy_plural = Security Policies
objectType_xmlSchemaCollection_plural = XML schema collections
objectType_extendedStoredProcedure_plural = Extended stored procedures
objectType_asymmetricKey_singular = Asymmetric key
objectType_default_singular = Default
#Object permission names
Permission_Alter = Alter
Permission_Connect = Connect

View File

@@ -7217,6 +7217,365 @@ The Query Processor estimates that implementing the following index could improv
<target state="new">Service {0} was not found in the service provider</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_functionTable_plural">
<source>Table-valued functions</source>
<target state="new">Table-valued functions</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_externalDataSource_singular">
<source>External Data Source</source>
<target state="new">External Data Source</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_serverRole_singular">
<source>Server role</source>
<target state="new">Server role</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_xmlSchemaCollection_singular">
<source>XML schema collection</source>
<target state="new">XML schema collection</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_storedProcedure_plural">
<source>Stored procedures</source>
<target state="new">Stored procedures</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_endpoint_plural">
<source>Endpoints</source>
<target state="new">Endpoints</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_sequence_singular">
<source>Sequence</source>
<target state="new">Sequence</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_userDefinedDataType_singular">
<source>User-defined data type</source>
<target state="new">User-defined data type</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_fullTextCatalog_plural">
<source>Full-text catalogs</source>
<target state="new">Full-text catalogs</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_credential_singular">
<source>Credential</source>
<target state="new">Credential</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_databaseRole_plural">
<source>Database roles</source>
<target state="new">Database roles</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_endpoint_singular">
<source>Endpoint</source>
<target state="new">Endpoint</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_view_plural">
<source>Views</source>
<target state="new">Views</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_assembly_singular">
<source>Assembly</source>
<target state="new">Assembly</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_functionScalar_singular">
<source>Scalar function</source>
<target state="new">Scalar function</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_server_plural">
<source>Servers</source>
<target state="new">Servers</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_table_singular">
<source>Table</source>
<target state="new">Table</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_serviceQueue_singular">
<source>Queue</source>
<target state="new">Queue</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_login_plural">
<source>Logins</source>
<target state="new">Logins</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_storedProcedure_singular">
<source>Stored procedure</source>
<target state="new">Stored procedure</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_default_plural">
<source>Defaults</source>
<target state="new">Defaults</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_symmetricKey_singular">
<source>Symmetric key</source>
<target state="new">Symmetric key</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_userDefinedTableType_singular">
<source>User-defined table type</source>
<target state="new">User-defined table type</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_functionInline_singular">
<source>Inline function</source>
<target state="new">Inline function</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_serverRole_plural">
<source>Server roles</source>
<target state="new">Server roles</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_agentjob_singular">
<source>Agent job</source>
<target state="new">Agent job</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_databaseRole_singular">
<source>Database role</source>
<target state="new">Database role</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_synonym_singular">
<source>Synonym</source>
<target state="new">Synonym</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_AvailabilityGroup_singular">
<source>Availability Group</source>
<target state="new">Availability Group</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_externalFileFormat_plural">
<source>External File Formats</source>
<target state="new">External File Formats</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_database_singular">
<source>Database</source>
<target state="new">Database</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_symmetricKey_plural">
<source>Symmetric keys</source>
<target state="new">Symmetric keys</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_securityPolicy_singular">
<source>Security Policy</source>
<target state="new">Security Policy</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_externalFileFormat_singular">
<source>External File Format</source>
<target state="new">External File Format</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_applicationRole_singular">
<source>Application role</source>
<target state="new">Application role</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_assembly_plural">
<source>Assemblies</source>
<target state="new">Assemblies</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_sequence_plural">
<source>Sequences</source>
<target state="new">Sequences</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_userDefinedDataType_plural">
<source>User-defined data types</source>
<target state="new">User-defined data types</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_server_singular">
<source>Server</source>
<target state="new">Server</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_aggregateFunction_singular">
<source>Aggregate function</source>
<target state="new">Aggregate function</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_fullTextCatalog_singular">
<source>Full-text catalog</source>
<target state="new">Full-text catalog</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_certificate_plural">
<source>Certificates</source>
<target state="new">Certificates</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_AvailabilityGroup_plural">
<source>Availability Groups</source>
<target state="new">Availability Groups</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_database_plural">
<source>Databases</source>
<target state="new">Databases</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_view_singular">
<source>View</source>
<target state="new">View</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_schema_plural">
<source>Schemas</source>
<target state="new">Schemas</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_rule_plural">
<source>Rules</source>
<target state="new">Rules</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_certificate_singular">
<source>Certificate</source>
<target state="new">Certificate</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_user_singular">
<source>User</source>
<target state="new">User</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_agentjob_plural">
<source>Agent jobs</source>
<target state="new">Agent jobs</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_synonym_plural">
<source>Synonyms</source>
<target state="new">Synonyms</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_aggregateFunction_plural">
<source>Aggregate functions</source>
<target state="new">Aggregate functions</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_functionTable_singular">
<source>Table-valued function</source>
<target state="new">Table-valued function</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_rule_singular">
<source>Rule</source>
<target state="new">Rule</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_serviceQueue_plural">
<source>Queues</source>
<target state="new">Queues</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_asymmetricKey_plural">
<source>Asymmetric keys</source>
<target state="new">Asymmetric keys</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_applicationRole_plural">
<source>Application roles</source>
<target state="new">Application roles</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_extendedStoredProcedure_singular">
<source>Extended stored procedure</source>
<target state="new">Extended stored procedure</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_login_singular">
<source>Login</source>
<target state="new">Login</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_functionInline_plural">
<source>Inline functions</source>
<target state="new">Inline functions</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_user_plural">
<source>Users</source>
<target state="new">Users</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_externalDataSource_plural">
<source>External Data Sources</source>
<target state="new">External Data Sources</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_functionScalar_plural">
<source>Scalar functions</source>
<target state="new">Scalar functions</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_table_plural">
<source>Tables</source>
<target state="new">Tables</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_credential_plural">
<source>Credentials</source>
<target state="new">Credentials</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_schema_singular">
<source>Schema</source>
<target state="new">Schema</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_userDefinedTableType_plural">
<source>User-defined table types</source>
<target state="new">User-defined table types</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_securityPolicy_plural">
<source>Security Policies</source>
<target state="new">Security Policies</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_xmlSchemaCollection_plural">
<source>XML schema collections</source>
<target state="new">XML schema collections</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_extendedStoredProcedure_plural">
<source>Extended stored procedures</source>
<target state="new">Extended stored procedures</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_asymmetricKey_singular">
<source>Asymmetric key</source>
<target state="new">Asymmetric key</target>
<note></note>
</trans-unit>
<trans-unit id="objectType_default_singular">
<source>Default</source>
<target state="new">Default</target>
</trans-unit>
<trans-unit id="FilterInPrimaryKey">
<source>In Primary Key</source>
<target state="new">In Primary Key</target>

View File

@@ -0,0 +1,36 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement.Contracts
{
public class SearchRequestParams : GeneralRequestDetails
{
/// <summary>
/// The context id.
/// </summary>
public string? ContextId { get; set; }
public string[]? ObjectTypes { get; set; }
public string? SearchText { get; set; }
public string? Schema { get; set; }
public string? Database { get; set; }
}
public class SearchResultItem
{
public string? Name { get; set; }
public string? Schema { get; set; }
public string? Type { get; set; }
}
public class SearchRequest
{
public static readonly RequestType<SearchRequestParams, SearchResultItem[]> Type = RequestType<SearchRequestParams, SearchResultItem[]>.Create("objectManagement/search");
}
}

View File

@@ -11,6 +11,7 @@ using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.ObjectManagement.Contracts;
using System.Collections.Generic;
using System.Collections.Concurrent;
using Microsoft.SqlTools.ServiceLayer.Management;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
@@ -64,6 +65,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.serviceHost.SetRequestHandler(SaveObjectRequest.Type, HandleSaveObjectRequest, true);
this.serviceHost.SetRequestHandler(ScriptObjectRequest.Type, HandleScriptObjectRequest, true);
this.serviceHost.SetRequestHandler(DisposeViewRequest.Type, HandleDisposeViewRequest, true);
this.serviceHost.SetRequestHandler(SearchRequest.Type, HandleSearchRequest, true);
}
internal async Task HandleRenameRequest(RenameRequestParams requestParams, RequestContext<RenameRequestResponse> requestContext)
@@ -116,6 +118,68 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
await requestContext.SendResult(new DisposeViewRequestResponse());
}
internal async Task HandleSearchRequest(SearchRequestParams requestParams, RequestContext<SearchResultItem[]> requestContext)
{
var context = this.GetContext(requestParams.ContextId);
ConnectionInfo connInfo;
ConnectionService.Instance.TryFindConnection(context.Parameters.ConnectionUri, out connInfo);
if (connInfo == null)
{
throw new ArgumentException("Invalid ConnectionUri");
}
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
List<SearchResultItem> res = new List<SearchResultItem>();
foreach (string type in requestParams.ObjectTypes)
{
SearchableObjectCollection result = new SearchableObjectCollection();
SearchableObjectType searchableObjectType = SecurableUtils.ConvertPotentialSqlObjectTypeToSearchableObjectType(type);
if (searchableObjectType == SearchableObjectType.LastType)
{
continue;
}
SearchableObjectTypeDescription desc = SearchableObjectTypeDescription.GetDescription(searchableObjectType);
if (requestParams.SearchText != null)
{
if (desc.IsDatabaseObject)
{
SearchableObject.Search(result, searchableObjectType, dataContainer.ConnectionInfo, context.Parameters.Database, requestParams.SearchText, false, true);
}
else
{
SearchableObject.Search(result, searchableObjectType, dataContainer.ConnectionInfo, requestParams.SearchText, false, true);
}
}
else
{
if (desc.IsDatabaseObject)
{
SearchableObject.Search(result, searchableObjectType, dataContainer.ConnectionInfo, context.Parameters.Database, true);
}
else
{
SearchableObject.Search(result, searchableObjectType, dataContainer.ConnectionInfo, true);
}
}
foreach (SearchableObject obj in result)
{
res.Add(new SearchResultItem
{
Name = obj.Name,
Type = type
});
}
}
await requestContext.SendResult(res.ToArray());
}
private IObjectTypeHandler GetObjectTypeHandler(SqlObjectType objectType)
{
foreach (var handler in objectTypeHandlers)

View File

@@ -75,12 +75,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
Value = item.Value
}).ToArray(),
OwnedSchemas = prototype.SchemasOwned,
SecurablePermissions = prototype.SecurablePermissions
};
var viewInfo = new AppRoleViewInfo()
{
ObjectInfo = appRoleInfo,
Schemas = prototype.Schemas
Schemas = prototype.Schemas,
SupportedSecurableTypes = SecurableUtils.GetSecurableTypeMetadata(SqlObjectType.ApplicationRole, dataContainer.Server.Version, parameters.Database, dataContainer.Server.DatabaseEngineType, dataContainer.Server.DatabaseEngineEdition)
};
var context = new AppRoleViewContext(parameters, dataContainer.ServerConnection);

View File

@@ -8,7 +8,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <summary>
/// a class for storing various application role properties
/// </summary>
public class AppRoleInfo : SqlObject
public class AppRoleInfo : SecurityPrincipalObject
{
public string? DefaultSchema { get; set; }
public string? Password { get; set; }

View File

@@ -8,7 +8,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <summary>
/// a class for storing various application role view properties
/// </summary>
public class AppRoleViewInfo : SqlObjectViewInfo
public class AppRoleViewInfo : SecurityPrincipalViewInfo
{
public string[]? Schemas { get; set; }
}

View File

@@ -74,12 +74,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
}).ToArray(),
Members = prototype.Members.ToArray(),
OwnedSchemas = prototype.SchemasOwned.ToArray(),
SecurablePermissions = prototype.SecurablePermissions
};
var viewInfo = new DatabaseRoleViewInfo()
{
ObjectInfo = DatabaseRoleInfo,
Schemas = prototype.Schemas
Schemas = prototype.Schemas,
SupportedSecurableTypes = SecurableUtils.GetSecurableTypeMetadata(SqlObjectType.DatabaseRole, dataContainer.Server.Version, parameters.Database, dataContainer.Server.DatabaseEngineType, dataContainer.Server.DatabaseEngineEdition)
};
var context = new DatabaseRoleViewContext(parameters, dataContainer.ServerConnection);

View File

@@ -8,7 +8,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <summary>
/// a class for storing various database role properties
/// </summary>
public class DatabaseRoleInfo : SqlObject
public class DatabaseRoleInfo : SecurityPrincipalObject
{
public string? Owner { get; set; }
public string[]? OwnedSchemas { get; set; }

View File

@@ -8,7 +8,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <summary>
/// a class for storing various database role view properties
/// </summary>
public class DatabaseRoleViewInfo : SqlObjectViewInfo
public class DatabaseRoleViewInfo : SecurityPrincipalViewInfo
{
public string[]? Schemas { get; set; }
}

View File

@@ -55,8 +55,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
}
string[] languages = languageOptionsList.ToArray();
LoginPrototype prototype = parameters.IsNewObject
? new LoginPrototype(dataContainer.Server)
: new LoginPrototype(dataContainer.Server, dataContainer.Server.GetSmoObject(parameters.ObjectUrn) as Login);
? new LoginPrototype(dataContainer)
: new LoginPrototype(dataContainer, dataContainer.Server.GetSmoObject(parameters.ObjectUrn) as Login);
List<string> loginServerRoles = new List<string>();
foreach (string role in prototype.ServerRoles.ServerRoleNames)
@@ -82,7 +82,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
ConnectPermission = prototype.WindowsGrantAccess,
IsEnabled = !prototype.IsDisabled,
IsLockedOut = prototype.IsLockedOut,
UserMapping = new ServerLoginDatabaseUserMapping[0]
UserMapping = new ServerLoginDatabaseUserMapping[0],
SecurablePermissions = prototype.SecurablePermissions
};
var supportedAuthTypes = new List<LoginAuthenticationType>();
@@ -104,7 +105,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
Languages = languages,
ServerRoles = prototype.ServerRoles.ServerRoleNames,
SupportAdvancedPasswordOptions = dataContainer.Server.DatabaseEngineType == DatabaseEngineType.Standalone || dataContainer.Server.DatabaseEngineEdition == DatabaseEngineEdition.SqlDataWarehouse,
SupportAdvancedOptions = dataContainer.Server.DatabaseEngineType == DatabaseEngineType.Standalone || dataContainer.Server.DatabaseEngineEdition == DatabaseEngineEdition.SqlManagedInstance
SupportAdvancedOptions = dataContainer.Server.DatabaseEngineType == DatabaseEngineType.Standalone || dataContainer.Server.DatabaseEngineEdition == DatabaseEngineEdition.SqlManagedInstance,
SupportedSecurableTypes = SecurableUtils.GetSecurableTypeMetadata(SqlObjectType.ServerLevelLogin, dataContainer.Server.Version, "", dataContainer.Server.DatabaseEngineType, dataContainer.Server.DatabaseEngineEdition)
};
var context = new LoginViewContext(parameters);
return Task.FromResult(new InitializeViewResult()
@@ -189,7 +191,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
}
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
LoginPrototype prototype = new LoginPrototype(dataContainer.Server, dataContainer.Server.Logins[login.Name]);
LoginPrototype prototype = new LoginPrototype(dataContainer, dataContainer.Server.Logins[login.Name]);
prototype.SqlPassword = login.Password;
if (0 != string.Compare(login.DefaultLanguage, SR.DefaultLanguagePlaceholder, StringComparison.Ordinal))
@@ -207,6 +209,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
prototype.IsDisabled = !login.IsEnabled;
prototype.MustChange = login.EnforcePasswordPolicy ? login.MustChangePassword : false;
prototype.WindowsGrantAccess = login.ConnectPermission;
prototype.SecurablePermissions = login.SecurablePermissions;
if (prototype.LoginType == SqlServer.Management.Smo.LoginType.SqlLogin)
{
@@ -256,7 +259,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
}
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
LoginPrototype prototype = new LoginPrototype(dataContainer.Server, login);
LoginPrototype prototype = new LoginPrototype(dataContainer, login);
if (prototype.LoginType == SqlServer.Management.Smo.LoginType.SqlLogin)
{

View File

@@ -35,7 +35,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <summary>
/// a class for storing various login properties
/// </summary>
public class LoginInfo : SqlObject
public class LoginInfo : SecurityPrincipalObject
{
public LoginAuthenticationType AuthenticationType { get; set; }

View File

@@ -6,7 +6,7 @@
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
public class LoginViewInfo : SqlObjectViewInfo
public class LoginViewInfo : SecurityPrincipalViewInfo
{
public LoginAuthenticationType[] AuthenticationTypes { get; set; }
public bool CanEditLockedOutState { get; set; }

View File

@@ -12,6 +12,7 @@ using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Management;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SqlTools.ServiceLayer.ObjectManagement.PermissionsData;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
@@ -32,7 +33,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
private bool exists;
private AppRolePrototypeData currentState;
private AppRolePrototypeData originalState;
private SecurablePermissions[] securablePermissions = null;
private Principal principal = null;
#endregion
#region Trace support
@@ -139,6 +141,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.currentState.ExtendedProperties = value;
}
}
public SecurablePermissions[] SecurablePermissions
{
get
{
return this.securablePermissions;
}
set
{
this.securablePermissions = value;
}
}
#endregion
#region Constructors / Dispose
@@ -149,6 +163,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.dataContainer = context;
this.currentState = new AppRolePrototypeData(context, database);
this.originalState = (AppRolePrototypeData)this.currentState.Clone();
this.securablePermissions = new SecurablePermissions[0];
}
/// <summary>
@@ -161,6 +176,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.databaseName = database;
this.currentState = new AppRolePrototypeData(context, database);
this.originalState = (AppRolePrototypeData)this.currentState.Clone();
this.principal = SecurableUtils.CreatePrincipal(false, PrincipalType.ApplicationRole, null, roleInfo.Name, context, database);
this.ApplyInfoToPrototype(roleInfo);
}
@@ -175,6 +191,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.databaseName = database;
this.currentState = new AppRolePrototypeData(context, database, role);
this.originalState = (AppRolePrototypeData)this.currentState.Clone();
this.securablePermissions = SecurableUtils.GetSecurablePermissions(true, PrincipalType.ApplicationRole, role, context);
this.principal = SecurableUtils.CreatePrincipal(true, PrincipalType.ApplicationRole, role, null, context, database);
this.principal.AddExistingSecurables();
}
#endregion
@@ -223,6 +242,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
SendToServerSchemaOwnershipChanges(db, approle);
SendToServerExtendedPropertiesChange();
SecurableUtils.SendToServerPermissionChanges(this.exists, this.Name, this.SecurablePermissions, this.principal, this.dataContainer, this.databaseName);
}
else // not in properties mode -> create role
{
@@ -236,6 +256,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
SendToServerSchemaOwnershipChanges(db, approle);
SendToServerExtendedPropertiesChange();
SecurableUtils.SendToServerPermissionChanges(this.exists, this.Name, this.SecurablePermissions, this.principal, this.dataContainer, this.databaseName);
}
}
@@ -327,6 +348,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.SchemasOwned = roleInfo.OwnedSchemas.ToArray();
this.Password = roleInfo.Password;
this.ExtendedProperties = roleInfo.ExtendedProperties.Select(ep => new KeyValuePair<string, string>(ep.Name, ep.Value)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
this.securablePermissions = roleInfo.SecurablePermissions;
}
private class AppRolePrototypeData : ICloneable

View File

@@ -12,6 +12,7 @@ using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Management;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SqlTools.ServiceLayer.ObjectManagement.PermissionsData;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
@@ -32,7 +33,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
private bool exists;
private DatabaseRolePrototypeData currentState;
private DatabaseRolePrototypeData originalState;
private SecurablePermissions[] securablePermissions = null;
private Principal principal = null;
#endregion
#region Trace support
@@ -138,6 +140,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
return this.dataContainer.Server.VersionMajor >= 9;
}
}
public SecurablePermissions[] SecurablePermissions
{
get
{
return this.securablePermissions;
}
set
{
this.securablePermissions = value;
}
}
#endregion
#region Constructors / Dispose
@@ -148,6 +162,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.dataContainer = context;
this.currentState = new DatabaseRolePrototypeData(context, database);
this.originalState = (DatabaseRolePrototypeData)this.currentState.Clone();
this.securablePermissions = new SecurablePermissions[0];
}
/// <summary>
@@ -160,6 +175,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.dataContainer = context;
this.currentState = new DatabaseRolePrototypeData(context, database);
this.originalState = (DatabaseRolePrototypeData)this.currentState.Clone();
this.principal = SecurableUtils.CreatePrincipal(false, PrincipalType.DatabaseRole, null, roleInfo.Name, context, database);
this.ApplyInfoToPrototype(roleInfo);
}
@@ -174,6 +190,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.dataContainer = context;
this.currentState = new DatabaseRolePrototypeData(context, database, role);
this.originalState = (DatabaseRolePrototypeData)this.currentState.Clone();
this.principal = SecurableUtils.CreatePrincipal(true, PrincipalType.DatabaseRole, role, null, context, database);
this.principal.AddExistingSecurables();
this.securablePermissions = SecurableUtils.GetSecurablePermissions(true, PrincipalType.DatabaseRole, role, context);
}
#endregion
@@ -219,6 +238,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
}
SendToServerSchemaOwnershipChanges(db, databaseRole);
SendToServerExtendedPropertiesChange();
SecurableUtils.SendToServerPermissionChanges(this.exists, this.Name, this.SecurablePermissions, this.principal, this.dataContainer, this.databaseName);
}
#endregion
@@ -341,6 +361,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.Members = roleInfo.Members.ToList();
this.SchemasOwned = roleInfo.OwnedSchemas.ToArray();
this.ExtendedProperties = roleInfo.ExtendedProperties.Select(ep => new KeyValuePair<string, string>(ep.Name, ep.Value)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
this.securablePermissions = roleInfo.SecurablePermissions;
}
private class DatabaseRolePrototypeData : ICloneable

View File

@@ -0,0 +1,200 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Data;
using System.Globalization;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlTools.ServiceLayer.Management;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
/// <summary>
/// Data model for the EffectivePermmisions UI
/// </summary>
internal class EffectivePermissionsData
{
#region fields
private CDataContainer dataContainer;
// urn we are targetting
private Urn urn;
// securable we are targetting
private SupportedSecurable securable;
// the principal we will execute as
private string principalName = string.Empty;
// indicates whether or not we should execute as a login or user
private bool executeAsLogin;
#endregion
#region properties
/// <summary>
/// True if the query for this principal will return column information
/// </summary>
public bool HasColumnInformation
{
get
{
// STrace.Assert(this.securable != null, "invalid object state");
return this.securable.HasColumnInformation;
}
}
/// <summary>
/// The name of the principal we are checking permissions for
/// </summary>
public string PrincipalName
{
get
{
return this.principalName;
}
}
/// <summary>
/// the display name of the securable we are querying. If the securable has a schema it will be
/// schema.securable, otherwise just securable
/// </summary>
public string SecurableDisplayName
{
get
{
// STrace.Assert(this.securable != null, "invalid object state");
string displayName;
if (this.securable.Schema.Length > 0)
{
displayName = String.Format(CultureInfo.CurrentCulture
, "{0}.{1}"
, this.securable.Schema
, this.securable.Name);
}
else
{
displayName = this.securable.Name;
}
return displayName;
}
}
#endregion
#region constructors
/// <summary>
/// Construct an EffectivePermissionsData object
/// </summary>
/// <param name="dataContainer">CDataContainer that represents the principal we are querying</param>
public EffectivePermissionsData(CDataContainer dataContainer)
{
if (dataContainer == null)
{
throw new ArgumentNullException("dataContainer");
}
this.dataContainer = dataContainer;
Initialize();
}
#endregion
#region public methods
/// <summary>
/// Query the effective permissions for principal against the securable
/// </summary>
/// <returns>Dataset representing the permissions</returns>
public DataSet QueryEffectivePermissions()
{
// get a connection
ServerConnection serverConnection = this.dataContainer.ServerConnection;
// see if we need to set the context to a particular db
string databaseName = GetDatabaseName(this.urn);
if (databaseName.Length > 0)
{
serverConnection.ExecuteNonQuery(
String.Format(CultureInfo.InvariantCulture
, "USE [{0}]"
, SecurableUtils.EscapeString(databaseName, "]")));
}
// get the securable query
string securableQuery = this.securable.GetPermissionsForSecurableSyntax();
// merge the securableQuery with the EXECUTE AS context
string sqlQuery =
String.Format(CultureInfo.InvariantCulture,
@"EXECUTE AS {0} = N'{1}';
{2}
REVERT;"
, this.executeAsLogin ? "LOGIN" : "USER"
, Urn.EscapeString(this.principalName)
, securableQuery);
return serverConnection.ExecuteWithResults(sqlQuery);
}
#endregion
#region implementation
/// <summary>
/// Initialize the object
/// </summary>
private void Initialize()
{
// STrace.Assert(this.dataContainer != null);
STParameters parameters = new STParameters(this.dataContainer.Document);
// get the Urn of the securable. This must be set
string securableUrn = string.Empty;
parameters.GetParam("urn", ref securableUrn);
// cannot proceed if there is no object to work on
if (securableUrn == null || securableUrn.Length == 0)
{
throw new InvalidOperationException();
}
this.urn = new Urn(securableUrn);
// get a supported securable for this object
this.securable = new SupportedSecurable(this.urn, this.dataContainer.Server);
// get the user we will be executing as
parameters.GetParam("executeas", ref this.principalName);
string executeAsType = String.Empty;
parameters.GetParam("executetype", ref executeAsType);
this.executeAsLogin = (executeAsType == "login");
// if no override is supplied then we will just execute as self
if (this.principalName == null || this.principalName.Length == 0)
{
// STrace.Assert(false, "Principal was not supplied. Defaulting to login");
this.principalName = this.dataContainer.ServerConnection.TrueLogin;
this.executeAsLogin = true;
}
}
/// <summary>
/// Get the database name if any that contains the securable
/// </summary>
/// <param name="urn">Securable</param>
/// <returns>Database name that contains the securable, or an empty string if this is a server
/// scoped object</returns>
private string GetDatabaseName(Urn urn)
{
String databaseName = string.Empty;
// otherwise try and find the database
while (urn != null && urn.Type != "Database")
{
urn = urn.Parent;
}
if (urn != null)
{
databaseName = urn.GetAttribute("Name");
}
return databaseName;
}
#endregion
}
}

View File

@@ -31,9 +31,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
if (this.configAction != ConfigAction.Drop)
{
prototype.ApplyGeneralChanges(this.DataContainer.Server);
prototype.ApplyServerRoleChanges(this.DataContainer.Server);
prototype.ApplyDatabaseRoleChanges(this.DataContainer.Server);
prototype.SendChangeToServer();
}
}
}

View File

@@ -16,6 +16,7 @@ using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.ServiceLayer.ObjectManagement.PermissionsData;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
@@ -1547,11 +1548,14 @@ INNER JOIN sys.sql_logins AS sql_logins
}
private bool exists;
private CDataContainer context;
private string machineName;
private LoginPrototypeData currentState;
private LoginPrototypeData originalState;
private bool mapToCredential;
private SecurablePermissions[] securablePermissions = null;
private Principal principal = null;
public bool MapToCredential
{
set
@@ -1905,6 +1909,18 @@ INNER JOIN sys.sql_logins AS sql_logins
}
}
public SecurablePermissions[] SecurablePermissions
{
get
{
return securablePermissions;
}
set
{
securablePermissions = value;
}
}
/// <summary>
/// Get the database roles collection for the user in a particular database
/// </summary>
@@ -2056,13 +2072,16 @@ INNER JOIN sys.sql_logins AS sql_logins
/// constructor
/// </summary>
/// <param name="server">The server on which we are creating a login</param>
public LoginPrototype(Microsoft.SqlServer.Management.Smo.Server server)
public LoginPrototype(CDataContainer context)
{
this.context = context;
var server = context.Server;
this.exists = false;
this.machineName = server.ConnectionContext.TrueName.ToUpperInvariant();
this.currentState = new LoginPrototypeData(server);
this.originalState = (LoginPrototypeData) this.currentState.Clone();
this.comparer = new SqlCollationSensitiveStringComparer(server.Information.Collation);
this.securablePermissions = new SecurablePermissions[0];
}
/// <summary>
@@ -2070,21 +2089,28 @@ INNER JOIN sys.sql_logins AS sql_logins
/// </summary>
/// <param name="server">The server on which we are modifying a login</param>
/// <param name="login">The login we are modifying</param>
public LoginPrototype(Microsoft.SqlServer.Management.Smo.Server server, Login login)
public LoginPrototype(CDataContainer context, Login login)
{
this.context = context;
var server = context.Server;
this.exists = true;
this.machineName = server.ConnectionContext.TrueName.ToUpperInvariant();
this.currentState = new LoginPrototypeData(server, login);
this.originalState = (LoginPrototypeData) this.currentState.Clone();
this.comparer = new SqlCollationSensitiveStringComparer(server.Information.Collation);
this.securablePermissions = SecurableUtils.GetSecurablePermissions(this.exists, PrincipalType.Login, login, context);
this.principal = SecurableUtils.CreatePrincipal(true, PrincipalType.Login, login, null, context);
this.principal.AddExistingSecurables();
}
/// <summary>
/// constructor
/// </summary>
/// <param name="server">The server on which we are creating a login</param>
public LoginPrototype(Microsoft.SqlServer.Management.Smo.Server server, LoginInfo login)
public LoginPrototype(CDataContainer context, LoginInfo login)
{
this.context = context;
var server = context.Server;
this.exists = false;
this.machineName = server.ConnectionContext.TrueName.ToUpperInvariant();
this.currentState = new LoginPrototypeData(server);
@@ -2112,6 +2138,8 @@ INNER JOIN sys.sql_logins AS sql_logins
this.IsDisabled = !login.IsEnabled;
this.MustChange = login.EnforcePasswordPolicy ? login.MustChangePassword : false;
this.WindowsGrantAccess = login.ConnectPermission;
this.securablePermissions = login.SecurablePermissions;
this.principal = SecurableUtils.CreatePrincipal(false, PrincipalType.Login, null, login.Name, context);
}
private LoginType GetLoginType(LoginInfo loginInfo)
@@ -2154,6 +2182,14 @@ INNER JOIN sys.sql_logins AS sql_logins
}
public void SendChangeToServer()
{
ApplyGeneralChanges(this.context.Server);
ApplyServerRoleChanges(this.context.Server);
ApplyDatabaseRoleChanges(this.context.Server);
SecurableUtils.SendToServerPermissionChanges(this.exists, this.LoginName, this.SecurablePermissions, this.principal, this.context, null);
}
/// <summary>
/// Create the login or modify the login's access type, default database, default language,
/// and password

View File

@@ -10,6 +10,7 @@ using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Management;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SqlTools.ServiceLayer.ObjectManagement.PermissionsData;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
@@ -26,6 +27,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// as a hash table where one can manipulate custom data
/// </summary>
private CDataContainer dataContainer = null;
private Principal principal = null;
private SecurablePermissions[] securablePermissions = null;
private bool exists;
private ServerRolePrototypeData currentState;
@@ -109,6 +112,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
return this.currentState.IsFixedRole;
}
}
public SecurablePermissions[] SecurablePermissions
{
get
{
return securablePermissions;
}
set
{
securablePermissions = value;
}
}
#endregion
#region Constructors / Dispose
@@ -118,6 +133,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.dataContainer = context;
this.currentState = new ServerRolePrototypeData(context);
this.originalState = (ServerRolePrototypeData)this.currentState.Clone();
this.securablePermissions = new SecurablePermissions[0];
}
/// <summary>
@@ -129,6 +145,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.dataContainer = context;
this.currentState = new ServerRolePrototypeData(context);
this.originalState = (ServerRolePrototypeData)this.currentState.Clone();
this.principal = SecurableUtils.CreatePrincipal(false, PrincipalType.ServerRole, null, roleInfo.Name, context);
this.ApplyInfoToPrototype(roleInfo);
}
@@ -142,6 +159,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.dataContainer = context;
this.currentState = new ServerRolePrototypeData(context, role);
this.originalState = (ServerRolePrototypeData)this.currentState.Clone();
this.principal = SecurableUtils.CreatePrincipal(true, PrincipalType.ServerRole, role, null, context);
this.principal.AddExistingSecurables();
this.securablePermissions = SecurableUtils.GetSecurablePermissions(this.exists, PrincipalType.ServerRole, role, this.dataContainer);
}
#endregion
@@ -183,6 +203,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
SendToServerMemberChanges(serverRole);
SendToServerMembershipChanges(serverRole);
SecurableUtils.SendToServerPermissionChanges(this.exists, this.Name, this.SecurablePermissions, this.principal, this.dataContainer, null);
}
#endregion
@@ -250,13 +271,13 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
}
}
public void ApplyInfoToPrototype(ServerRoleInfo roleInfo)
{
this.Name = roleInfo.Name;
this.Owner = roleInfo.Owner;
this.Members = roleInfo.Members.ToList();
this.Memberships = roleInfo.Memberships.ToList();
this.SecurablePermissions = roleInfo.SecurablePermissions;
}
private class ServerRolePrototypeData : ICloneable

View File

@@ -9,7 +9,6 @@ using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Resources;
using System.Text;
using System.Globalization;
using Microsoft.SqlServer.Management.Smo;
@@ -281,7 +280,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// Constructor
/// </summary>
/// <param name="image">Bitmap for the object type</param>
/// <param name="typeNameKey">The key to look up localized type names, e.g. "objectType.functionTable"</param>
/// <param name="typeNameKey">The key to look up localized type names, e.g. "objectType_functionTable"</param>
/// <param name="urnObjectType">The URN object type substring, e.g. "UserDefinedFunction"</param>
/// <param name="specialRestrictions">Any special clauses needed for the URN, e.g. "@FunctionType='2'"</param>
/// <param name="disallowSystemObjectsRestriction">Clause to restrict selection to non-system objects, e.g. "@IsSystemObject='false'"</param>
@@ -294,8 +293,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
string specialRestrictions,
string disallowSystemObjectsRestriction,
bool isDatabaseObject,
bool isSchemaObject,
ResourceManager resourceManager)
bool isSchemaObject)
{
// STrace.Assert(image != null, "image is null");
// STrace.Assert((typeNameKey != null) && (typeNameKey.Length != 0), "typeNameKey is null or empty");
@@ -309,9 +307,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.disallowSystemObjectsRestriction = disallowSystemObjectsRestriction;
this.isDatabaseObject = isDatabaseObject;
this.isSchemaObject = isSchemaObject;
this.typeNamePlural = resourceManager.GetString(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}.plural", typeNameKey));
this.typeNameSingular = resourceManager.GetString(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}.singular", typeNameKey));
this.typeNamePlural = SR.Keys.GetString(string.Format("{0}_plural", typeNameKey));
this.typeNameSingular = SR.Keys.GetString(string.Format("{0}_singular", typeNameKey));
// STrace.Assert((this.typeNamePlural != null) && (this.typeNamePlural.Length != 0), "could not get plural type name");
// STrace.Assert((this.typeNameSingular != null) && (this.typeNameSingular.Length != 0), "could not get singular type name");
@@ -321,7 +318,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// Constructor
/// </summary>
/// <param name="image">Bitmap for the object type</param>
/// <param name="typeNameKey">The key to look up localized type names, e.g. "objectType.functionTable"</param>
/// <param name="typeNameKey">The key to look up localized type names, e.g. "objectType_functionTable"</param>
/// <param name="urnObjectType">The URN object type substring, e.g. "UserDefinedFunction"</param>
/// <param name="isDatabaseObject">Whether the object is contained by a database</param>
/// <param name="isSchemaObject">Whether the object is contained byt a schema</param>
@@ -330,8 +327,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
string typeNameKey,
string urnObjectType,
bool isDatabaseObject,
bool isSchemaObject,
ResourceManager resourceManager)
bool isSchemaObject)
{
// STrace.Assert(image != null, "image is null");
// STrace.Assert((typeNameKey != null) && (typeNameKey.Length != 0), "typeNameKey is null or empty");
@@ -344,8 +340,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.isDatabaseObject = isDatabaseObject;
this.isSchemaObject = isSchemaObject;
this.typeNamePlural = resourceManager.GetString(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}.plural", typeNameKey));
this.typeNameSingular = resourceManager.GetString(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}.singular", typeNameKey));
this.typeNamePlural = SR.Keys.GetString(string.Format("{0}_plural", typeNameKey));
this.typeNameSingular = SR.Keys.GetString(string.Format("{0}_singular", typeNameKey));
// STrace.Assert((this.typeNamePlural != null) && (this.typeNamePlural.Length != 0), "could not get plural type name");
// STrace.Assert((this.typeNameSingular != null) && (this.typeNameSingular.Length != 0), "could not get singular type name");
@@ -620,14 +616,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
if (SearchableObjectTypeDescription.firstVersionSpecificTypeInfoUpdate)
{
ResourceManager resourceManager = new ResourceManager("Microsoft.SqlServer.Management.SqlMgmt.SqlObjectSearchStrings", typeof(SearchableObjectTypeDescription).Assembly);
// Color transparent = ResourceUtils.StandardBitmapTransparentColor;
//Re-writing the value of SearchableObjectType.ServerRole in the Dictionary.
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.ServerRole] =
new SearchableObjectTypeDescription(
// // DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("Flexible_server_role.ico")).ToBitmap(),
"objectType.serverRole",
"objectType_serverRole",
"Role",
string.Empty,
Utils.IsSql11OrLater(serverVersion.Major)
@@ -636,8 +629,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
? "@ID=2" //Public server role's ID is 2.
: string.Empty,
false,
false,
resourceManager);
false);
firstVersionSpecificTypeInfoUpdate = false;
}
@@ -653,364 +645,324 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
SearchableObjectTypeDescription.typeToDescription = new HybridDictionary(25);
}
ResourceManager resourceManager = new ResourceManager("Microsoft.SqlServer.Management.SqlMgmt.SqlObjectSearchStrings", typeof(SearchableObjectTypeDescription).Assembly);
// Color transparent = ResourceUtils.StandardBitmapTransparentColor;
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.AggregateFunction] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("ScalarValuedFunction.ico")).ToBitmap(),
"objectType.aggregateFunction",
"objectType_aggregateFunction",
"UserDefinedAggregate",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.ApplicationRole] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("application_role_16x.ico")).ToBitmap(),
"objectType.applicationRole",
"objectType_applicationRole",
"ApplicationRole",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Assembly] =
new SearchableObjectTypeDescription(
// // DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("assemblies.ico")).ToBitmap(),
"objectType.assembly",
"objectType_assembly",
"SqlAssembly",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.AsymmetricKey] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("asymmetric_key.ico")).ToBitmap(),
"objectType.asymmetricKey",
"objectType_asymmetricKey",
"AsymmetricKey",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Certificate] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("certificate.ico")).ToBitmap(),
"objectType.certificate",
"objectType_certificate",
"Certificate",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Database] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("database.ico")).ToBitmap(),
"objectType.database",
"objectType_database",
"Database",
String.Empty,
"@IsSystemObject=false()",
false,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.AgentJob] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("jobs.ico")).ToBitmap(),
"objectType.agentjob",
"objectType_agentjob",
"JobServer/Job",
false,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.DatabaseRole] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("database_roles_16x.ico")).ToBitmap(),
"objectType.databaseRole",
"objectType_databaseRole",
"Role",
String.Empty,
"@IsFixedRole=false()",
true,
false,
resourceManager);
false);
//Without version info, we can't have system object Urn as it differs with version.
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.ServerRole] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("Flexible_server_role.ico")).ToBitmap(),
"objectType.serverRole",
"objectType_serverRole",
"Role",
false,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Endpoint] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("endpoint.ico")).ToBitmap(),
"objectType.endpoint",
"objectType_endpoint",
"Endpoint",
false,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.ExtendedStoredProcedure] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("user_extended_stored_proc.ico")).ToBitmap(),
"objectType.extendedStoredProcedure",
"objectType_extendedStoredProcedure",
"ExtendedStoredProcedure",
String.Empty,
"@IsSystemObject=false()",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.ExternalDataSource] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("ExternalDataSource.ico")).ToBitmap(),
"objectType.externalDataSource",
"objectType_externalDataSource",
"ExternalDataSource",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.ExternalFileFormat] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("ExternalFileFormat.ico")).ToBitmap(),
"objectType.externalFileFormat",
"objectType_externalFileFormat",
"ExternalFileFormat",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.FullTextCatalog] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("full_text_catalog.ico")).ToBitmap(),
"objectType.fullTextCatalog",
"objectType_fullTextCatalog",
"FullTextCatalog",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.FunctionInline] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("table_valued_function.ico")).ToBitmap(),
"objectType.functionInline",
"objectType_functionInline",
"UserDefinedFunction",
String.Format(System.Globalization.CultureInfo.InvariantCulture, "@FunctionType='{0}'", (int)UserDefinedFunctionType.Inline),
"@IsSystemObject=false()",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.FunctionScalar] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("ScalarValuedFunction.ico")).ToBitmap(),
"objectType.functionScalar",
"objectType_functionScalar",
"UserDefinedFunction",
String.Format(System.Globalization.CultureInfo.InvariantCulture, "@FunctionType='{0}'", (int)UserDefinedFunctionType.Scalar),
"@IsSystemObject=false()",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.FunctionTable] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("table_valued_function.ico")).ToBitmap(),
"objectType.functionTable",
"objectType_functionTable",
"UserDefinedFunction",
String.Format(System.Globalization.CultureInfo.InvariantCulture, "@FunctionType='{0}'", (int)UserDefinedFunctionType.Table),
"@IsSystemObject=false()",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Login] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("log_in_16x.ico")).ToBitmap(),
"objectType.login",
"objectType_login",
"Login",
String.Empty,
"@IsSystemObject=false()",
false,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.LoginOnly] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("log_in_16x.ico")).ToBitmap(),
"objectType.login",
"objectType_login",
"Login",
"@LoginType = 2 or @LoginType = 0",
"@IsSystemObject=false()",
false,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Schema] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("database_schema.ico")).ToBitmap(),
"objectType.schema",
"objectType_schema",
"Schema",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Server] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("server.ico")).ToBitmap(),
"objectType.server",
"objectType_server",
String.Empty,
false,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.SecurityPolicy] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("securitypolicy.ico")).ToBitmap(),
"objectType.securityPolicy",
"objectType_securityPolicy",
"SecurityPolicy",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.ServiceQueue] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("queue.ico")).ToBitmap(),
"objectType.serviceQueue",
"objectType_serviceQueue",
"ServiceBroker/ServiceQueue",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.StoredProcedure] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("stored_procedure.ico")).ToBitmap(),
"objectType.storedProcedure",
"objectType_storedProcedure",
"StoredProcedure",
String.Empty,
"@IsSystemObject=false()",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Synonym] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("synonym.ico")).ToBitmap(),
"objectType.synonym",
"objectType_synonym",
"Synonym",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Sequence] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("sequence.ico")).ToBitmap(),
"objectType.sequence",
"objectType_sequence",
"Sequence",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Table] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("table.ico")).ToBitmap(),
"objectType.table",
"objectType_table",
"Table",
String.Empty,
"@IsSystemObject=false()",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.User] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("user_16x.ico")).ToBitmap(),
"objectType.user",
"objectType_user",
"User",
String.Empty,
"(@IsSystemObject=false() or @Name='guest')",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.UserDefinedDataType] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("user_defined_data_type.ico")).ToBitmap(),
"objectType.userDefinedDataType",
"objectType_userDefinedDataType",
"UserDefinedDataType",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.View] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("view.ico")).ToBitmap(),
"objectType.view",
"objectType_view",
"View",
String.Empty,
"@IsSystemObject=false()",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.XmlSchemaCollection] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("XML_schemas.ico")).ToBitmap(),
"objectType.xmlSchemaCollection",
"objectType_xmlSchemaCollection",
"XmlSchemaCollection",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Rule] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("rule.ico")).ToBitmap(),
"objectType.rule",
"objectType_rule",
"Rule",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Default] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("defaults_16x.ico")).ToBitmap(),
"objectType.default",
"objectType_default",
"Default",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.Credential] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("credential.ico")).ToBitmap(),
"objectType.credential",
"objectType_credential",
"Credential",
false,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.SymmetricKey] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("symmetric_key.ico")).ToBitmap(),
"objectType.symmetricKey",
"objectType_symmetricKey",
"SymmetricKey",
true,
false,
resourceManager);
false);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.UserDefinedTableType] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("table.ico")).ToBitmap(),
"objectType.userDefinedTableType",
"objectType_userDefinedTableType",
"UserDefinedTableType",
true,
true,
resourceManager);
true);
SearchableObjectTypeDescription.typeToDescription[SearchableObjectType.AvailabilityGroup] =
new SearchableObjectTypeDescription(
// DpiUtil.GetScaledIcon(ResourceUtils.LoadIcon("Availability_Group.ico")).ToBitmap(),
"objectType.AvailabilityGroup",
"objectType_AvailabilityGroup",
"AvailabilityGroup",
false,
false,
resourceManager);
false);
}
/// <summary>

View File

@@ -0,0 +1,296 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Globalization;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
/// <summary>
/// Represents a Securable in SQL that can generate the TSQL to list
/// its permissions.
/// </summary>
internal class SupportedSecurable
{
#region constants
private const string queryWithColumn = @"SELECT
permission_name AS [Permission]
,subentity_name AS [Column]
FROM fn_my_permissions(N'{0}', N'{1}')
ORDER BY permission_name, subentity_name;";
private const string queryWithoutColumn = @"SELECT
permission_name AS [Permission]
FROM fn_my_permissions(N'{0}', N'{1}')
ORDER BY permission_name;";
private const string queryWithoutSecurableName = @"SELECT
permission_name AS [Permission]
FROM fn_my_permissions(NULL, N'{1}')
ORDER BY permission_name;";
#endregion
#region fields
/// <summary>
/// SMO server we are targetting. This is needed so we can generate the correct
/// query against Table valued functions
/// </summary>
private SqlServer.Management.Smo.Server server;
/// <summary>
/// Securable we are targetting
/// </summary>
private Urn securable;
/// <summary>
/// Name of the securable
/// </summary>
private string securableName;
/// <summary>
/// Schema of the securable. If the securable does not have a schema this will be an Empty string
/// </summary>
private string securableSchema;
/// <summary>
/// The SMO type of the securable.
/// </summary>
private string securableType;
#endregion
#region public properties
/// <summary>
/// Indicates whether or not the securable will return column information or just a
/// list of permissions
/// </summary>
public bool HasColumnInformation
{
get
{
bool hasColumnInformation = false;
if (securable.Type == "Table" || securable.Type == "View")
{
hasColumnInformation = true;
}
else if (securable.Type == "UserDefinedFunction" && this.server != null)
{
UserDefinedFunction function = server.GetSmoObject(this.securable) as UserDefinedFunction;
// STrace.Assert(function != null, "Could not get correct SMO object");
hasColumnInformation = (function != null && function.FunctionType == UserDefinedFunctionType.Table);
}
return hasColumnInformation;
}
}
/// <summary>
/// name of the securable
/// </summary>
public string Name
{
get
{
return this.securableName;
}
}
/// <summary>
/// schema of the securable
/// </summary>
public string Schema
{
get
{
return this.securableSchema;
}
}
#endregion
#region Construction
/// <summary>
/// Create a new SupportedSecurable object.
/// </summary>
/// <param name="securable">The securable we are targetting</param>
/// <param name="server">The server where the securable resides. Can be null</param>
public SupportedSecurable(Urn securable, SqlServer.Management.Smo.Server server)
{
if (securable == null)
{
throw new ArgumentNullException("securable");
}
this.securable = securable;
this.server = server;
// get the name
this.securableName = this.securable.GetAttribute("Name");
// get the schema from the urn
this.securableSchema = this.securable.GetAttribute("Schema");
// convert null to string.empty
this.securableSchema ??= String.Empty;
// get the type
this.securableType = this.securable.Type;
// check that we were passed good information
// STrace.Assert(this.securableName != null && this.securableName.Length > 0, "No usable object name available");
// STrace.Assert(this.securableType != null && this.securableType.Length > 0, "No usable object type available");
}
#endregion
#region public methods
/// <summary>
/// Generate a SQL query that would query the permissions on this securable
/// </summary>
/// <returns>a string that represents the query</returns>
public string GetPermissionsForSecurableSyntax()
{
string sqlQuery;
string fullSecurableName = null;
// get the class we will pass
string securableClass = GetSecurableClassForUrn(this.securable);
// Do not pass securable name for SERVER securables
if (securableClass == "SERVER")
{
sqlQuery = queryWithoutSecurableName;
}
else
{
if (this.HasColumnInformation)
{
sqlQuery = queryWithColumn;
}
else
{
sqlQuery = queryWithoutColumn;
}
if (this.securableSchema.Length > 0)
{
fullSecurableName = String.Format(CultureInfo.InvariantCulture, "[{0}].[{1}]"
, SecurableUtils.EscapeString(SecurableUtils.EscapeString(this.securableSchema, "]"), "'")
, SecurableUtils.EscapeString(SecurableUtils.EscapeString(this.securableName, "]"), "'"));
}
else
{
fullSecurableName = String.Format(CultureInfo.InvariantCulture, "[{0}]"
, SecurableUtils.EscapeString(SecurableUtils.EscapeString(this.securableName, "]"), "'"));
}
}
// return the select query
return String.Format(CultureInfo.InvariantCulture, sqlQuery, fullSecurableName, securableClass);
}
#endregion
#region implementation
/// <summary>
/// Finds a type for a Urn that can be passed to fn_my_permissions
/// </summary>
/// <param name="type">Urn</param>
/// <returns>tsql type</returns>
private static string GetSecurableClassForUrn(Urn securable)
{
string securableType;
// just use a simple switch. If we wanted to be more sophisticated we could use a
// chain-of-responsibility pattern
switch (securable.Type)
{
case "ApplicationRole":
securableType = "APPLICATION ROLE";
break;
case "SqlAssembly":
securableType = "ASSEMBLY";
break;
case "AsymmetricKey":
securableType = "ASYMMETRIC KEY";
break;
case "Certificate":
securableType = "CERTIFICATE";
break;
case "ServiceContract":
securableType = "CONTRACT";
break;
case "Database":
securableType = "DATABASE";
break;
case "Endpoint":
securableType = "ENDPOINT";
break;
case "ExternalDataSource":
securableType = "EXTERNAL DATA SOURCE";
break;
case "ExternalFileFormat":
securableType = "EXTERNAL FILE FORMAT";
break;
case "FullTextCatalog":
securableType = "FULLTEXT CATALOG";
break;
case "Login":
securableType = "LOGIN";
break;
case "MessageType":
securableType = "MESSAGE TYPE";
break;
case "AvailabilityGroup":
securableType = "AVAILABILITY GROUP";
break;
// the following types map to OBJECT
case "UserDefinedAggregate":
case "Check":
case "Default":
case "ForeignKey":
// index is for index and primary key constraints
case "Index":
case "StoredProcedure":
case "UserDefinedFunction":
case "Rule":
case "Synonym":
case "Sequence":
case "ServiceQueue":
case "Trigger":
case "DdlTrigger":
case "Table":
case "View":
case "ExtendedStoredProcedure":
securableType = "OBJECT";
break;
case "RemoteServiceBinding":
securableType = "REMOTE SERVICE BINDING";
break;
case "Role":
securableType = (securable.Parent.Type == "Database") ? "ROLE" : "SERVER ROLE";
break;
case "ServiceRoute":
securableType = "ROUTE";
break;
case "Schema":
securableType = "SCHEMA";
break;
case "SecurityPolicy":
securableType = "SECURITY POLICY";
break;
case "Server":
securableType = "SERVER";
break;
case "BrokerService":
securableType = "SERVICE";
break;
case "SymmetricKey":
securableType = "SYMMETRIC KEY";
break;
case "UserDefinedDataType":
securableType = "TYPE";
break;
case "User":
securableType = "USER";
break;
case "XmlSchemaCollection":
securableType = "XML SCHEMA COLLECTION";
break;
default:
// throw if we don't know about something
throw new InvalidOperationException();
}
return securableType;
}
#endregion
}
}

View File

@@ -40,7 +40,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
currentUserType = UserActions.GetCurrentUserTypeForExistingUser(dataContainer.Server.GetSmoObject(dataContainer.ObjectUrn) as User);
}
this.userPrototype = UserPrototypeFactory.GetUserPrototype(dataContainer, user, originalData, currentUserType);
this.userPrototype = UserPrototypeFactory.GetUserPrototype(dataContainer, user, originalData, currentUserType, dataContainer.IsNewObject);
}
// /// <summary>

View File

@@ -12,6 +12,7 @@ using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.ServiceLayer.ObjectManagement.PermissionsData;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
@@ -93,6 +94,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
public SecureString passwordConfirm = new SecureString();
public SecureString oldPassword = new SecureString();
public bool isOldPasswordRequired = false;
public bool isNewObject = false;
/// <summary>
/// Used for creating clone of a UserPrototypeData.
@@ -363,6 +365,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
private bool exists = false;
private Database parent;
private CDataContainer context;
private SecurablePermissions[] securablePermissions = new SecurablePermissions[0];
private Principal principal = null;
public bool IsRoleMembershipChangesApplied { get; set; } //default is false
public bool IsSchemaOwnershipChangesApplied { get; set; } //default is false
@@ -483,6 +487,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.currentState.isMember[roleName] = isMember;
}
public SecurablePermissions[] SecurablePermissions
{
get
{
return this.securablePermissions;
}
set
{
this.securablePermissions = value;
}
}
#endregion
/// <summary>
@@ -501,6 +517,19 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
Database? parent = context.Server.GetSmoObject(new Urn(context.ParentUrn)) as Database ?? throw new ArgumentException("Context ParentUrn is invalid");
this.parent = parent;
var userName = this.currentState.name;
if (current.isNewObject)
{
this.securablePermissions = new SecurablePermissions[0];
this.principal = SecurableUtils.CreatePrincipal(false, PrincipalType.DatabaseRole, null, userName, context, parent.Name);
}
else
{
this.securablePermissions = SecurableUtils.GetSecurablePermissions(true, PrincipalType.User, parent.Users[userName], context);
this.principal = SecurableUtils.CreatePrincipal(true, PrincipalType.User, parent.Users[userName], null, context, parent.Name);
this.principal.AddExistingSecurables();
}
this.roleNames = this.PopulateRoles();
this.schemaNames = this.PopulateSchemas();
}
@@ -564,6 +593,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
this.ApplyRoleMembershipChanges(parentDb, user);
this.IsRoleMembershipChangesApplied = true;
SecurableUtils.SendToServerPermissionChanges(!string.IsNullOrEmpty(this.currentState.name), this.Name, this.SecurablePermissions, this.principal, context, parentDb.Name);
}
return user;
@@ -1031,10 +1062,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
public static UserPrototype GetUserPrototype(
CDataContainer context, UserInfo? user,
UserPrototypeData? originalData, ExhaustiveUserTypes userType)
UserPrototypeData? originalData, ExhaustiveUserTypes userType, bool isNewObject)
{
UserPrototype currentPrototype = null;
UserPrototypeData currentData = new UserPrototypeData(context, user);
currentData.isNewObject = isNewObject;
switch (userType)
{
case ExhaustiveUserTypes.AsymmetricKeyMappedUser:
@@ -1067,6 +1099,10 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
currentPrototype = null;
break;
}
if (user != null && user.SecurablePermissions != null)
{
currentPrototype.SecurablePermissions = user.SecurablePermissions;
}
return currentPrototype;
}
}

View File

@@ -56,14 +56,16 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
Name = prototype.Name,
Owner = prototype.Owner,
Members = prototype.Members.ToArray(),
Memberships = prototype.Memberships.ToArray()
Memberships = prototype.Memberships.ToArray(),
SecurablePermissions = prototype.SecurablePermissions
};
var viewInfo = new ServerRoleViewInfo()
{
ObjectInfo = ServerRoleInfo,
IsFixedRole = prototype.IsFixedRole,
ServerRoles = serverRoles.ToArray()
ServerRoles = serverRoles.ToArray(),
SupportedSecurableTypes = SecurableUtils.GetSecurableTypeMetadata(SqlObjectType.ServerRole, dataContainer.Server.Version, "", dataContainer.Server.DatabaseEngineType, dataContainer.Server.DatabaseEngineEdition)
};
var context = new ServerRoleViewContext(parameters);

View File

@@ -8,7 +8,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <summary>
/// a class for storing various server role properties
/// </summary>
public class ServerRoleInfo : SqlObject
public class ServerRoleInfo : SecurityPrincipalObject
{
public string? Owner { get; set; }
public string[]? Members { get; set; }

View File

@@ -8,7 +8,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <summary>
/// a class for storing various server role view properties
/// </summary>
public class ServerRoleViewInfo : SqlObjectViewInfo
public class ServerRoleViewInfo : SecurityPrincipalViewInfo
{
public bool IsFixedRole { get; set; }
public string[]? ServerRoles { get; set; }

View File

@@ -98,7 +98,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
}
// generate a user prototype
UserPrototype currentUserPrototype = UserPrototypeFactory.GetUserPrototype(dataContainer, userInfo, originalData: null, userType);
UserPrototype currentUserPrototype = UserPrototypeFactory.GetUserPrototype(dataContainer, userInfo, originalData: null, userType, parameters.IsNewObject);
// get the default schema if available
string defaultSchema = null;
@@ -212,13 +212,15 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
DefaultSchema = defaultSchema,
OwnedSchemas = schemaNames.ToArray(),
DatabaseRoles = databaseRoles.ToArray(),
DefaultLanguage = defaultLanguage
DefaultLanguage = defaultLanguage,
SecurablePermissions = currentUserPrototype.SecurablePermissions
},
UserTypes = supportedUserTypes.ToArray(),
Languages = languageOptionsList.ToArray(),
Schemas = currentUserPrototype.SchemaNames.ToArray(),
Logins = logins,
DatabaseRoles = currentUserPrototype.DatabaseRoleNames.ToArray()
DatabaseRoles = currentUserPrototype.DatabaseRoleNames.ToArray(),
SupportedSecurableTypes = SecurableUtils.GetSecurableTypeMetadata(SqlObjectType.User, dataContainer.Server.Version, parameters.Database, dataContainer.Server.DatabaseEngineType, dataContainer.Server.DatabaseEngineEdition)
};
var context = new UserViewContext(parameters, dataContainer.ServerConnection, currentUserPrototype.CurrentState);
return new InitializeViewResult { ViewInfo = userViewInfo, Context = context };

View File

@@ -33,7 +33,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <summary>
/// a class for storing various user properties
/// </summary>
public class UserInfo : SqlObject
public class UserInfo : SecurityPrincipalObject
{
public DatabaseUserType? Type { get; set; }

View File

@@ -8,7 +8,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// <summary>
/// The information required to render the user view.
/// </summary>
public class UserViewInfo : SqlObjectViewInfo
public class UserViewInfo : SecurityPrincipalViewInfo
{
public DatabaseUserType[]? UserTypes { get; set; }

View File

@@ -0,0 +1,13 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
public class PermissionMetadata
{
public string? Name { get; set; }
public string? DisplayName { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
public class SecurablePermissionItem
{
public string? Permission { get; set; }
public string? Grantor { get; set; }
public bool? Grant { get; set; }
public bool? WithGrant { get; set; }
}
public class SecurablePermissions
{
public string? Name { get; set; }
public string? Schema { get; set; }
public string? Type { get; set; }
public string[]? EffectivePermissions { get; set; }
public SecurablePermissionItem[]? Permissions { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
public class SecurableTypeMetadata
{
public string? Name { get; set; }
public string? DisplayName { get; set; }
public PermissionMetadata[]? Permissions { get; set; }
}
}

View File

@@ -0,0 +1,530 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.ServiceLayer.ObjectManagement.PermissionsData;
using Newtonsoft.Json;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
public class SecurableUtils
{
private static readonly SearchableObjectType[] securableTypesForServerLevel = new SearchableObjectType[] {
SearchableObjectType.AvailabilityGroup,
SearchableObjectType.Endpoint,
SearchableObjectType.Login,
SearchableObjectType.ServerRole,
SearchableObjectType.Server
};
private static readonly SearchableObjectType[] securableTypesForDbLevel = new SearchableObjectType[] {
SearchableObjectType.AggregateFunction,
SearchableObjectType.ApplicationRole,
SearchableObjectType.Assembly,
SearchableObjectType.AsymmetricKey,
SearchableObjectType.Certificate,
SearchableObjectType.Database,
SearchableObjectType.DatabaseRole,
SearchableObjectType.ExternalDataSource,
SearchableObjectType.ExternalFileFormat,
SearchableObjectType.FullTextCatalog,
SearchableObjectType.FunctionInline,
SearchableObjectType.ServiceQueue,
SearchableObjectType.FunctionScalar,
SearchableObjectType.Schema,
SearchableObjectType.SecurityPolicy,
SearchableObjectType.Sequence,
SearchableObjectType.StoredProcedure,
SearchableObjectType.SymmetricKey,
SearchableObjectType.Synonym,
SearchableObjectType.Table,
SearchableObjectType.FunctionTable,
SearchableObjectType.UserDefinedDataType,
SearchableObjectType.UserDefinedTableType,
SearchableObjectType.User,
SearchableObjectType.View,
SearchableObjectType.XmlSchemaCollection
};
static internal string launchEffectivePermissions = @"
<formdescription>
<params>
<servername></servername>
<servertype>sql</servertype>
<database></database>
<urn></urn>
<executeas></executeas>
<executetype></executetype>
<A32942B7-FBDE-4ac3-B84E-F5EC89961094 />
<assemblyname>sqlmgmt.dll</assemblyname>
</params>
</formdescription>";
public static SecurableTypeMetadata[] GetSecurableTypeMetadata(SqlObjectType objectType, Version serverVersion, string databaseName,DatabaseEngineType databaseEngineType, DatabaseEngineEdition engineEdition)
{
List<SecurableTypeMetadata> res = new List<SecurableTypeMetadata>();
switch (objectType)
{
case SqlObjectType.ServerLevelLogin:
case SqlObjectType.ServerRole:
AddSecurableTypeMetadata(res, securableTypesForServerLevel, null, serverVersion, databaseName, databaseEngineType, engineEdition);
break;
case SqlObjectType.ApplicationRole:
case SqlObjectType.DatabaseRole:
case SqlObjectType.User:
AddSecurableTypeMetadata(res, securableTypesForDbLevel, null, serverVersion, databaseName, databaseEngineType, engineEdition);
break;
default:
break;
}
return res.ToArray();
}
private static void AddSecurableTypeMetadata(List<SecurableTypeMetadata> res, SearchableObjectType[] supportedTypes, SearchableObjectType[] excludeList, Version serverVersion, string databaseName,DatabaseEngineType databaseEngineType, DatabaseEngineEdition engineEdition)
{
foreach(SearchableObjectType t in supportedTypes)
{
if (t == SearchableObjectType.LastType || (excludeList != null && excludeList.Contains(t)))
{
continue;
}
SecurableType secType = PermissionsData.Securable.GetSecurableType(t);
SearchableObjectTypeDescription desc = SearchableObjectTypeDescription.GetDescription(t);
var pList = PermissionsData.Securable.GetRelevantPermissions(secType, serverVersion, databaseName, databaseEngineType, engineEdition);
var permissions = new PermissionMetadata[pList.Count];
for (int i = 0; i < pList.Count; i++)
{
var p = (Permission)pList[i];
permissions[i] = new PermissionMetadata()
{
Name = p?.Name,
DisplayName = p?.Name
};
}
SecurableTypeMetadata metadata = new SecurableTypeMetadata()
{
Name = desc.DisplayTypeNameSingular,
DisplayName = desc.DisplayTypeNamePlural,
Permissions = permissions
};
res.Add(metadata);
}
res.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.InvariantCulture));
}
public static SecurablePermissions[] GetSecurablePermissions(bool principalExists, PrincipalType principalType, SqlSmoObject o, CDataContainer dataContainer)
{
List<SecurablePermissions> res = new List<SecurablePermissions>();
Principal principal;
try
{
principal = CreatePrincipal(principalExists, principalType, o, null, dataContainer);
}
catch(Exception)
{
return new SecurablePermissions[0];
}
principal.AddExistingSecurables();
var securables = principal.GetSecurables(new SecurableComparer(SecurableComparer.DefaultSortingOrder, true));
foreach (Securable s in securables)
{
var permissionStates = principal.GetPermissionStates(s);
Dictionary<string, SecurablePermissionItem> permissionItemsDict = new Dictionary<string, SecurablePermissionItem>();
for (int i = 0; i < permissionStates.Count; i++)
{
var p = permissionStates[i];
string key = p?.Permission.Name ?? string.Empty;
if (!permissionItemsDict.ContainsKey(key) || string.IsNullOrEmpty(permissionItemsDict[key].Grantor))
{
var permissionItem = new SecurablePermissionItem()
{
Permission = p?.Permission.Name,
Grantor = p?.Grantor,
Grant = p?.State == PermissionStatus.Revoke ? null : p?.State == PermissionStatus.Grant || p?.State == PermissionStatus.WithGrant,
WithGrant = p?.State == PermissionStatus.Revoke ? null : p?.State == PermissionStatus.WithGrant,
};
permissionItemsDict[key] = permissionItem;
}
}
var permissions = permissionItemsDict.Values.OrderBy(x => x.Permission, StringComparer.InvariantCulture).ToArray();
SecurablePermissions secPerm = new SecurablePermissions()
{
Name = s.Name,
Schema = s.Schema,
Type = s.TypeName,
Permissions = permissions,
EffectivePermissions = CanHaveEffectivePermissions(principalType) ? GetEffectivePermissions(dataContainer, s, principal) : new string[0]
};
res.Add(secPerm);
}
return res.ToArray();
}
public static bool CanHaveEffectivePermissions(PrincipalType principalType)
{
if (principalType == PrincipalType.ServerRole || principalType == PrincipalType.DatabaseRole || principalType == PrincipalType.ApplicationRole)
{
return false;
}
return true;
}
internal static string[] GetEffectivePermissions(CDataContainer dataContainer, Securable securable, Principal principal)
{
var doc = ReadEffectivePermissionsXml(securable, principal);
dataContainer.Document = doc;
var dataModel = new EffectivePermissionsData(dataContainer);
List<string> res = new List<string>();
DataSet data = dataModel.QueryEffectivePermissions();
// STrace.Assert(data.Tables.Count == 1, "Unknown number of tables returned");
if (data.Tables.Count > 0)
{
DataTable table = data.Tables[0];
// STrace.Assert(table.Columns.Count >= 1 && table.Columns.Count <= 2, "Too many columns returned");
bool hasColumnInformation = dataModel.HasColumnInformation;
// loop through and add rows
foreach (DataRow row in table.Rows)
{
res.Add(row[0].ToString());
}
}
return res.ToArray();
}
/// <summary>
/// Form the xml to query effective permissions data
/// </summary>
/// <returns></returns>
private static XmlDocument ReadEffectivePermissionsXml(Securable securable, Principal principal )
{
if (securable != null && principal != null)
{
string executeas = null;
string executetype = null;
GetPrincipalToExecuteAs(principal,
securable.DatabaseName,
securable.ConnectionInfo,
out executeas,
out executetype);
// build a document
XmlDocument xml = new XmlDocument();
xml.LoadXml(launchEffectivePermissions);
xml.SelectSingleNode("/formdescription/params/urn").InnerText = securable.Urn;
xml.SelectSingleNode("/formdescription/params/servername").InnerText = ((SqlConnectionInfo)securable.ConnectionInfo).ServerName;
xml.SelectSingleNode("/formdescription/params/database").InnerText = securable.DatabaseName;
xml.SelectSingleNode("/formdescription/params/executeas").InnerText = executeas;
xml.SelectSingleNode("/formdescription/params/executetype").InnerText = executetype;
return xml;
}
return null;
}
/// <summary>
/// Create principal object for server level principals
/// </summary>
internal static Principal CreatePrincipal(bool principalExists, PrincipalType principalType, SqlSmoObject o, string? objectName, CDataContainer dataContainer)
{
if (principalExists)
{
NamedSmoObject obj = (NamedSmoObject) o;
return new Principal(obj, dataContainer.ConnectionInfo);
}
else
{
Version serverVersion = Securable.GetServerVersion(dataContainer.ConnectionInfo);
return new Principal(
objectName,
principalType,
principalExists,
dataContainer.ConnectionInfo,
serverVersion);
}
}
/// <summary>
/// Create principal object for database level principals
/// </summary>
internal static Principal CreatePrincipal(bool principalExists, PrincipalType principalType, SqlSmoObject o, string? objectName, CDataContainer dataContainer, string databaseName)
{
if (principalExists)
{
NamedSmoObject obj = (NamedSmoObject)o;
return new Principal(obj, dataContainer.ConnectionInfo);
}
else
{
Version serverVersion = Securable.GetServerVersion(dataContainer.ConnectionInfo);
DatabaseEngineType databaseEngineType = Securable.GetDatabaseEngineType(dataContainer.ConnectionInfo);
DatabaseEngineEdition databaseEngineEdition = Securable.GetDatabaseEngineEdition(dataContainer.ConnectionInfo);
return new Principal(
objectName,
databaseName,
principalType,
principalExists,
dataContainer.ConnectionInfo,
serverVersion,
databaseEngineType,
databaseEngineEdition);
}
}
public static String EscapeString(String s, string esc)
{
if (null == s)
{
return null;
}
string replace = esc + esc;
StringBuilder sb = new StringBuilder(s);
sb.Replace(esc, replace);
return sb.ToString();
}
internal static SearchableObjectType ConvertPotentialSqlObjectTypeToSearchableObjectType(string typeStr)
{
if (typeStr == ConvertSqlObjectTypeToStringValue(SqlObjectType.ApplicationRole))
{
return SearchableObjectType.ApplicationRole;
}
else if (typeStr == ConvertSqlObjectTypeToStringValue(SqlObjectType.Credential))
{
return SearchableObjectType.Credential;
}
else if (typeStr == ConvertSqlObjectTypeToStringValue(SqlObjectType.DatabaseRole))
{
return SearchableObjectType.DatabaseRole;
}
else if (typeStr == ConvertSqlObjectTypeToStringValue(SqlObjectType.ServerLevelLogin))
{
return SearchableObjectType.Login;
}
else if (typeStr == ConvertSqlObjectTypeToStringValue(SqlObjectType.ServerRole))
{
return SearchableObjectType.ServerRole;
}
else if (typeStr == ConvertSqlObjectTypeToStringValue(SqlObjectType.Table))
{
return SearchableObjectType.Table;
}
else if (typeStr == ConvertSqlObjectTypeToStringValue(SqlObjectType.User))
{
return SearchableObjectType.User;
}
else if (typeStr == ConvertSqlObjectTypeToStringValue(SqlObjectType.View))
{
return SearchableObjectType.View;
}
else
{
return ConvertStringToSearchableObjectType(typeStr);
}
}
private static string ConvertSqlObjectTypeToStringValue(SqlObjectType objectType)
{
return JsonConvert.SerializeObject(objectType).Replace("\"", "");
}
private static SearchableObjectType ConvertStringToSearchableObjectType(string typeStr)
{
foreach(SearchableObjectType t in Enum.GetValues(typeof(SearchableObjectType)))
{
if (t == SearchableObjectType.LastType)
{
continue;
}
SecurableType secType = PermissionsData.Securable.GetSecurableType(t);
SearchableObjectTypeDescription desc = SearchableObjectTypeDescription.GetDescription(t);
if (desc.DisplayTypeNameSingular == typeStr || desc.DisplayTypeNamePlural == typeStr)
{
return t;
}
}
return SearchableObjectType.LastType;
}
internal static void GetPrincipalToExecuteAs(Principal principal,
string databaseName,
object connectionInfo,
out string executeas,
out string executetype)
{
executeas = null;
executetype = null;
//
// IF we are a user AND we are mapped to a login,
// then we actually want to calculate effective
// permissions as the login, and not as the user.
// why? because that's the only way the server
// level perms will be taken into account.
//
if (principal.PrincipalType == PrincipalType.User &&
!string.IsNullOrEmpty(databaseName))
{
SqlConnectionInfoWithConnection ci = connectionInfo as SqlConnectionInfoWithConnection;
if (ci != null && ci.ServerConnection != null)
{
Server server = new Server(ci.ServerConnection);
if (server != null)
{
Database db = server.Databases[databaseName];
if (db != null)
{
User u = db.Users[principal.Name];
//
// if the the user is mapped to a certificate or
// or asymmetric key, we should execute as user.
//
if (u != null &&
(u.LoginType == LoginType.SqlLogin ||
u.LoginType == LoginType.WindowsUser ||
u.LoginType == LoginType.WindowsGroup) &&
!string.IsNullOrEmpty(u.Login))
{
executeas = u.Login;
executetype = "login";
}
}
}
}
}
//
// if we couldn't determine what type of user the principal was,
// or if the user is mapped to a certificate or asymmetric key, or if
// the principal was a login, we will default to executing as whatever
// principal type we are (either login or user).
//
if (string.IsNullOrEmpty(executeas) || string.IsNullOrEmpty(executetype))
{
executeas = principal.Name;
executetype = (principal.PrincipalType == PrincipalType.Login) ? "login" : "user";
}
}
internal static SearchableObject ConvertFromSecurableNameToSearchableObject(string securableName, string type, string database, object connectionInfo)
{
SearchableObjectType searchableObjectType = ConvertPotentialSqlObjectTypeToSearchableObjectType(type);
SearchableObjectTypeDescription desc = SearchableObjectTypeDescription.GetDescription(searchableObjectType);
var urn = desc.GetSearchUrn(securableName, true, true);
return SearchableObject.GetSearchableObject(searchableObjectType, connectionInfo, database, securableName);
}
internal static void SendToServerPermissionChanges(bool exists, string name, SecurablePermissions[] securablePermissions, Principal principal, CDataContainer dataContainer, string database)
{
if (securablePermissions == null)
{
return;
}
if (!exists)
{
foreach (SecurablePermissions secPerm in securablePermissions)
{
var securable = principal.AddSecurable(SecurableUtils.ConvertFromSecurableNameToSearchableObject(secPerm.Name, secPerm.Type, database, dataContainer.ConnectionInfo));
var states = principal.GetPermissionStates(securable);
ApplyPermissionStates(secPerm.Permissions, states);
}
}
else
{
var securables = principal.GetSecurables(new SecurableComparer(SecurableComparer.DefaultSortingOrder, true));
foreach (SecurablePermissions secPerm in securablePermissions)
{
var securable = FindMatchedSecurable(securables, secPerm.Name) ?? principal.AddSecurable(SecurableUtils.ConvertFromSecurableNameToSearchableObject(secPerm.Name, secPerm.Type, database, dataContainer.ConnectionInfo));
var states = principal.GetPermissionStates(securable);
ApplyPermissionStates(secPerm.Permissions, states);
}
var newSecurableNames = securablePermissions.Select(s => s.Name).ToHashSet();
foreach (Securable securable in securables)
{
if (!newSecurableNames.Contains(securable.Name))
{
var states = principal.GetPermissionStates(securable);
for (int i = 0; i < states.Count; i++)
{
states[i].Revoke();
}
principal.RemoveSecurable(securable);
}
}
}
principal.ApplyChanges(name, dataContainer.Server);
}
private static Securable FindMatchedSecurable(SecurableList securableList, string name)
{
foreach (Securable securable in securableList)
{
if (securable.Name == name)
{
return securable;
}
}
return null;
}
private static void ApplyPermissionStates(SecurablePermissionItem[] items, PermissionStateCollection states)
{
foreach (var p in items)
{
var key = p.Permission + p.Grantor;
if (p.WithGrant == true)
{
states[key].State = PermissionStatus.WithGrant;
}
else if (p.Grant == true)
{
states[key].State = PermissionStatus.Grant;
}
else if (p.Grant == false)
{
states[key].State = PermissionStatus.Deny;
}
else if (p.Grant == null)
{
states[key].State = PermissionStatus.Revoke;
}
}
var itemNames = items.Select(item => item.Permission).ToHashSet();
for (int i = 0; i < states.Count; i++)
{
var state = states[i];
if (!itemNames.Contains(state.Permission.Name))
{
state.State = PermissionStatus.Revoke;
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
public abstract class SecurityPrincipalObject : SqlObject
{
public SecurablePermissions[]? SecurablePermissions { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
public abstract class SecurityPrincipalViewInfo : SqlObjectViewInfo
{
public SecurableTypeMetadata[]? SupportedSecurableTypes { get; set; }
}
}

View File

@@ -71,7 +71,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
Password = "placeholder" + new Random().NextInt64(10000000, 90000000).ToString() + "!*PLACEHOLDER",
OldPassword = "placeholder" + new Random().NextInt64(10000000, 90000000).ToString() + "!*PLACEHOLDER",
DefaultLanguage = "English - us_english",
DefaultDatabase = "master"
DefaultDatabase = "master",
SecurablePermissions = new SecurablePermissions[0]
};
}
@@ -84,7 +85,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
LoginName = loginName,
Password = "placeholder" + new Random().NextInt64(10000000, 90000000).ToString() + "!*PLACEHOLDER",
DefaultSchema = "dbo",
OwnedSchemas = new string[] { "" }
OwnedSchemas = new string[] { "" },
SecurablePermissions = new SecurablePermissions[0]
};
}