Beispiel #1
0
        /// <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));
        }
Beispiel #2
0
        /// <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");
 }
Beispiel #4
0
        /// <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"));
        }
Beispiel #5
0
 /// <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();
 }