/// <summary> /// Perform user validation /// </summary> /// <param name="login">Users login</param> /// <param name="password">Users password</param> /// <returns></returns> public Message ValidateUser(string login, string password) { var credentials = AccountUtils.Base64Encode(login + ":" + password); var usr = MongoRepository.GetCollection <User>() .Find(Builders <User> .Filter.Eq("Credentials", credentials)) .FirstOrDefault(); if (usr == null) { return(new ErrorMessage("Błędny login i/lub hasło")); } return(new ResultMessage(credentials)); }
/// <summary> /// Execute external transfer with use of http POST call /// </summary> /// <param name="transfer"><see cref="Transfer"/> object</param> /// <param name="accountTo">Destination bank account number</param> /// <param name="credentials">Base64 endoded users credentials</param> /// <returns></returns> public Message ExecuteExternalTransfer(Transfer transfer, string accountTo, string credentials) { var dict = new Dictionary <string, string>(); try { var reader = new StreamReader( File.OpenRead("map.csv")); reader.ReadLine(); while (!reader.EndOfStream) { var line = reader.ReadLine(); if (line == null) { return(new ErrorMessage("EndOfFileException")); } var map = line.Split(','); if (map[1].Last() != '/') { map[1] += '/'; } dict.Add(map[0], map[1]); } var bankId = accountTo.Substring(2, 8); _httpClient = new HttpClient(); _httpClient.BaseAddress = new Uri($"{dict[bankId]}accounts/"); } catch (FileNotFoundException) { return(new ErrorMessage("Nie znaleziono pliku \"map.csv\"")); } catch (KeyNotFoundException ex) { return(new ErrorMessage(ex.Message)); } //_httpClient = new HttpClient(); //_httpClient.BaseAddress = new Uri("http://localhost:8080/accounts/"); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", AccountUtils.Base64Encode("admin:admin")); _httpClient.DefaultRequestHeaders.Accept.Clear(); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var collection = MongoRepository.GetCollection <User>(); var filter = Builders <User> .Filter.Where( x => x.Credentials == credentials && x.Accounts.Any(a => a.BankAccountNumber == transfer.From)); var user = collection.Find(filter) .FirstOrDefault(); if (user == null) { return(new ErrorMessage("Brak użytkownika spełniającego kryteria")); } var account = user.Accounts.FirstOrDefault(x => x.BankAccountNumber == transfer.From); if (account == null) { return(new ErrorMessage($"Błędne numer rachunku bankowego: {transfer.From}")); } var newAmount = account.Amount - transfer.Amount; if (newAmount < 0) { return(new ErrorMessage("Nie wystarczająca ilość środków na koncie")); } var transferCopy = new Transfer { Amount = transfer.Amount * 100, From = transfer.From, Title = transfer.Title }; // Send POST request var resultMessageTask = SendRequest(transferCopy, accountTo); resultMessageTask.Wait(); var resultMessage = resultMessageTask.Result; if (resultMessage.IsError) { return(resultMessage); } var update = Builders <User> .Update.Set(x => x.Accounts[-1].Amount, newAmount); var result = MongoRepository.GetCollection <User>() .UpdateOne(filter, update); if (result.IsAcknowledged) { var historyCollection = MongoRepository.GetCollection <History>(); var historyRecord = new History { Amount = transfer.Amount, Date = DateTime.Now, From = transfer.From, To = accountTo, Type = Constants.ExternalTransferType, UserOrdinal = user.Ordinal, Title = transfer.Title }; historyCollection.InsertOneAsync(historyRecord); } return(resultMessage); }
public void LoginFromCredentialsTest() { Assert.AreEqual(AccountUtils.LoginFromCredentials(AccountUtils.Base64Encode("acc:pass")), "acc"); Assert.AreEqual(AccountUtils.LoginFromCredentials(AccountUtils.Base64Encode("x:x")), "x"); }
/// <summary> /// One and only rest service enpoint hanlding external transfer. /// </summary> /// <param name="stream">Gets json from request body. Json deserialize to <see cref="Transfer"/></param> /// <param name="bankAccountNumberTo">26-digit destination bank account number</param> /// <returns></returns> public Stream RecieveTransfer(Stream stream, string bankAccountNumberTo) { var sr = new StreamReader(stream); var res = sr.ReadToEnd(); var ctx = WebOperationContext.Current; if (ctx == null) { return(AccountUtils.CreateJsonErrorResponse("Bład wewnętrzny")); } if (!ctx.IncomingRequest.Headers[HttpRequestHeader.ContentType].Contains("application/json")) { ctx.OutgoingResponse.StatusCode = HttpStatusCode.BadRequest; return(AccountUtils.CreateJsonErrorResponse("Zły nagłówek: " + HttpRequestHeader.ContentType)); } var transfer = JsonConvert.DeserializeObject <Transfer>(res); // Getting WWW-Authenticate header from POST request. eqample "Basic 23sd1" // Substring cuts "Basic " var credentials = ctx.IncomingRequest.Headers[HttpRequestHeader.Authorization].Substring(6); var truth = AccountUtils.Base64Encode("admin:admin"); // Checks credentials if (truth != credentials) { ctx.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; return(AccountUtils.CreateJsonErrorResponse("Błąd uwierzytelniania")); } // Checks destination bank account number in terms of checksum var isValidTo = AccountUtils.ValidateAccountNumber(bankAccountNumberTo); if (!isValidTo) { ctx.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; return(AccountUtils.CreateJsonErrorResponse($"Niepoprawne konto: {bankAccountNumberTo}")); } // Checks if destination and source bank account numbers are equal if (bankAccountNumberTo == transfer.From) { ctx.OutgoingResponse.StatusCode = HttpStatusCode.BadRequest; return(AccountUtils.CreateJsonErrorResponse("Konto docelowe musi być różne od konta źródłowego !")); } var collection = MongoRepository.GetCollection <User>(); var filterTo = Builders <User> .Filter.Where( x => x.Accounts.Any(a => a.BankAccountNumber == bankAccountNumberTo)); var accountTo = collection.Find(filterTo) .FirstOrDefault().Accounts.FirstOrDefault(a => a.BankAccountNumber == bankAccountNumberTo); // If there is no destination account in database then return 404 code if (accountTo == null) { ctx.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; return(AccountUtils.CreateJsonErrorResponse($"Nie znaleziono konta: {bankAccountNumberTo}")); } var newAmountTo = accountTo.Amount + (transfer.Amount / 100); var updateTo = Builders <User> .Update.Set(x => x.Accounts[-1].Amount, newAmountTo); var resultTo = collection.UpdateOne(filterTo, updateTo); if (resultTo.IsAcknowledged) { ctx.OutgoingResponse.StatusCode = HttpStatusCode.Created; return(null); } ctx.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError; return(AccountUtils.CreateJsonErrorResponse("Bład aktualizacji bazy danych")); }
/// <summary> /// Contructor creating user with new account contains 0 money /// </summary> /// <param name="login">Users login</param> /// <param name="password">Users password</param> public User(string login, string password) { Ordinal = getLastUserIndex() + 1; Credentials = AccountUtils.Base64Encode(login + ":" + password); CreateNewAccount(); }