using System.Diagnostics; using System.Text; using Azaion.CommonSecurity.DTO; using Azaion.CommonSecurity.DTO.Commands; using MessagePack; using NetMQ; using NetMQ.Sockets; namespace Azaion.CommonSecurity.Services; public interface IResourceLoader { MemoryStream LoadFileFromPython(string fileName); } public interface IAuthProvider { User CurrentUser { get; } } public class PythonResourceLoader : IResourceLoader, IAuthProvider { private readonly ApiCredentials _credentials; private readonly AzaionApiClient _api; private readonly DealerSocket _dealer = new(); private readonly Guid _clientId = Guid.NewGuid(); public User CurrentUser { get; } public PythonResourceLoader(ApiConfig apiConfig, ApiCredentials credentials, AzaionApiClient api) { _credentials = credentials; _api = api; //StartPython(apiConfig, credentials); _dealer.Options.Identity = Encoding.UTF8.GetBytes(_clientId.ToString("N")); _dealer.Connect($"tcp://{SecurityConstants.ZMQ_HOST}:{SecurityConstants.ZMQ_PORT}"); _dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.GetUser))); var user = _dealer.Get(); if (user == null) throw new Exception("Can't get user from Auth provider"); CurrentUser = user; } private void StartPython( ApiConfig apiConfig, ApiCredentials credentials) { using var process = new Process(); process.StartInfo = new ProcessStartInfo { FileName = SecurityConstants.AzaionInferencePath, Arguments = $"-e {credentials.Email} -p {credentials.Password} -f {apiConfig.ResourcesFolder}", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, //CreateNoWindow = true }; process.OutputDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); }; process.ErrorDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); }; process.Start(); } public async Task LoadFileFromApi(CancellationToken cancellationToken = default) { var hardwareService = new HardwareService(); var hardwareInfo = hardwareService.GetHardware(); var encryptedStream = await _api.GetResource("azaion_inference.exe", _credentials.Password, hardwareInfo, cancellationToken); var key = Security.MakeEncryptionKey(_credentials.Email, _credentials.Password, hardwareInfo.Hash); var stream = new MemoryStream(); await encryptedStream.DecryptTo(stream, key, cancellationToken); stream.Seek(0, SeekOrigin.Begin); } public MemoryStream LoadFileFromPython(string fileName) { try { _dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.Load, fileName))); if (!_dealer.TryReceiveFrameBytes(TimeSpan.FromSeconds(3), out var bytes)) throw new Exception($"Unable to receive {fileName}"); return new MemoryStream(bytes); } catch (Exception ex) { throw new Exception($"Failed to load fil0e '{fileName}': {ex.Message}", ex); } } }