Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(repeater): refrain from utilizing non standard ports #166

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/SecTester.Core/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
{
private readonly Regex _schemaRegex = new(@"^.+:\/\/");
private readonly Regex _hostnameNormalizationRegex = new(@"^(?!(?:\w+:)?\/\/)|^\/\/");
private readonly string[] _loopbackAddresses = { "localhost", "127.0.0.1" };
private readonly string[] _loopbackAddresses = { "localhost", "127.0.0.1", "::1" };
private readonly List<ICredentialProvider> _credentialProviders;

public string Bus { get; private set; }
Expand All @@ -32,7 +32,7 @@
public string Version { get; }
public string RepeaterVersion { get; } = "10.0.0";

public Configuration(string? hostname, Credentials? credentials = null, IEnumerable<ICredentialProvider>? credentialProviders = null,

Check warning on line 35 in src/SecTester.Core/Configuration.cs

View workflow job for this annotation

GitHub Actions / windows-2019

Non-nullable property 'Bus' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 35 in src/SecTester.Core/Configuration.cs

View workflow job for this annotation

GitHub Actions / windows-2019

Non-nullable property 'Api' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
LogLevel logLevel = LogLevel.Error)
{
Version = FileVersionInfo.GetVersionInfo(GetType().Assembly.Location).ProductVersion;
Expand Down
6 changes: 3 additions & 3 deletions src/SecTester.Repeater/Api/CreateRepeaterRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
using System.Text;
using SecTester.Bus.Commands;
using SecTester.Bus.Dispatchers;
using SecTester.Core;

namespace SecTester.Repeater.Api;

internal record CreateRepeaterRequest : HttpRequest<Unit>
internal record CreateRepeaterRequest : HttpRequest<RepeaterIdentity>
{
public CreateRepeaterRequest(string name, string? description) :
base("/api/v1/repeaters", HttpMethod.Post, expectReply: false)
{
var data = new
{
Name = name,
Description = description
Description = description,
ClientRole = "dev-centric"
};
var content = MessageSerializer.Serialize(data);
Body = new StringContent(content, Encoding.UTF8, "application/json");
Expand Down
14 changes: 2 additions & 12 deletions src/SecTester.Repeater/Api/DefaultRepeaters.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using SecTester.Core.Bus;
using SecTester.Core.Exceptions;
Expand All @@ -17,13 +15,11 @@ public DefaultRepeaters(ICommandDispatcher commandDispatcher)

public async Task<string> CreateRepeater(string name, string? description = default)
{
await _commandDispatcher.Execute(new CreateRepeaterRequest(name, description)).ConfigureAwait(false);

var repeaterId = (await FindRepeaterByName(name).ConfigureAwait(false))?.Id;
var repeaterId = (await _commandDispatcher.Execute(new CreateRepeaterRequest(name, description)).ConfigureAwait(false))?.Id;

if (string.IsNullOrEmpty(repeaterId))
{
throw new SecTesterException("Cannot find created repeater id");
throw new SecTesterException("Cannot create repeater");
}

return repeaterId!;
Expand All @@ -35,10 +31,4 @@ await _commandDispatcher.Execute(
new DeleteRepeaterRequest(repeaterId)
).ConfigureAwait(false);
}

private async Task<RepeaterIdentity?> FindRepeaterByName(string name)
{
var repeaters = await _commandDispatcher.Execute(new ListRepeatersRequest()).ConfigureAwait(false);
return repeaters?.FirstOrDefault(repeater => repeater.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
}
}
6 changes: 0 additions & 6 deletions src/SecTester.Repeater/Api/ListRepeatersRequest.cs

This file was deleted.

3 changes: 1 addition & 2 deletions src/SecTester.Repeater/Api/RepeaterIdentity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

namespace SecTester.Repeater.Api;

internal record RepeaterIdentity(string Id, string Name)
internal record RepeaterIdentity(string Id)
{
public string Id { get; } = Id ?? throw new ArgumentNullException(nameof(Id));
public string Name { get; } = Name ?? throw new ArgumentNullException(nameof(Name));
}
57 changes: 57 additions & 0 deletions src/SecTester.Repeater/Bus/DefaultRepeaterBusFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SecTester.Core;
using SecTester.Core.Utils;
using SocketIO.Serializer.MessagePack;
using SocketIOClient;

namespace SecTester.Repeater.Bus;

public class DefaultRepeaterBusFactory : IRepeaterBusFactory
{
private readonly Configuration _config;
private readonly ILoggerFactory _loggerFactory;
private readonly IServiceScopeFactory _scopeFactory;

public DefaultRepeaterBusFactory(Configuration config, ILoggerFactory loggerFactory, IServiceScopeFactory scopeFactory)
{
_config = config ?? throw new ArgumentNullException(nameof(config));
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
_scopeFactory = scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory));
}

public IRepeaterBus Create(string repeaterId)
{
if (_config.Credentials is null)
{
throw new InvalidOperationException(
"Please provide credentials to establish a connection with the bus."
);
}

var url = new Uri(_config.Api);
var options = new SocketIoRepeaterBusOptions(url);
var client = new SocketIOClient.SocketIO(url, new SocketIOOptions
{
Path = options.Path,
ReconnectionAttempts = options.ReconnectionAttempts,
ReconnectionDelayMax = options.ReconnectionDelayMax,
ConnectionTimeout = options.ConnectionTimeout,
Auth = new List<KeyValuePair<string, string>>
{
new("token", _config.Credentials.Token), new("domain", repeaterId)
},
})
{
Serializer = new SocketIOMessagePackSerializer()
};
var wrapper = new SocketIoClientWrapper(client);

var scope = _scopeFactory.CreateAsyncScope();
var timerProvider = scope.ServiceProvider.GetRequiredService<ITimerProvider>();

return new SocketIoRepeaterBus(options, wrapper, timerProvider, _loggerFactory.CreateLogger<IRepeaterBus>());
}
}
38 changes: 0 additions & 38 deletions src/SecTester.Repeater/Bus/DefaultRepeaterEventBusFactory.cs

This file was deleted.

15 changes: 15 additions & 0 deletions src/SecTester.Repeater/Bus/IRepeaterBus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Threading;
using System.Threading.Tasks;

namespace SecTester.Repeater.Bus;

public interface IRepeaterBus : IAsyncDisposable
{
event Func<IncomingRequest, Task<OutgoingResponse>> RequestReceived;
event Action<Exception> ErrorOccurred;
event Action<Version> UpgradeAvailable;

Task Connect();
Task Deploy(string repeaterId, CancellationToken? cancellationToken = null);
}
6 changes: 6 additions & 0 deletions src/SecTester.Repeater/Bus/IRepeaterBusFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace SecTester.Repeater.Bus;

public interface IRepeaterBusFactory
{
IRepeaterBus Create(string repeaterId);
}
8 changes: 0 additions & 8 deletions src/SecTester.Repeater/Bus/IRepeaterEventBusFactory.cs

This file was deleted.

14 changes: 14 additions & 0 deletions src/SecTester.Repeater/Bus/ISocketIoClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Threading.Tasks;

namespace SecTester.Repeater.Bus;

internal interface ISocketIoClient : IDisposable
{
public bool Connected { get; }
public Task Connect();
public Task Disconnect();
public void On(string eventName, Action<ISocketIoResponse> callback);
public void Off(string eventName);
public Task EmitAsync(string eventName, params object[] data);
}
11 changes: 11 additions & 0 deletions src/SecTester.Repeater/Bus/ISocketIoResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Threading;
using System.Threading.Tasks;

namespace SecTester.Repeater.Bus;

internal interface ISocketIoResponse
{
public T GetValue<T>(int i = 0);
public Task CallbackAsync(params object[] data);
public Task CallbackAsync(CancellationToken cancellationToken, params object[] data);
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using SecTester.Core.Bus;
using SecTester.Repeater.Runners;

namespace SecTester.Repeater.Bus;

[MessageType(name: "ExecuteScript")]
public record RequestExecutingEvent(Uri Url) : Event, IRequest
public record IncomingRequest(Uri Url) : Event, IRequest
{
public string? Body { get; init; }
[JsonPropertyName("correlation_id_regex")]
public Regex? CorrelationIdRegex { get; init; }
public HttpMethod Method { get; init; } = HttpMethod.Get;
public Protocol Protocol { get; init; } = Protocol.Http;
public Uri Url { get; init; } = Url ?? throw new ArgumentNullException(nameof(Url));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using SecTester.Repeater.Runners;

namespace SecTester.Repeater.Bus;

public record RequestExecutingResult : IResponse
public record OutgoingResponse : IResponse
{
[JsonPropertyName("status_code")] public int? StatusCode { get; init; }
public int? StatusCode { get; init; }

public string? Body { get; init; }
public string? Message { get; init; }

[JsonPropertyName("error_code")] public string? ErrorCode { get; init; }
public string? ErrorCode { get; init; }

public Protocol Protocol { get; init; } = Protocol.Http;

Expand Down
6 changes: 0 additions & 6 deletions src/SecTester.Repeater/Bus/RegisterRepeaterCommand.cs

This file was deleted.

3 changes: 0 additions & 3 deletions src/SecTester.Repeater/Bus/RegisterRepeaterPayload.cs

This file was deleted.

3 changes: 0 additions & 3 deletions src/SecTester.Repeater/Bus/RegisterRepeaterResult.cs

This file was deleted.

10 changes: 0 additions & 10 deletions src/SecTester.Repeater/Bus/RepeaterRegisteringError.cs

This file was deleted.

6 changes: 0 additions & 6 deletions src/SecTester.Repeater/Bus/RepeaterStatusEvent.cs

This file was deleted.

30 changes: 0 additions & 30 deletions src/SecTester.Repeater/Bus/RequestExecutingEventListener.cs

This file was deleted.

29 changes: 29 additions & 0 deletions src/SecTester.Repeater/Bus/SocketIoClientWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Threading.Tasks;

namespace SecTester.Repeater.Bus;

internal sealed class SocketIoClientWrapper : ISocketIoClient
{
private readonly SocketIOClient.SocketIO _socketIo;

public SocketIoClientWrapper(SocketIOClient.SocketIO socketIo) => _socketIo = socketIo ?? throw new ArgumentNullException(nameof(socketIo));

public void Dispose()
{
_socketIo.Dispose();
GC.SuppressFinalize(this);
}

public bool Connected => _socketIo.Connected;

public Task Connect() => _socketIo.ConnectAsync();

public Task Disconnect() => _socketIo.DisconnectAsync();

public void On(string eventName, Action<ISocketIoResponse> callback) => _socketIo.On(eventName, x => callback(x as ISocketIoResponse));

Check warning on line 24 in src/SecTester.Repeater/Bus/SocketIoClientWrapper.cs

View workflow job for this annotation

GitHub Actions / windows-2019

Possible null reference argument for parameter 'obj' in 'void Action<ISocketIoResponse>.Invoke(ISocketIoResponse obj)'.

public void Off(string eventName) => _socketIo.Off(eventName);

public Task EmitAsync(string eventName, params object[] data) => _socketIo.EmitAsync(eventName, data);
}
Loading
Loading