Skip to content

Commit 81adaec

Browse files
committed
Add source and site instance information to secret files. Fixes #2094
1 parent 9323241 commit 81adaec

File tree

5 files changed

+50
-11
lines changed

5 files changed

+50
-11
lines changed

src/WebJobs.Script.WebHost/Security/ScriptSecrets.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
using System;
55
using System.Collections;
66
using System.Collections.Generic;
7+
using System.Globalization;
78
using System.Linq;
89
using System.Text;
910
using System.Threading.Tasks;
11+
using Microsoft.Azure.WebJobs.Script.Config;
1012
using Newtonsoft.Json;
1113

1214
namespace Microsoft.Azure.WebJobs.Script.WebHost
@@ -15,6 +17,9 @@ public abstract class ScriptSecrets
1517
{
1618
protected ScriptSecrets()
1719
{
20+
HostName = ScriptSettingsManager.Instance.GetSetting(EnvironmentSettingNames.AzureWebsiteHostName);
21+
InstanceId = ScriptSettingsManager.Instance.InstanceId;
22+
Source = ScriptConstants.Runtime;
1823
}
1924

2025
[JsonIgnore]
@@ -23,6 +28,15 @@ protected ScriptSecrets()
2328
[JsonIgnore]
2429
public abstract ScriptSecretsType SecretsType { get; }
2530

31+
[JsonProperty(PropertyName = "hostName")]
32+
public string HostName { get; set; }
33+
34+
[JsonProperty(PropertyName = "instanceId")]
35+
public string InstanceId { get; set; }
36+
37+
[JsonProperty(PropertyName = "source")]
38+
public string Source { get; set; }
39+
2640
protected abstract ICollection<Key> GetKeys(string keyScope);
2741

2842
public abstract ScriptSecrets Refresh(IKeyValueConverterFactory factory);

src/WebJobs.Script/Config/ScriptSettingsManager.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ public virtual string AzureWebsiteUniqueSlotName
6868
}
6969
}
7070

71+
public virtual string InstanceId
72+
{
73+
get
74+
{
75+
string instanceId = GetSetting(EnvironmentSettingNames.AzureWebsiteInstanceId)
76+
?? Environment.MachineName.GetHashCode().ToString("X").PadLeft(32, '0');
77+
78+
return instanceId.Substring(0, 32);
79+
}
80+
}
81+
7182
public virtual string ApplicationInsightsInstrumentationKey
7283
{
7384
get => GetSettingFromCache(EnvironmentSettingNames.AppInsightsInstrumentationKey);

src/WebJobs.Script/Host/ScriptHost.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,7 @@ public string InstanceId
114114
{
115115
if (_instanceId == null)
116116
{
117-
_instanceId = _settingsManager.GetSetting(EnvironmentSettingNames.AzureWebsiteInstanceId)
118-
?? Environment.MachineName.GetHashCode().ToString("X").PadLeft(32, '0');
119-
120-
_instanceId = _instanceId.Substring(0, 32);
117+
_instanceId = _settingsManager.InstanceId;
121118
}
122119

123120
return _instanceId;

src/WebJobs.Script/ScriptConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public static class ScriptConstants
7474
public const string HttpMethodConstraintName = "httpMethod";
7575
public static readonly ImmutableArray<string> AssemblyFileTypes = ImmutableArray.Create(".dll", ".exe");
7676
public const string SwaggerDocumentationKey = "swaggerdocumentationkey";
77+
public const string Runtime = "runtime";
7778

7879
public const int MaximumHostIdLength = 32;
7980
public const int DynamicSkuConnectionLimit = 50;

test/WebJobs.Script.Tests/Security/ScriptSecretSerializerV1Tests.cs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Linq;
7+
using Microsoft.Azure.WebJobs.Script.Config;
78
using Microsoft.Azure.WebJobs.Script.WebHost;
89
using Newtonsoft.Json.Linq;
910
using Xunit;
@@ -40,16 +41,23 @@ public void SerializeFunctionSecrets_ReturnsExpectedResult()
4041

4142
var jsonObject = JObject.Parse(serializedSecret);
4243
var serializedSecrets = jsonObject.Property("keys")?.Value?.ToObject<List<Key>>();
44+
var source = jsonObject.Property("source")?.Value;
45+
var hostName = jsonObject.Property("hostName")?.Value;
46+
var instanceId = jsonObject.Property("instanceId")?.Value;
4347

4448
Assert.NotNull(serializedSecret);
4549
AssertKeyCollectionsEquality(secrets.Keys, serializedSecrets);
50+
Assert.Equal(source, secrets.Source);
51+
Assert.Equal(hostName, secrets.HostName);
52+
Assert.Equal(instanceId, secrets.InstanceId);
4653
}
4754

48-
[Fact]
49-
public void DeserializeFunctionSecrets_ReturnsExpectedResult()
55+
[Theory]
56+
[InlineData("{ 'keys': [ { 'name': 'Key1', 'value': 'Value1', 'encrypted': false }, { 'name': 'Key2', 'value': 'Value2', 'encrypted': true } ] }", null)]
57+
[InlineData("{ 'keys': [ { 'name': 'Key1', 'value': 'Value1', 'encrypted': false }, { 'name': 'Key2', 'value': 'Value2', 'encrypted': true } ], 'hostName': 'test', 'source': 'runtime'}", "test")]
58+
public void DeserializeFunctionSecrets_ReturnsExpectedResult(string serializedSecret, string hostName)
5059
{
5160
var serializer = new ScriptSecretSerializerV1();
52-
var serializedSecret = "{ 'keys': [ { 'name': 'Key1', 'value': 'Value1', 'encrypted': false }, { 'name': 'Key2', 'value': 'Value2', 'encrypted': true } ] }";
5361
var expected = new List<Key>
5462
{
5563
new Key
@@ -67,14 +75,16 @@ public void DeserializeFunctionSecrets_ReturnsExpectedResult()
6775
};
6876

6977
FunctionSecrets actual = serializer.DeserializeSecrets<FunctionSecrets>(JObject.Parse(serializedSecret));
78+
Assert.Equal(hostName, actual.HostName);
7079
AssertKeyCollectionsEquality(expected, actual.Keys);
7180
}
7281

73-
[Fact]
74-
public void DeserializeHostSecrets_ReturnsExpectedResult()
82+
[Theory]
83+
[InlineData("{'masterKey':{'name':'master','value':'1234','encrypted':false},'functionKeys':[{'name':'Key1','value':'Value1','encrypted':false},{'name':'Key2','value':'Value2','encrypted':true}]}", null)]
84+
[InlineData("{'masterKey':{'name':'master','value':'1234','encrypted':false},'functionKeys':[{'name':'Key1','value':'Value1','encrypted':false},{'name':'Key2','value':'Value2','encrypted':true}], 'hostName': 'test', 'source': 'runtime' }", "test")]
85+
public void DeserializeHostSecrets_ReturnsExpectedResult(string serializedSecret, string hostName)
7586
{
7687
var serializer = new ScriptSecretSerializerV1();
77-
var serializedSecret = "{'masterKey':{'name':'master','value':'1234','encrypted':false},'functionKeys':[{'name':'Key1','value':'Value1','encrypted':false},{'name':'Key2','value':'Value2','encrypted':true}]}";
7888
var expected = new HostSecrets
7989
{
8090
MasterKey = new Key { Name = "master", Value = "1234" },
@@ -92,13 +102,16 @@ public void DeserializeHostSecrets_ReturnsExpectedResult()
92102
Value = "Value2",
93103
IsEncrypted = true
94104
}
95-
}
105+
},
106+
HostName = hostName
96107
};
97108

98109
HostSecrets actual = serializer.DeserializeSecrets<HostSecrets>(JObject.Parse(serializedSecret));
99110

100111
Assert.NotNull(actual);
101112
Assert.Equal(expected.MasterKey, actual.MasterKey);
113+
Assert.Equal(actual.HostName, hostName);
114+
Assert.Equal(expected.Source, ScriptConstants.Runtime);
102115
AssertKeyCollectionsEquality(expected.FunctionKeys, actual.FunctionKeys);
103116
}
104117

@@ -132,17 +145,20 @@ public void SerializeHostSecrets_ReturnsExpectedResult()
132145
var jsonObject = JObject.Parse(serializedSecret);
133146
var functionSecrets = jsonObject.Property("functionKeys")?.Value?.ToObject<List<Key>>();
134147
var masterKey = jsonObject.Property("masterKey")?.Value?.ToObject<Key>();
148+
var instanceId = jsonObject.Property("instanceId")?.Value;
135149

136150
Assert.NotNull(serializedSecret);
137151
Assert.Equal(secrets.MasterKey, masterKey);
138152
AssertKeyCollectionsEquality(secrets.FunctionKeys, functionSecrets);
153+
Assert.Equal(instanceId, secrets.InstanceId);
139154
}
140155

141156
[Theory]
142157
[InlineData(typeof(HostSecrets), false, "{'masterKey': 'masterKeySecretString','functionKey': 'functionKeySecretString'}")]
143158
[InlineData(typeof(FunctionSecrets), false, "{'key':'functionKeySecretString'}")]
144159
[InlineData(typeof(HostSecrets), true, "{'masterKey': {'name': 'master','value': '1234','encrypted': false},'functionKeys': [{'name': 'Key1','value': 'Value1','encrypted': false},{'name': 'Key2','value': 'Value2','encrypted': true}]}")]
145160
[InlineData(typeof(FunctionSecrets), true, "{'keys': [{'name': 'Key1','value': 'Value1','encrypted': false},{'name': 'Key2','value': 'Value2','encrypted': true}]}")]
161+
[InlineData(typeof(HostSecrets), false, "{'masterKey': 'masterKeySecretString','functionKey': 'functionKeySecretString', 'hostName': 'test1', 'instanceId': 'test2', 'source': 'test3'}")]
146162
public void CanSerialize_WithValidHostPayload_ReturnsTrue(Type type, bool expectedResult, string input)
147163
{
148164
var serializer = new ScriptSecretSerializerV1();

0 commit comments

Comments
 (0)