private void ReplicationWorker(object param) { var cancelationToken = (CancellationToken)param; while (!cancelationToken.IsCancellationRequested) { if (_arbitrationServiceProvider?.State == ServiceState.Hot) { try { if (_replicatorProxy != null) { while (!_replicationQueue.IsEmpty) { // Check connection before replicating to keep replication data // on queue in case backup service fails _replicatorProxy.CheckState(); if (_replicationQueue.TryDequeue(out var replicationItem)) { _replicatorProxy.ReplicateData(replicationItem); } } } else { _replicatorProxy = CreateReplicatorProxy(); if (_replicatorProxy?.CheckState() == ServiceState.Standby) { Console.WriteLine( $"Replicator proxy to {_replicatorProxyFactory.Endpoint.Address} opened."); } else { Thread.Sleep(100); } } } catch (SecurityAccessDeniedException secEx) { Console.WriteLine( $"({nameof(BankServiceApp)}) [{nameof(ReplicatorProxy)}] Security exception while trying to replicate: {secEx.Message}"); _replicatorProxy = null; // Break on sec exception since replicator probably doesn't have necessary privileges. break; } } }
public NewCardResults RequestNewCard(string password) { if (!Thread.CurrentPrincipal.IsInRole("Clients")) { Task.Run(() => { ProxyPool.GetProxy <IBankAuditService>().Log(new EventLogData( _applicationName, ExtractUsernameFromFullName(Thread.CurrentPrincipal.Identity.Name), "Request for new card failed client isn't in client's role.", EventLogEntryType.FailureAudit)); }); throw new SecurityException("Principal isn't part of Clients role."); } try { var clientName = ExtractUsernameFromFullName(Thread.CurrentPrincipal.Identity.Name); Console.WriteLine($"Client {clientName} requested new card."); Task.Run(() => { ProxyPool.GetProxy <IBankAuditService>().Log(new EventLogData( _applicationName, clientName, "Request for new card!", EventLogEntryType.Information)); }); if (CertificateManager.Instance.GetCertificateFromStore( StoreLocation.LocalMachine, StoreName.My, clientName) != null) { throw new InvalidOperationException("You already have issued card."); } RevokeCertificate(clientName); var CACertificate = CertificateManager.Instance.GetCACertificate(); CertificateManager.Instance.CreateAndStoreNewCertificate( clientName, password, CACertificate, BankAppConfig.BankTransactionServiceCertificatePath); var cert = CertificateManager.Instance.GetCertificateFromStore( StoreLocation.LocalMachine, StoreName.My, clientName); if (cert == null) { throw new ArgumentNullException(nameof(cert)); } var resultData = new NewCardResults { PinCode = GenerateRandomPin() }; var client = BankCache.GetClientFromCache(_bankCache, clientName); client.ResetPin(null, resultData.PinCode); Task.Run(() => { ProxyPool.GetProxy <IBankAuditService>().Log(new EventLogData( _applicationName, clientName, "Successfully created a card!", EventLogEntryType.Information)); }); _bankCache.StoreData(); var replicationData = new ReplicationItem( client, ReplicationType.UserData | ReplicationType.CertificateData, cert); _replicatorProxy.ReplicateData(replicationData); return(resultData); } catch (ArgumentNullException ane) { Task.Run(() => { ProxyPool.GetProxy <IBankAuditService>().Log(new EventLogData( _applicationName, Thread.CurrentPrincipal.Identity.Name, ane.Message, EventLogEntryType.Error)); }); throw new FaultException <CustomServiceException>(new CustomServiceException(ane.Message + "was null!")); } }
public bool ExecuteTransaction(byte[] signature, ITransaction transaction) { var clientName = GetClientNameFromAuthContext(ServiceSecurityContext.Current.AuthorizationContext); var hash = HashData(transaction); VerifySignature(signature, hash, clientName); var client = BankCache.GetClientFromCache(_bankCache, clientName); if (client != null) { if (!client.CheckPin(transaction.Pin)) { Task.Run(() => { ProxyPool.GetProxy <IBankAuditService>().Log(new EventLogData( _applicationName, clientName, "Invalid Pin.", EventLogEntryType.Error)); }); throw new SecurityException("Invalid Pin."); } } var success = false; switch (transaction.TransactionType) { case TransactionType.Deposit: client.Account.Deposit(transaction.Amount); success = true; Task.Run(() => { ProxyPool.GetProxy <IBankAuditService>().Log(new EventLogData( _applicationName, clientName, $"Deposit made with {transaction.Amount} amount.", EventLogEntryType.Information)); }); break; case TransactionType.Withdrawal: if (client.Account.Balance >= transaction.Amount) { client.Account.Withdraw(transaction.Amount); if (++client.Withdraw >= _withdrawLimitForAudit) { Task.Run(() => { ProxyPool.GetProxy <IBankAuditService>().Log(new EventLogData( _applicationName, clientName, $"Client exceeded withdraw transaction amount by {client.Withdraw - _withdrawLimitForAudit}.", EventLogEntryType.Information)); }); } success = true; Task.Run(() => { ProxyPool.GetProxy <IBankAuditService>().Log(new EventLogData( _applicationName, clientName, $"Withdrawal made with {transaction.Amount} amount.", EventLogEntryType.Information)); }); } break; default: throw new InvalidOperationException("Invalid operation. For check balance use dedicated method."); } if (success) { _bankCache.StoreData(); _replicatorProxy.ReplicateData(new ReplicationItem(client)); } return(success); }