예제 #1
0
        public static async Task <GetCategoriesResponseDto> Build(
            UserLogInData entity,
            CloudTable table)
        {
            var dtoResponse = new GetCategoriesResponseDto();
            var householdId = entity.HouseholdId;
            var retrieveHouseholdOperation = TableOperation.Retrieve <Household>(householdId, householdId);
            var householdResult            = await table.ExecuteAsync(retrieveHouseholdOperation);

            if (householdResult.Result != null)
            {
                var household  = householdResult.Result as Household;
                var categories = JsonConvert.DeserializeObject <List <Category> >(household.CategoriesAggregated);
                dtoResponse.Categories = categories;
            }
            else
            {
                var retrieveUsersOwnCategories = TableOperation.Retrieve <UserDetails>(householdId, entity.PartitionKey);
                var userDetailsResult          = await table.ExecuteAsync(retrieveUsersOwnCategories);

                if (userDetailsResult.Result != null)
                {
                    var userDetails = userDetailsResult.Result as UserDetails;
                    var categories  = JsonConvert.DeserializeObject <List <Category> >(userDetails.Categories);
                    dtoResponse.Categories = categories;
                }
                else
                {
                    return(null);
                }
            }
            return(dtoResponse);
        }
예제 #2
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Function,
                 "get",
                 "post",
                 Route = "users/delete/{login}/")
            ] HttpRequestMessage req,
            string login,
            [Table("ExpensesApp")] CloudTable table,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData logInData,
            [Table("ExpensesApp", "household_{login}", "user_{login}")] UserDetails details,
            TraceWriter log)
        {
            if (login == null)
            {
                log.Info("DeleteUser response: BadRequest - login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a login on the query string or in the request body"));
            }
            if (logInData == null)
            {
                log.Info($"DeleteUser response: BadRequest - no such user");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login does not exist"
                           ));
            }

            // usuñ wp³yw tej osoby na gospodarstwo
            // - usuñ z listy cz³onków
            // - usuñ z zagregowanych œrodków

            if (!string.IsNullOrEmpty(logInData.HouseholdId))
            {
                await DeleteInfluenceOnHousehold(logInData.HouseholdId, logInData.Login, details.Wallets, table, log);
            }

            if (logInData.HouseholdId != $"household_{logInData.Login}")
            {
                await DeleteUserDetailsAssignedToHousehold(logInData.HouseholdId, logInData.PartitionKey, table, log);
            }

            TableOperation tableOperation = TableOperation.Delete(logInData);
            await table.ExecuteAsync(tableOperation);

            var dbUser = $"user_{login}";

            log.Info($"DeleteUser response: Deleted entity with PK={dbUser} and RK={dbUser}");
            return(req.CreateResponse(HttpStatusCode.OK));
        }
예제 #3
0
 private static async Task <TableResult> UpdateUserHouseholdInfo(UserLogInData user, string household, CloudTable table, TraceWriter log)
 {
     user.HouseholdId = household;
     try
     {
         log.Info($"InviteToHousehold: proceeding to add household {household} to user {user.Login}");
         TableOperation updateOperation = TableOperation.Replace(user);
         return(await table.ExecuteAsync(updateOperation));
     }
     catch (Exception ex)
     {
         log.Error($"Failed to edit user {user.Login}", ex);
         return(null);
     }
 }
예제 #4
0
 private static async Task <bool> SetThatInvterHasAGroup(UserLogInData invitersLogInData, CloudTable table, TraceWriter log)
 {
     try
     {
         log.Info("SetThatInvterHasAGroup");
         invitersLogInData.BelongsToGroup = true;
         var updateOp = TableOperation.Replace(invitersLogInData);
         await table.ExecuteAsync(updateOp);
     }
     catch (Exception ex)
     {
         log.Error("Cannot set that invter has a group", ex);
         return(false);
     }
     return(true);
 }
예제 #5
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Function,
                 "get",
                 "post",
                 Route = "households/accept/{from}/{to}/{rowKey}")
            ] HttpRequestMessage req,
            string from,
            string to,
            string rowKey,
            [Table("ExpensesApp")] CloudTable table,
            [Table("ExpensesApp", "household_{from}", "household_{from}")] Household household,
            [Table("ExpensesApp", "user_{from}", "user_{from}")] UserLogInData invitersLogInData,
            [Table("ExpensesApp", "user_{to}", "user_{to}")] UserLogInData invitedUserLogInData,
            [Table("ExpensesApp", "household_{to}", "user_{to}")] UserDetails invitedUser,
            [Table("ExpensesApp", "message_{to}", "{rowKey}")] Message message,
            TraceWriter log)
        {
            if (from == null)
            {
                log.Info("AcceptInvitationToHousehold response: BadRequest - inviter's login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass an inviter's login on the query string or in the request body"));
            }
            if (to == null)
            {
                log.Info("AcceptInvitationToHousehold response: BadRequest - receiver's login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a receiver's login on the query string or in the request body"));
            }

            if (!(await SetThatInvterHasAGroup(invitersLogInData, table, log)) ||
                !(await SetThatReceiverIsConfirmedAndAddHisWalletsAndCategories(household, invitedUser, table, log)) ||
                !(await SetUserBelongsToHousehold(household.PartitionKey, invitedUserLogInData, table, log)) ||
                !(await DeleteInvitationMessage(message, table, log)))
            {
                log.Info("AcceptInvitationToHousehold response: Problem with activating user");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.InternalServerError,
                           value: "Problem with activating user"));
            }

            return(req.CreateResponse(HttpStatusCode.OK, household.PartitionKey));
        }
예제 #6
0
        public static HttpResponseMessage Run(
            [HttpTrigger(
                 AuthorizationLevel.Anonymous,
                 "get",
                 "post",
                 Route = "users/salt/{login}/")
            ] HttpRequestMessage req,
            string login,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData entity,
            TraceWriter log)
        {
            log.Info("Request to GetSalt");

            var dbUser = $"user_{login}";

            if (login == null)
            {
                log.Info("GetSalt response: BadRequest - login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a login on the query string or in the request body"));
            }

            string salt;

            if (entity == null)
            {
                salt = HashUtil.GenerateSalt();
                log.Info($"GetSalt response: no entity with PK={entity.PartitionKey} and RK={entity.RowKey} in the database. Responding with fake salt: {salt}");
            }
            else
            {
                salt = entity.Salt;
                log.Info($"GetSalt response: successfully found entity with PK={entity.PartitionKey} and RK={entity.RowKey} in the database. Responding with corresponding salt: {salt}");
            }

            return(new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent(salt)
            });
        }
예제 #7
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Function,
                 "get",
                 "post",
                 Route = "categories/getall/{login}/")
            ] HttpRequestMessage req,
            string login,
            [Table("ExpensesApp")] CloudTable table,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData entity,
            TraceWriter log)
        {
            if (login == null)
            {
                log.Info("GetCategories response: BadRequest - login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a login on the query string or in the request body"));
            }
            if (entity == null)
            {
                log.Info($"GetCategories response: BadRequest - user does not exist");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login does not exist"
                           ));
            }

            var dtoResponse = await GetCategoriesDtoBuilder.Build(entity, table);

            if (dtoResponse == null)
            {
                log.Info($"GetCategories response: InternalServerError - user does not have categories neither in household nor in user detailed info");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.InternalServerError,
                           value: "Cannot get categories"
                           ));
            }

            return(req.CreateResponse(HttpStatusCode.OK, dtoResponse));
        }
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Function,
                 "get",
                 "post",
                 Route = "cashflows/getdata/{householdId}/{login}/")
            ] HttpRequestMessage req,
            string householdId,
            string login,
            [Table("ExpensesApp")] CloudTable table,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData userLogInData,
            [Table("ExpensesApp", "{householdId}", "user_{login}")] UserDetails userDetails,
            TraceWriter log)
        {
            log.Info("GetDataForAddCashFlow processed a request.");


            if (login == null)
            {
                log.Info("GetDataForAddCashFlow response: BadRequest - login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a login on the query string or in the request body"));
            }
            if (householdId == null)
            {
                log.Info("GetDataForAddCashFlow response: BadRequest - householdId is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a householdId on the query string or in the request body"));
            }
            if (userLogInData == null)
            {
                log.Info($"GetDataForAddCashFlow response: BadRequest - user does not exist");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login does not exist"
                           ));
            }
            if (userDetails == null)
            {
                log.Info($"GetDataForAddCashFlow response: BadRequest - User with given login does not exist");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login does not exist"
                           ));
            }

            var categoriesDto = await GetCategoriesDtoBuilder.Build(userLogInData, table);

            var walletsDto = GetWallets(userDetails);

            if (categoriesDto == null || walletsDto == null)
            {
                log.Info($"GetDataForAddCashFlow response: InternalServerError - user does not have categories neither in household nor in user detailed info, or there is a problem with his wallets");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.InternalServerError,
                           value: "Cannot get categories or wallets"
                           ));
            }

            var responseDto = new GetDataForAddCashFlowResponseDto()
            {
                Categories = categoriesDto.Categories,
                Wallets    = walletsDto
            };

            return(req.CreateResponse(HttpStatusCode.OK, responseDto));
        }
예제 #9
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Anonymous,
                 "post",
                 Route = "users/login/{login}/")
            ] HttpRequestMessage req,
            string login,
            [Table("ExpensesApp")] CloudTable table,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData entity,
            TraceWriter log)
        {
            log.Info("Request to LogIn");

            LogInDto logInDto = null;

            try
            {
                logInDto = await req.Content.ReadAsDeserializedJson <LogInDto>();
            }
            catch
            {
                log.Info("LogIn response: BadRequest - cannot read dto object");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a valid dto object in the request content"));
            }

            if (login == null)
            {
                log.Info("LogIn response: BadRequest - login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a login on the query string or in the request body"));
            }
            if (logInDto == null ||
                string.IsNullOrWhiteSpace(logInDto.HashedPassword))
            {
                log.Info("LogIn response: BadRequest - dto object content is not valid");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass correct values to the dto object"));
            }
            if (entity == null ||
                entity.PasswordHash != logInDto.HashedPassword)
            {
                log.Info($"LogIn response: BadRequest - wrong credentials");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login does not exist or the password was incorrect"
                           ));
            }

            log.Info($"LogIn response: OK - user {login} has been authenticated");

            UserDetails userDetails = null;

            try
            {
                var rertieveTableOperation = TableOperation.Retrieve <UserDetails>(entity.HouseholdId, entity.PartitionKey);
                var result = await table.ExecuteAsync(rertieveTableOperation);

                userDetails = result?.Result as UserDetails;
            }
            catch (Exception ex)
            {
                log.Error($"LogIn response: InternalServerError. Couldn't retreieve UserDetails PK={entity.HouseholdId}, RK={entity.PartitionKey}", ex);
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.InternalServerError,
                           value: "Couldn't retreieve UserDetails"
                           ));
            }

            bool userBelongsToHousehold = false;

            try
            {
                var retrieveOperation = TableOperation.Retrieve <Household>(entity.HouseholdId, entity.HouseholdId);
                var result            = await table.ExecuteAsync(retrieveOperation);

                if (result != null && result.Result != null && result.Result is Household)
                {
                    userBelongsToHousehold = true;
                }
            }
            catch (Exception ex)
            {
                log.Error($"LogIn response: InternalServerError. Couldn't retreieve Household PK={entity.HouseholdId}, RK={entity.PartitionKey}", ex);
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.InternalServerError,
                           value: "Couldn't retreieve Household"
                           ));
            }

            var responseDto = new LogInResponseDto()
            {
                Key                = entity.Key,
                Configured         = userDetails != null,
                HouseholdId        = entity.HouseholdId,
                BelongsToHousehold = userBelongsToHousehold
            };

            return(req.CreateResponse(HttpStatusCode.OK, responseDto));
        }
예제 #10
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Function,
                 "post",
                 Route = "cashflows/add/{login}/")
            ] HttpRequestMessage req,
            string login,
            [Table("ExpensesApp")] ICollector <Cashflow> outTable,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData user,
            [Queue("expenses-addcashflow")] CloudQueue queue,
            [Table("ExpensesApp")] CloudTable table,
            TraceWriter log)
        {
            AddCashFlowDto dto = null;

            try
            {
                log.Info($"json dto: " + req.Content);
                dto = await req.Content.ReadAsDeserializedJson <AddCashFlowDto>();
            }
            catch
            {
                log.Info("AddCashFlow response: BadRequest - cannot read dto object");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a valid dto object in the request content"));
            }
            if (login == null)
            {
                log.Info("AddCashFlow response: BadRequest - login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a login on the query string or in the request body"));
            }
            if (user == null)
            {
                log.Info($"AddCashFlow response: BadRequest - user does not exist");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login does not exist"
                           ));
            }

            var cashflowBase = new Cashflow()
            {
                DateTime     = dto.DateTime,
                CategoryGuid = dto.CategoryGuid,
                Amount       = JsonConvert.SerializeObject(dto.Amount),
                Details      = JsonConvert.SerializeObject(dto.Details),
                WalletGuid   = dto.WalletGuid
            };
            var dateTimeInverted = RowKeyUtils.GetInvertedDateString(dto.DateTime);
            var guid             = Guid.NewGuid();

            if (user.BelongsToGroup)
            {
                var cashflowHousehold = new Cashflow(cashflowBase)
                {
                    PartitionKey = user.HouseholdId,
                    RowKey       = $"householdCashflow_{dateTimeInverted}_{guid}"
                };
                outTable.Add(cashflowHousehold);
                log.Info($"Added cashflowHousehold PK={cashflowHousehold.PartitionKey} RK={cashflowHousehold.RowKey}");
            }
            var cashflowUser = new Cashflow(cashflowBase)
            {
                PartitionKey = user.HouseholdId,
                RowKey       = $"userCashflow_{login}_{dateTimeInverted}_{guid}"
            };

            outTable.Add(cashflowUser);
            log.Info($"Added cashflowHousehold PK={cashflowUser.PartitionKey} RK={cashflowUser.RowKey}");

            //var cashflowHouseholdCategory = new Cashflow(cashflowBase)
            //{
            //    PartitionKey = user.HouseholdId,
            //    RowKey = $"householdCategoryCashflow_{dto.CategoryGuid}_{dateTimeInverted}_{guid}"
            //};
            //outTable.Add(cashflowHouseholdCategory);
            //log.Info($"Added cashflowHousehold PK={cashflowHouseholdCategory.PartitionKey} RK={cashflowHouseholdCategory.RowKey}");

            //var cashflowUserCategory = new Cashflow(cashflowBase)
            //{
            //    PartitionKey = user.HouseholdId,
            //    RowKey = $"userCategoryCashflow_{login}_{dto.CategoryGuid}_{dateTimeInverted}_{guid}"
            //};
            //outTable.Add(cashflowUserCategory);
            //log.Info($"Added cashflowHousehold PK={cashflowUserCategory.PartitionKey} RK={cashflowUserCategory.RowKey}");

            var addMessageDto = new AddMessageToAddCashflowQueueDto()
            {
                Amount             = dto.Amount,
                HouseholdPk        = user.HouseholdId,
                HouseholdRk        = user.HouseholdId,
                WalletGuid         = dto.WalletGuid,
                CategoryGuid       = dto.CategoryGuid,
                UserBelongsToGroup = user.BelongsToGroup,
                Login = login
            };

            if (user.BelongsToGroup)
            {
                var message = JsonConvert.SerializeObject(addMessageDto);
                await queue.AddMessageAsync(new CloudQueueMessage(message));

                log.Info($"Enqueued message {message}");
            }
            else
            {
                log.Info("User does not belong to a group. Only his wallet will be updated");
                await UpdateUsersWallet(addMessageDto, table, log);
            }

            return(req.CreateResponse(HttpStatusCode.OK));
        }
예제 #11
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Function,
                 "post",
                 Route = "users/configure/{login}/")
            ] HttpRequestMessage req,
            string login,
            [Table("ExpensesApp")] CloudTable table,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData entity,
            TraceWriter log)
        {
            log.Info("Request to ConfigureUser");

            ConfigureUserDto dto = null;

            try
            {
                dto = await req.Content.ReadAsDeserializedJson <ConfigureUserDto>();
            }
            catch
            {
                log.Info("ConfigureUser response: BadRequest - cannot read dto object");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a valid dto object in the request content"));
            }
            if (login == null)
            {
                log.Info("ConfigureUser response: BadRequest - login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a login on the query string or in the request body"));
            }
            if (entity == null)
            {
                log.Info($"ConfigureUser response: BadRequest - no such user");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login does not exist"
                           ));
            }

            var userDetails = new UserDetails()
            {
                PartitionKey = entity.HouseholdId,
                RowKey       = entity.PartitionKey,
                Height       = dto.Height,
                Name         = dto.Name,
                Sex          = dto.Sex == Model.Enums.Sex.Female ? true : false,
                Wallets      = JsonConvert.SerializeObject(dto.Wallets),
                Weight       = dto.Weight,
                Login        = entity.Login,
                Categories   = JsonConvert.SerializeObject(DefaultCategoryUtils.GetDefaultCategories(entity.Login)),
                DateOfBirth  = dto.DateOfBirth,
                Pal          = dto.Pal,
                Charges      = JsonConvert.SerializeObject(new Dictionary <string, List <Money> >())
            };
            TableOperation insertTableOperation = TableOperation.Insert(userDetails);
            await table.ExecuteAsync(insertTableOperation);

            var dbUser = $"user_{login}";

            log.Info($"ConfigureUser response: Updated entity with PK={userDetails.PartitionKey} and RK={userDetails.RowKey}");
            return(req.CreateResponse(HttpStatusCode.OK));
        }
예제 #12
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Function,
                 "post",
                 Route = "categories/add/{login}/")
            ] HttpRequestMessage req,
            string login,
            [Table("ExpensesApp")] CloudTable table,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData entity,
            TraceWriter log)
        {
            if (entity == null)
            {
                log.Info($"AddCategory response: BadRequest - no such user");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login does not exist"
                           ));
            }


            AddCategoryDto dto = null;

            try
            {
                dto = await req.Content.ReadAsDeserializedJson <AddCategoryDto>();
            }
            catch
            {
                log.Info("AddCategory response: BadRequest - cannot read dto object");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a valid dto object in the request content"));
            }


            var newCategory = new Category()
            {
                Name   = dto.Name,
                Factor = dto.Factor
            };

            var householdId = entity.HouseholdId;
            var retrieveHouseholdOperation = TableOperation.Retrieve <Household>(householdId, householdId);
            var householdResult            = await table.ExecuteAsync(retrieveHouseholdOperation);

            if (householdResult.Result != null)
            {
                var household = householdResult.Result as Household;

                if (newCategory.Factor == null)
                {
                    var members = JsonConvert.DeserializeObject <List <Member> >(household.Members);
                    var factor  = new Dictionary <string, double>();
                    foreach (var member in members)
                    {
                        if (member.Login == login)
                        {
                            factor.Add(member.Login, 100);
                        }
                        else
                        {
                            factor.Add(member.Login, 0);
                        }
                    }
                    newCategory.Factor = factor;
                }

                var categories = JsonConvert.DeserializeObject <List <Category> >(household.CategoriesAggregated);
                categories.Add(newCategory);
                household.CategoriesAggregated = JsonConvert.SerializeObject(categories);
                var updateTableOperation = TableOperation.Replace(household);
                await table.ExecuteAsync(updateTableOperation);
            }
            else
            {
                var retrieveUsersOwnCategories = TableOperation.Retrieve <UserDetails>(householdId, entity.PartitionKey);
                var userDetailsResult          = await table.ExecuteAsync(retrieveUsersOwnCategories);

                if (userDetailsResult.Result != null)
                {
                    var userDetails = userDetailsResult.Result as UserDetails;
                    var categories  = JsonConvert.DeserializeObject <List <Category> >(userDetails.Categories);

                    if (newCategory.Factor == null)
                    {
                        newCategory.Factor = new Dictionary <string, double>()
                        {
                            { login, 100 }
                        };
                    }

                    categories.Add(newCategory);
                    userDetails.Categories = JsonConvert.SerializeObject(categories);
                    var updateTableOperation = TableOperation.Replace(userDetails);
                    await table.ExecuteAsync(updateTableOperation);
                }
                else
                {
                    log.Info($"AddCategory response: InternalServerError - user does not have categories neither in household nor in user detailed info");
                    return(req.CreateResponse(
                               statusCode: HttpStatusCode.InternalServerError,
                               value: "Cannot get categories"
                               ));
                }
            }

            return(req.CreateResponse(HttpStatusCode.OK));
        }
예제 #13
0
        private static async Task <TableResult> UpsertHousehold(UserDetails invitersDetails, UserLogInData invitersLogInData, UserLogInData notConfirmedMember, CloudTable table, TraceWriter log)
        {
            var retrieveHouseholdOperation = TableOperation.Retrieve <Household>(invitersLogInData.HouseholdId, invitersLogInData.HouseholdId);
            var result = await table.ExecuteAsync(retrieveHouseholdOperation);

            if (result != null && result.Result != null && result.Result is Household)
            {
                log.Info($"InviteToHousehold: the inviter belongs to a household {invitersLogInData.HouseholdId}");
                return(await UpdateExistingHousehold(
                           householdPk : $"{invitersLogInData.HouseholdId}",
                           notConfirmedMemberLogin : notConfirmedMember.Login,
                           table : table, log : log));
            }
            else
            {
                log.Info($"InviteToHousehold: the inviter does not belong to any household yet. Creating a new one.");
                var householdPk = $"household_{invitersLogInData.Login}";
                await CreateNewHousehold(
                    newHouseholdPk : householdPk,
                    ownerDetails : invitersDetails,
                    notConfirmedMemberLogin : notConfirmedMember.Login,
                    table : table, log : log);

                return(await UpdateUserHouseholdInfo(
                           user : invitersLogInData,
                           household : householdPk,
                           table : table, log : log));
            }
        }
예제 #14
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Anonymous,
                 "post",
                 Route = "users/add/{login}/")
            ] HttpRequestMessage req,
            string login,
            [Table("ExpensesApp")] ICollector <UserLogInData> outTable,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData entity,
            TraceWriter log)
        {
            log.Info("Request to AddUser");

            var        dbUser      = $"user_{login}";
            var        householdId = $"household_{login}";
            AddUserDto addUserDto  = null;

            try
            {
                addUserDto = await req.Content.ReadAsDeserializedJson <AddUserDto>();
            }
            catch
            {
                log.Info("AddUser response: BadRequest - cannot read dto object");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a valid dto object in the request content"));
            }

            if (login == null)
            {
                log.Info("AddUser response: BadRequest - login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a login on the query string or in the request body"));
            }
            if (addUserDto == null ||
                string.IsNullOrWhiteSpace(addUserDto.HashedPassword) ||
                string.IsNullOrWhiteSpace(addUserDto.Salt))
            {
                log.Info("AddUser response: BadRequest - dto object content is not valid");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass correct values to the dto object"));
            }
            if (entity != null)
            {
                log.Info($"AddUser response: BadRequest - entity with PK={entity.PartitionKey} and RK={entity.RowKey} already exists");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login already exists"
                           ));
            }

            var key = await RequestANewKeyForUser(dbUser, log);

            var newUser = new UserLogInData()
            {
                PartitionKey   = dbUser,
                RowKey         = dbUser,
                Login          = login,
                PasswordHash   = addUserDto.HashedPassword,
                Key            = key,
                Salt           = addUserDto.Salt,
                HouseholdId    = householdId,
                BelongsToGroup = false
            };

            outTable.Add(newUser);

            log.Info($"AddUser response: Created - entity with PK={newUser.PartitionKey} and RK={newUser.RowKey}");
            return(req.CreateResponse(HttpStatusCode.Created));
        }
예제 #15
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Function,
                 "get",
                 "post",
                 Route = "households/invite/{invitersLogin}/{receiverLogin}")
            ] HttpRequestMessage req,
            string invitersLogin,
            string receiverLogin,
            [Table("ExpensesApp")] CloudTable table,
            [Table("ExpensesApp", "user_{invitersLogin}", "user_{invitersLogin}")] UserLogInData invitersEntity,
            [Table("ExpensesApp", "user_{receiverLogin}", "user_{receiverLogin}")] UserLogInData receiverEntity,
            TraceWriter log)
        {
            if (invitersLogin == null)
            {
                log.Info("InviteToHousehold response: BadRequest - inviter's login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass an inviter's login on the query string or in the request body"));
            }
            if (receiverLogin == null)
            {
                log.Info("InviteToHousehold response: BadRequest - invited person's login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass an invited person's login on the query string or in the request body"));
            }
            if (invitersEntity == null)
            {
                log.Info($"InviteToHousehold response: BadRequest - no such user: {invitersLogin}");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: $"User with login {invitersLogin} does not exist"
                           ));
            }
            if (receiverEntity == null)
            {
                log.Info($"InviteToHousehold response: BadRequest - no such user: {receiverLogin}");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: $"User with login {receiverLogin} does not exist"
                           ));
            }
            if (receiverEntity.BelongsToGroup)
            {
                log.Info($"InviteToHousehold response: BadRequest - user {receiverLogin} already belongs to a group");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: $"User with login {receiverLogin} already belongs to a group"
                           ));
            }

            var retrieveTableOperation = TableOperation.Retrieve <UserDetails>(invitersEntity.HouseholdId, invitersEntity.PartitionKey);
            var retrieveResult         = await table.ExecuteAsync(retrieveTableOperation);

            var userDetails = retrieveResult.Result as UserDetails;

            if (await InsertInvitationMessage(
                    invitersDetails: userDetails,
                    inviter: invitersEntity,
                    receiver: receiverEntity,
                    table: table, log: log) == null)
            {
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.InternalServerError,
                           value: $"Can't insert invitation message"
                           ));
            }
            if (await UpsertHousehold(
                    invitersDetails: userDetails,
                    invitersLogInData: invitersEntity,
                    notConfirmedMember: receiverEntity,
                    table: table, log: log) == null)
            {
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.InternalServerError,
                           value: $"Can't upsert household"
                           ));
            }

            return(req.CreateResponse(HttpStatusCode.OK));
        }
예제 #16
0
        private static async Task <TableResult> InsertInvitationMessage(UserDetails invitersDetails, UserLogInData inviter, UserLogInData receiver, CloudTable table, TraceWriter log)
        {
            var date   = DateTime.UtcNow;
            var rowKey = RowKeyUtils.GetInvertedDateString(date);

            string householdOwner = null;

            if (string.IsNullOrEmpty(inviter.HouseholdId))
            {
                householdOwner = inviter.Login;
            }
            else
            {
                var splited = inviter.HouseholdId.Split('_');
                householdOwner = splited.Last();
            }

            var message = new Message()
            {
                PartitionKey = $"message_{receiver.Login}",
                RowKey       = rowKey,
                From         = JsonConvert.SerializeObject(new UserShort()
                {
                    Name  = invitersDetails.Name,
                    Login = inviter.Login
                }),
                Topic   = $"{invitersDetails.Name} invites you to household",
                Content = $"/api/households/accept/{householdOwner}/{receiver.Login}/{rowKey}"
            };

            log.Info("InviteToHousehold: proceeding with inserting invitation message");
            try
            {
                TableOperation insertOperation = TableOperation.Insert(message);
                return(await table.ExecuteAsync(insertOperation));
            }
            catch (Exception ex)
            {
                log.Error("InviteToHousehold: failed to insert invitation message", ex);
                return(null);
            }
        }
예제 #17
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(
                 AuthorizationLevel.Function,
                 "get", "post",
                 Route = "users/loginwithkey/{login}")
            ] HttpRequestMessage req,
            string login,
            [Table("ExpensesApp")] CloudTable table,
            [Table("ExpensesApp", "user_{login}", "user_{login}")] UserLogInData entity,
            TraceWriter log)
        {
            if (login == null)
            {
                log.Info("LogIn response: BadRequest - login is null");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Please pass a login on the query string or in the request body"));
            }

            if (entity == null)
            {
                log.Info($"LogIn response: BadRequest - no such user");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "User with given login does not exist"
                           ));
            }

            string key = req.GetQueryNameValuePairs()
                         .FirstOrDefault(q => string.Compare(q.Key, "code", true) == 0)
                         .Value;

            if (entity.Key != key)
            {
                log.Info($"LogIn response: BadRequest - key doesn't belong to this user");
                log.Info($"-----------------was: {key}");
                log.Info($"but should have been: {entity.Key}");
                int i = 0;
                for (; i < key.Length; ++i)
                {
                    if (entity.Key.Length < i + 1 || entity.Key[i] != key[i])
                    {
                        break;
                    }
                }
                log.Info($"at char: {i}");
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.BadRequest,
                           value: "Given key doesn't belong to this user"
                           ));
            }

            log.Info($"LogIn response: OK - user {login} has been authenticated");

            UserDetails userDetails = null;

            try
            {
                var rertieveTableOperation = TableOperation.Retrieve <UserDetails>(entity.HouseholdId, entity.PartitionKey);
                var result = await table.ExecuteAsync(rertieveTableOperation);

                userDetails = result?.Result as UserDetails;
            }
            catch (Exception ex)
            {
                log.Error($"LogIn response: InternalServerError. Couldn't retreieve UserDetails PK={entity.HouseholdId}, RK={entity.PartitionKey}", ex);
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.InternalServerError,
                           value: "Couldn't retreieve UserDetails"
                           ));
            }

            bool userBelongsToHousehold = false;

            try
            {
                var retrieveOperation = TableOperation.Retrieve <Household>(entity.HouseholdId, entity.HouseholdId);
                var result            = await table.ExecuteAsync(retrieveOperation);

                if (result != null && result.Result != null && result.Result is Household)
                {
                    userBelongsToHousehold = true;
                }
            }
            catch (Exception ex)
            {
                log.Error($"LogIn response: InternalServerError. Couldn't retreieve Household PK={entity.HouseholdId}, RK={entity.PartitionKey}", ex);
                return(req.CreateResponse(
                           statusCode: HttpStatusCode.InternalServerError,
                           value: "Couldn't retreieve Household"
                           ));
            }

            var responseDto = new LogInResponseDto()
            {
                Key                = entity.Key,
                Configured         = userDetails != null,
                HouseholdId        = entity.HouseholdId,
                BelongsToHousehold = userBelongsToHousehold
            };

            return(req.CreateResponse(HttpStatusCode.OK, responseDto));
        }
예제 #18
0
        private static async Task <bool> SetUserBelongsToHousehold(string partitionKey, UserLogInData invitedUser, CloudTable table, TraceWriter log)
        {
            try
            {
                log.Info("SetUserBelongsToHousehold");
                invitedUser.HouseholdId    = partitionKey;
                invitedUser.BelongsToGroup = true;
                var updateTableOperation = TableOperation.Replace(invitedUser);
                await table.ExecuteAsync(updateTableOperation);

                return(true);
            }
            catch (Exception ex)
            {
                log.Error("Cannot edit user's household", ex);
                return(false);
            }
        }