Skip to content

Commit fa14eec

Browse files
committed
Allow Internal Auth for SyncTriggers
1 parent f887558 commit fa14eec

File tree

3 files changed

+65
-17
lines changed

3 files changed

+65
-17
lines changed

src/WebJobs.Script.WebHost/Controllers/AdminController.cs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,7 @@ public FunctionStatus GetFunctionStatus(string name)
106106
[EnableDebugMode]
107107
public IHttpActionResult GetHostStatus()
108108
{
109-
var authorizationLevel = Request.GetAuthorizationLevel();
110-
if (Request.IsAuthDisabled() ||
111-
authorizationLevel == AuthorizationLevel.Admin ||
112-
Request.IsAntaresInternalRequest())
109+
if (Request.IsAuthDisabled() || Request.IsAdminOrInternalRequest())
113110
{
114111
var status = new HostStatus
115112
{
@@ -159,10 +156,7 @@ public IHttpActionResult Log(IEnumerable<HostLogEntry> logEntries)
159156
return BadRequest("An array of log entry objects is expected.");
160157
}
161158

162-
var authorizationLevel = Request.GetAuthorizationLevel();
163-
if (Request.IsAuthDisabled() ||
164-
authorizationLevel == AuthorizationLevel.Admin ||
165-
Request.IsAntaresInternalRequest())
159+
if (Request.IsAuthDisabled() || Request.IsAdminOrInternalRequest())
166160
{
167161
foreach (var logEntry in logEntries)
168162
{
@@ -212,18 +206,26 @@ public HttpResponseMessage LaunchDebugger()
212206

213207
[HttpPost]
214208
[Route("admin/host/synctriggers")]
209+
[AllowAnonymous]
215210
public async Task<HttpResponseMessage> SyncTriggers()
216211
{
217-
var result = await _functionsSyncManager.TrySyncTriggersAsync();
218-
219-
// Return a dummy body to make it valid in ARM template action evaluation
220-
var statusCode = result.Success ? HttpStatusCode.OK : HttpStatusCode.InternalServerError;
221-
var responseContent = new JObject
212+
if (Request.IsAuthDisabled() || Request.IsAdminOrInternalRequest())
222213
{
223-
{ "status", result.Success ? "success" : result.Error }
224-
};
214+
var result = await _functionsSyncManager.TrySyncTriggersAsync();
215+
216+
// Return a dummy body to make it valid in ARM template action evaluation
217+
var statusCode = result.Success ? HttpStatusCode.OK : HttpStatusCode.InternalServerError;
218+
var responseContent = new JObject
219+
{
220+
{ "status", result.Success ? "success" : result.Error }
221+
};
225222

226-
return Request.CreateResponse(statusCode, responseContent);
223+
return Request.CreateResponse(statusCode, responseContent);
224+
}
225+
else
226+
{
227+
return Request.CreateResponse(HttpStatusCode.Unauthorized);
228+
}
227229
}
228230

229231
[Route("admin/extensions/{name}/{*extra}")]

src/WebJobs.Script/Extensions/HttpRequestMessageExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ public static bool IsAntaresInternalRequest(this HttpRequestMessage request)
7373
return !request.Headers.Contains(ScriptConstants.AntaresLogIdHeaderName);
7474
}
7575

76+
public static bool IsAdminOrInternalRequest(this HttpRequestMessage request)
77+
{
78+
var authorizationLevel = request.GetAuthorizationLevel();
79+
return authorizationLevel == AuthorizationLevel.Admin || request.IsAntaresInternalRequest();
80+
}
81+
7682
public static bool IsAuthDisabled(this HttpRequestMessage request)
7783
{
7884
return request.GetRequestPropertyOrDefault<bool>(ScriptConstants.AzureFunctionsHttpRequestAuthorizationDisabledKey);

test/WebJobs.Script.Tests.Integration/SamplesEndToEndTests.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,21 @@
1414
using System.Threading.Tasks;
1515
using System.Web.Http;
1616
using System.Xml.Linq;
17+
using Autofac;
1718
using Microsoft.Azure.WebJobs.Host;
1819
using Microsoft.Azure.WebJobs.Script.Config;
1920
using Microsoft.Azure.WebJobs.Script.Tests.Properties;
2021
using Microsoft.Azure.WebJobs.Script.WebHost;
2122
using Microsoft.Azure.WebJobs.Script.WebHost.Filters;
23+
using Microsoft.Azure.WebJobs.Script.WebHost.Management;
2224
using Microsoft.Azure.WebJobs.Script.WebHost.Models;
2325
using Microsoft.ServiceBus;
2426
using Microsoft.ServiceBus.Messaging;
2527
using Microsoft.WindowsAzure.Storage;
2628
using Microsoft.WindowsAzure.Storage.Blob;
2729
using Microsoft.WindowsAzure.Storage.Queue;
2830
using Microsoft.WindowsAzure.Storage.Table;
31+
using Moq;
2932
using Newtonsoft.Json;
3033
using Newtonsoft.Json.Linq;
3134
using Xunit;
@@ -37,6 +40,7 @@ namespace Microsoft.Azure.WebJobs.Script.Tests
3740
public class SamplesEndToEndTests : IClassFixture<SamplesEndToEndTests.TestFixture>
3841
{
3942
internal const string MasterKey = "t8laajal0a1ajkgzoqlfv5gxr4ebhqozebw4qzdy";
43+
private const string TestInstanceId = "a03948aa41d0c354ce659d273031a12c9b5755727cb9f66c1b4792a0cd3c5998";
4044

4145
private readonly ScriptSettingsManager _settingsManager;
4246
private TestFixture _fixture;
@@ -226,6 +230,37 @@ public async Task Home_Get_InAzureEnvironment_AsInternalRequest_ReturnsNoContent
226230
}
227231
}
228232

233+
[Fact]
234+
public async Task SyncTriggers_AdminAuth_Succeeds()
235+
{
236+
string uri = "admin/host/synctriggers";
237+
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
238+
request.Headers.Add(AuthorizationLevelAttribute.FunctionsKeyHeaderName, MasterKey);
239+
HttpResponseMessage response = await this._fixture.HttpClient.SendAsync(request);
240+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
241+
}
242+
243+
[Fact]
244+
public async Task SyncTriggers_InternalAuth_Succeeds()
245+
{
246+
using (new TestScopedSettings(_settingsManager, EnvironmentSettingNames.AzureWebsiteInstanceId, "testinstance"))
247+
{
248+
string uri = "admin/host/synctriggers";
249+
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
250+
HttpResponseMessage response = await this._fixture.HttpClient.SendAsync(request);
251+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
252+
}
253+
}
254+
255+
[Fact]
256+
public async Task SyncTriggers_ExternalUnauthorized_ReturnsUnauthorized()
257+
{
258+
string uri = "admin/host/synctriggers";
259+
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
260+
HttpResponseMessage response = await this._fixture.HttpClient.SendAsync(request);
261+
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
262+
}
263+
229264
[Fact]
230265
public async Task HttpTrigger_CSharp_Poco_Post_Succeeds()
231266
{
@@ -1178,7 +1213,12 @@ public TestFixture()
11781213
SecretsPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\..\src\WebJobs.Script.WebHost\App_Data\Secrets"),
11791214
TraceWriter = _traceWriter
11801215
};
1181-
WebApiConfig.Register(_config, _settingsManager, HostSettings);
1216+
WebApiConfig.Register(_config, _settingsManager, HostSettings, (builder, settings) =>
1217+
{
1218+
var syncManagerMock = new Mock<IFunctionsSyncManager>(MockBehavior.Strict);
1219+
syncManagerMock.Setup(p => p.TrySyncTriggersAsync(It.IsAny<bool>())).ReturnsAsync(new SyncTriggersResult { Success = true });
1220+
builder.Register<IFunctionsSyncManager>(_ => syncManagerMock.Object);
1221+
});
11821222

11831223
HttpServer = new HttpServer(_config);
11841224
HttpClient = new HttpClient(HttpServer);

0 commit comments

Comments
 (0)