diff --git a/examples/WireMock.Net.ConsoleApplication/Program.cs b/examples/WireMock.Net.ConsoleApplication/Program.cs
index b4c83630..cf0be467 100644
--- a/examples/WireMock.Net.ConsoleApplication/Program.cs
+++ b/examples/WireMock.Net.ConsoleApplication/Program.cs
@@ -19,6 +19,8 @@ namespace WireMock.Net.ConsoleApplication
var server = FluentMockServer.StartWithAdminInterface(url1, url2, url3);
Console.WriteLine("FluentMockServer listening at {0}", string.Join(" and ", server.Urls));
+ server.SetBasicAuthentication("a", "b");
+
server.AllowPartialMapping();
server
diff --git a/src/WireMock.Net/Mapping.cs b/src/WireMock.Net/Mapping.cs
index 5f34c262..ef24c85c 100644
--- a/src/WireMock.Net/Mapping.cs
+++ b/src/WireMock.Net/Mapping.cs
@@ -73,5 +73,13 @@ namespace WireMock
return result;
}
+
+ ///
+ /// Gets a value indicating whether this mapping is an Admin Interface.
+ ///
+ ///
+ /// true if this mapping is an Admin Interface; otherwise, false.
+ ///
+ public bool IsAdminInterface => Provider is DynamicResponseProvider;
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
index 24deb393..a45ba100 100644
--- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
@@ -142,7 +142,7 @@ namespace WireMock.Server
return new ResponseMessage { StatusCode = 500, Body = e.ToString() };
}
- return new ResponseMessage { Body = "Mapping added" };
+ return new ResponseMessage { StatusCode = 201, Body = "Mapping added" };
}
private void DeserializeAndAddMapping(string json, Guid? guid = null)
diff --git a/src/WireMock.Net/Server/FluentMockServer.cs b/src/WireMock.Net/Server/FluentMockServer.cs
index 64d2c3c1..6abb300b 100644
--- a/src/WireMock.Net/Server/FluentMockServer.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.cs
@@ -4,10 +4,12 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
+using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Http;
using WireMock.Logging;
+using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Validation;
@@ -34,22 +36,27 @@ namespace WireMock.Server
private bool _allowPartialMapping;
+ private IMatcher _authorizationMatcher;
+
///
/// Gets the ports.
///
///
/// The ports.
///
+ [PublicAPI]
public List Ports { get; }
///
/// Gets the urls.
///
+ [PublicAPI]
public string[] Urls { get; }
///
/// Gets the request logs.
///
+ [PublicAPI]
public IEnumerable LogEntries
{
get
@@ -64,6 +71,7 @@ namespace WireMock.Server
///
/// Gets the mappings.
///
+ [PublicAPI]
public IEnumerable Mappings
{
get
@@ -159,6 +167,7 @@ namespace WireMock.Server
///
/// Stop this server.
///
+ [PublicAPI]
public void Stop()
{
_httpServer.Stop();
@@ -167,6 +176,7 @@ namespace WireMock.Server
///
/// Resets LogEntries and Mappings.
///
+ [PublicAPI]
public void Reset()
{
ResetLogEntries();
@@ -177,6 +187,7 @@ namespace WireMock.Server
///
/// Resets the LogEntries.
///
+ [PublicAPI]
public void ResetLogEntries()
{
lock (((ICollection)_logEntries).SyncRoot)
@@ -209,6 +220,7 @@ namespace WireMock.Server
///
/// Resets the Mappings.
///
+ [PublicAPI]
public void ResetMappings()
{
lock (((ICollection)_mappings).SyncRoot)
@@ -243,6 +255,7 @@ namespace WireMock.Server
///
/// The matcher.
/// The .
+ [PublicAPI]
public IEnumerable SearchLogsFor(IRequestMatcher matcher)
{
lock (((ICollection)_logEntries).SyncRoot)
@@ -258,6 +271,7 @@ namespace WireMock.Server
///
/// The delay.
///
+ [PublicAPI]
public void AddRequestProcessingDelay(TimeSpan delay)
{
lock (_syncRoot)
@@ -269,6 +283,7 @@ namespace WireMock.Server
///
/// Allows the partial mapping.
///
+ [PublicAPI]
public void AllowPartialMapping()
{
lock (_syncRoot)
@@ -277,11 +292,27 @@ namespace WireMock.Server
}
}
+ ///
+ /// Sets the basic authentication.
+ ///
+ /// The username.
+ /// The password.
+ [PublicAPI]
+ public void SetBasicAuthentication([NotNull] string username, [NotNull] string password)
+ {
+ Check.NotNull(username, nameof(username));
+ Check.NotNull(password, nameof(password));
+
+ string authorization = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
+ _authorizationMatcher = new RegexMatcher("^(?i)BASIC " + authorization + "$");
+ }
+
///
/// The given.
///
/// The request matcher.
/// The .
+ [PublicAPI]
public IRespondWithAProvider Given(IRequestMatcher requestMatcher)
{
return new RespondWithAProvider(RegisterMapping, requestMatcher);
@@ -344,10 +375,7 @@ namespace WireMock.Server
if (_allowPartialMapping)
{
var partialMappings = mappings
- .Where(pm =>
- (pm.Mapping.Provider is DynamicResponseProvider && pm.MatchResult.IsPerfectMatch) ||
- !(pm.Mapping.Provider is DynamicResponseProvider)
- )
+ .Where(pm => pm.Mapping.IsAdminInterface && pm.MatchResult.IsPerfectMatch || !pm.Mapping.IsAdminInterface)
.OrderBy(m => m.MatchResult)
.ThenBy(m => m.Mapping.Priority)
.ToList();
@@ -369,24 +397,26 @@ namespace WireMock.Server
if (targetMapping == null)
{
- response = new ResponseMessage
- {
- StatusCode = 404,
- Body = "No mapping found"
- };
+ response = new ResponseMessage { StatusCode = 404, Body = "No mapping found" };
+ return;
}
- else
+
+ if (targetMapping.IsAdminInterface && _authorizationMatcher != null)
{
- response = await targetMapping.ResponseTo(request);
+ string authorization;
+ bool present = request.Headers.TryGetValue("Authorization", out authorization);
+ if (!present || _authorizationMatcher.IsMatch(authorization) < 1.0)
+ {
+ response = new ResponseMessage { StatusCode = 401 };
+ return;
+ }
}
+
+ response = await targetMapping.ResponseTo(request);
}
catch (Exception ex)
{
- response = new ResponseMessage
- {
- StatusCode = 500,
- Body = ex.ToString()
- };
+ response = new ResponseMessage { StatusCode = 500, Body = ex.ToString() };
}
finally
{
@@ -406,4 +436,4 @@ namespace WireMock.Server
}
}
}
-}
+}
\ No newline at end of file