Skip to content

Commit 647e298

Browse files
committed
Added new Server threat detection support
1 parent 925f2b3 commit 647e298

12 files changed

+473
-48
lines changed

src/ResourceManager/Sql/Commands.Sql/Commands.Sql.csproj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@
5151
<Prefer32Bit>false</Prefer32Bit>
5252
</PropertyGroup>
5353
<ItemGroup>
54+
<Compile Include="ThreatDetection\Cmdlet\UseAzureSqlServerThreatDetectionPolicy.cs" />
55+
<Compile Include="ThreatDetection\Cmdlet\GetAzureSqlServerThreatDetection.cs" />
56+
<Compile Include="ThreatDetection\Cmdlet\RemoveSqlServerThreatDetection.cs" />
57+
<Compile Include="ThreatDetection\Cmdlet\SetAzureSqlServerThreatDetection.cs" />
58+
<Compile Include="ThreatDetection\Cmdlet\SqlServerThreatDetectionCmdletBase.cs" />
59+
<Compile Include="ThreatDetection\Model\ServerThreatDetectionPolicyModel.cs" />
5460
<Compile Include="ThreatDetection\Cmdlet\SqlDatabaseThreatDetectionCmdletBase.cs" />
5561
<Compile Include="ThreatDetection\Cmdlet\GetAzureSqlDatabaseThreatDetection.cs" />
5662
<Compile Include="ThreatDetection\Cmdlet\SetAzureSqlDatabaseThreatDetection.cs" />
@@ -95,7 +101,7 @@
95101
<Compile Include="Auditing\Cmdlet\UseAzureSqlServerAuditingPolicy.cs" />
96102
<Compile Include="Auditing\Model\BaseAuditingPolicyModel.cs" />
97103
<Compile Include="ThreatDetection\Model\BaseThreatDetectionPolicyModel.cs" />
98-
<Compile Include="ThreatDetection\Model\DatabaseThreatDetectionPolicyModel .cs" />
104+
<Compile Include="ThreatDetection\Model\DatabaseThreatDetectionPolicyModel.cs" />
99105
<Compile Include="Auditing\Model\DatabaseAuditingPolicyModel.cs" />
100106
<Compile Include="Auditing\Model\ServerAuditingPolicyModel.cs" />
101107
<Compile Include="Auditing\Services\AuditingEndpointsCommunicator.cs" />
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System.Management.Automation;
16+
using Microsoft.Azure.Commands.Sql.ThreatDetection.Model;
17+
18+
namespace Microsoft.Azure.Commands.Sql.ThreatDetection.Cmdlet
19+
{
20+
/// <summary>
21+
/// Returns the auditing policy of a specific server.
22+
/// </summary>
23+
[Cmdlet(VerbsCommon.Get, "AzureRmSqlServerThreatDetectionPolicy"),
24+
OutputType(typeof(ServerThreatDetectionPolicyModel))]
25+
public class AzureRmSqlServerThreatDetectionPolicy : SqlServerThreatDetectionCmdletBase
26+
{
27+
/// <summary>
28+
/// No sending is needed as this is a Get cmdlet
29+
/// </summary>
30+
/// <param name="model">The model object with the data to be sent to the REST endpoints</param>
31+
protected override ServerThreatDetectionPolicyModel PersistChanges(ServerThreatDetectionPolicyModel model)
32+
{
33+
return null;
34+
}
35+
}
36+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System.Management.Automation;
16+
using Microsoft.Azure.Commands.Sql.ThreatDetection.Model;
17+
18+
namespace Microsoft.Azure.Commands.Sql.ThreatDetection.Cmdlet
19+
{
20+
/// <summary>
21+
/// Disables auditing on a specific server.
22+
/// </summary>
23+
[Cmdlet(VerbsCommon.Remove, "AzureRmSqlServerThreatDetectionPolicy"),
24+
OutputType(typeof(ServerThreatDetectionPolicyModel))]
25+
26+
public class AzureRmSqlServerThreatDetection : SqlServerThreatDetectionCmdletBase
27+
{
28+
/// <summary>
29+
/// Defines whether the cmdlets will output the model object at the end of its execution
30+
/// </summary>
31+
[Parameter(Mandatory = false)]
32+
public SwitchParameter PassThru { get; set; }
33+
34+
/// <summary>
35+
/// Returns true if the model object that was constructed by this cmdlet should be written out
36+
/// </summary>
37+
/// <returns>True if the model object should be written out, False otherwise</returns>
38+
protected override bool WriteResult() { return PassThru; }
39+
40+
/// <summary>
41+
/// Updates the given model element with the cmdlet specific operation
42+
/// </summary>
43+
/// <param name="model">A model object</param>
44+
protected override ServerThreatDetectionPolicyModel ApplyUserInputToModel(
45+
ServerThreatDetectionPolicyModel model)
46+
{
47+
model = base.ApplyUserInputToModel(model);
48+
model.ThreatDetectionState = ThreatDetectionStateType.Disabled;
49+
return model;
50+
}
51+
}
52+
}

src/ResourceManager/Sql/Commands.Sql/ThreatDetection/Cmdlet/SetAzureSqlDatabaseThreatDetection.cs

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ protected override DatabaseThreatDetectionPolicyModel ApplyUserInputToModel(Data
6868
base.ApplyUserInputToModel(model);
6969

7070
model.ThreatDetectionState = ThreatDetectionStateType.Enabled;
71+
model.UseServerDefault = UseServerDefaultOptions.Disabled;
7172

7273
if (NotificationRecipientsEmails != null)
7374
{
@@ -84,50 +85,9 @@ protected override DatabaseThreatDetectionPolicyModel ApplyUserInputToModel(Data
8485
model.ExcludedDetectionTypes = ExcludedDetectionType.Select(s => SecurityConstants.ExcludedDetectionToExcludedDetectionTypes[s]).ToArray();
8586
}
8687

87-
ValidateInput(model);
88+
model.ValidateInput();
8889

8990
return model;
9091
}
91-
92-
/// <summary>
93-
/// Preforms validity checks
94-
/// </summary>
95-
/// <param name="model">The model</param>
96-
private void ValidateInput(DatabaseThreatDetectionPolicyModel model)
97-
{
98-
// Validity checks:
99-
// 1. Check that EmailAddresses are in correct format
100-
bool areEmailAddressesInCorrectFormat = AreEmailAddressesInCorrectFormat(model.NotificationRecipientsEmails);
101-
if (!areEmailAddressesInCorrectFormat)
102-
{
103-
throw new Exception(Properties.Resources.EmailsAreNotValid);
104-
}
105-
106-
// 2. check that EmailAdmins is not False and NotificationRecipientsEmails is not empty
107-
if (!model.EmailAdmins && string.IsNullOrEmpty(model.NotificationRecipientsEmails))
108-
{
109-
throw new Exception(Properties.Resources.NeedToProvideEmail);
110-
}
111-
}
112-
113-
/// <summary>
114-
/// Checks if email addresses are in a correct format
115-
/// </summary>
116-
/// <param name="emailAddresses">The email addresses</param>
117-
/// <returns>Returns whether the email addresses are in a correct format</returns>
118-
private bool AreEmailAddressesInCorrectFormat(string emailAddresses)
119-
{
120-
if (string.IsNullOrEmpty(emailAddresses))
121-
{
122-
return true;
123-
}
124-
125-
string[] emailAddressesArray = emailAddresses.Split(';').Where(s => !string.IsNullOrEmpty(s)).ToArray();
126-
var emailRegex =
127-
new Regex(string.Format("{0}{1}",
128-
@"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))",
129-
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$"));
130-
return !emailAddressesArray.Any(e => !emailRegex.IsMatch(e));
131-
}
13292
}
13393
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using System.Linq;
17+
using System.Management.Automation;
18+
using System.Text.RegularExpressions;
19+
using Microsoft.Azure.Commands.Sql.Common;
20+
using Microsoft.Azure.Commands.Sql.ThreatDetection.Model;
21+
22+
namespace Microsoft.Azure.Commands.Sql.ThreatDetection.Cmdlet
23+
{
24+
/// <summary>
25+
/// Sets the auditing policy properties for a specific server.
26+
/// </summary>
27+
[Cmdlet(VerbsCommon.Set, "AzureRmSqlServerThreatDetectionPolicy"), OutputType(typeof(ServerThreatDetectionPolicyModel))]
28+
public class SetAzureSqlServerThreatDetection : SqlServerThreatDetectionCmdletBase
29+
{
30+
/// <summary>
31+
/// Defines whether the cmdlets will output the model object at the end of its execution
32+
/// </summary>
33+
[Parameter(Mandatory = false)]
34+
public SwitchParameter PassThru { get; set; }
35+
36+
/// <summary>
37+
/// Gets or sets the Threat Detection Email Addresses
38+
/// </summary>
39+
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "A semicolon separated list of email addresses to send the alerts to")]
40+
public string NotificationRecipientsEmails { get; set; }
41+
42+
/// <summary>
43+
/// Gets or sets the whether to email administrators
44+
/// </summary>
45+
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "Defines whether to email administrators")]
46+
[ValidateNotNullOrEmpty]
47+
public bool? EmailAdmins { get; set; }
48+
49+
/// <summary>
50+
/// Gets or sets the names of the detection types to filter.
51+
/// </summary>
52+
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "Detection types to exclude")]
53+
[ValidateSet(SecurityConstants.Successful_SQLi, SecurityConstants.Attempted_SQLi, SecurityConstants.Client_GEO_Anomaly, SecurityConstants.Failed_Logins_Anomaly, SecurityConstants.Failed_Queries_Anomaly, SecurityConstants.Data_Extraction_Anomaly, SecurityConstants.Data_Alteration_Anomaly, IgnoreCase = false)]
54+
public string[] ExcludedDetectionType { get; set; }
55+
56+
/// <summary>
57+
/// Returns true if the model object that was constructed by this cmdlet should be written out
58+
/// </summary>
59+
/// <returns>True if the model object should be written out, False otherwise</returns>
60+
protected override bool WriteResult() { return PassThru; }
61+
62+
/// <summary>
63+
/// Updates the given model element with the cmdlet specific operation
64+
/// </summary>
65+
/// <param name="model">A model object</param>
66+
protected override ServerThreatDetectionPolicyModel ApplyUserInputToModel(ServerThreatDetectionPolicyModel model)
67+
{
68+
base.ApplyUserInputToModel(model);
69+
70+
model.ThreatDetectionState = ThreatDetectionStateType.Enabled;
71+
72+
if (NotificationRecipientsEmails != null)
73+
{
74+
model.NotificationRecipientsEmails = NotificationRecipientsEmails;
75+
}
76+
77+
if (EmailAdmins != null)
78+
{
79+
model.EmailAdmins = (bool)EmailAdmins;
80+
}
81+
82+
if (ExcludedDetectionType != null)
83+
{
84+
model.ExcludedDetectionTypes = ExcludedDetectionType.Select(s => SecurityConstants.ExcludedDetectionToExcludedDetectionTypes[s]).ToArray();
85+
}
86+
87+
model.ValidateInput();
88+
89+
return model;
90+
}
91+
}
92+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Microsoft.Azure.Commands.Sql.Common;
16+
using Microsoft.Azure.Commands.Sql.Auditing.Services;
17+
using Microsoft.Azure.Commands.Sql.ThreatDetection.Model;
18+
using Microsoft.Azure.Commands.Sql.ThreatDetection.Services;
19+
using Microsoft.Azure.Common.Authentication.Models;
20+
21+
namespace Microsoft.Azure.Commands.Sql.ThreatDetection.Cmdlet
22+
{
23+
/// <summary>
24+
/// The base class for all Azure Sql Server security Management Cmdlets
25+
/// </summary>
26+
public abstract class SqlServerThreatDetectionCmdletBase : AzureSqlCmdletBase<ServerThreatDetectionPolicyModel, SqlThreatDetectionAdapter>
27+
{
28+
/// <summary>
29+
/// Provides the model element that this cmdlet operates on
30+
/// </summary>
31+
/// <returns>A model object</returns>
32+
protected override ServerThreatDetectionPolicyModel GetEntity()
33+
{
34+
return ModelAdapter.GetServerThreatDetectionPolicy(ResourceGroupName, ServerName, clientRequestId);
35+
}
36+
37+
/// <summary>
38+
/// Creation and initialization of the ModelAdapter object
39+
/// </summary>
40+
/// <param name="subscription">The AzureSubscription in which the current execution is performed</param>
41+
/// <returns>An initialized and ready to use ModelAdapter object</returns>
42+
protected override SqlThreatDetectionAdapter InitModelAdapter(AzureSubscription subscription)
43+
{
44+
return new SqlThreatDetectionAdapter(DefaultProfile.Context);
45+
}
46+
47+
/// <summary>
48+
/// This method is responsible to call the right API in the communication layer that will eventually send the information in the
49+
/// object to the REST endpoint
50+
/// </summary>
51+
/// <param name="model">The model object with the data to be sent to the REST endpoints</param>
52+
protected override ServerThreatDetectionPolicyModel PersistChanges(ServerThreatDetectionPolicyModel model)
53+
{
54+
ModelAdapter.SetServerThreatDetectionPolicy(model, clientRequestId);
55+
return null;
56+
}
57+
}
58+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Microsoft.Azure.Commands.Sql.Properties;
16+
using Microsoft.Azure.Commands.Sql.ThreatDetection.Model;
17+
using System;
18+
using System.Management.Automation;
19+
20+
namespace Microsoft.Azure.Commands.Sql.ThreatDetection.Cmdlet
21+
{
22+
/// <summary>
23+
/// Marks the given database as using its server's default policy instead of its own policy.
24+
/// </summary>
25+
[Cmdlet(VerbsOther.Use, "AzureRmSqlServerThreatDetectionPolicy"), OutputType(typeof(DatabaseThreatDetectionPolicyModel))]
26+
[Alias("Use-AzureRmSqlDatabaseServerThreatDetectionPolicy")]
27+
public class UseAzureSqlServerThreatDetectionPolicy : SqlDatabaseThreatDetectionCmdletBase
28+
{
29+
/// <summary>
30+
/// Defines whether the cmdlets will output the model object at the end of its execution
31+
/// </summary>
32+
[Parameter(Mandatory = false)]
33+
public SwitchParameter PassThru { get; set; }
34+
35+
/// <summary>
36+
/// Returns true if the model object that was constructed by this cmdlet should be written out
37+
/// </summary>
38+
/// <returns>True if the model object should be written out, False otherwise</returns>
39+
protected override bool WriteResult() { return PassThru; }
40+
41+
/// <summary>
42+
/// Updates the given model element with the cmdlet specific operation
43+
/// </summary>
44+
/// <param name="model">A model object</param>
45+
protected override DatabaseThreatDetectionPolicyModel ApplyUserInputToModel(DatabaseThreatDetectionPolicyModel model)
46+
{
47+
base.ApplyUserInputToModel(model);
48+
if (model.ThreatDetectionState == ThreatDetectionStateType.New)
49+
{
50+
model.ThreatDetectionState = ThreatDetectionStateType.Enabled;
51+
}
52+
model.UseServerDefault = UseServerDefaultOptions.Enabled;
53+
return model;
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)