using CarCareTracker.External.Interfaces; using CarCareTracker.Models; namespace CarCareTracker.Logic { public interface IUserLogic { List GetCollaboratorsForVehicle(int vehicleId); bool AddUserAccessToVehicle(int userId, int vehicleId); bool DeleteCollaboratorFromVehicle(int userId, int vehicleId); OperationResponse DeleteCollaboratorFromVehicle(int vehicleId, string username); OperationResponse AddCollaboratorToVehicle(int vehicleId, string username); List FilterUserVehicles(List results, int userId); bool UserCanEditVehicle(int userId, int vehicleId, HouseholdPermission permission); bool UserCanDirectlyEditVehicle(int userId, int vehicleId); bool DeleteAllAccessToVehicle(int vehicleId); bool DeleteAllAccessToUser(int userId); List GetHouseholdForParentUserId(int parentUserId); List GetHouseholdForChildUserId(int childUserId); OperationResponse AddUserToHousehold(int parentUserId, string childUsername); bool UpdateUserHousehold(int parentUserId, int childUserId, List permissions); bool DeleteUserFromHousehold(int parentUserId, int childUserId); bool DeleteAllHouseholdByParentUserId(int parentUserId); bool DeleteAllHouseholdByChildUserId(int childUserId); } public class UserLogic: IUserLogic { private readonly IUserAccessDataAccess _userAccess; private readonly IUserRecordDataAccess _userData; private readonly IUserHouseholdDataAccess _userHouseholdData; public UserLogic(IUserAccessDataAccess userAccess, IUserRecordDataAccess userData, IUserHouseholdDataAccess userHouseholdData) { _userAccess = userAccess; _userData = userData; _userHouseholdData = userHouseholdData; } public List GetCollaboratorsForVehicle(int vehicleId) { var result = _userAccess.GetUserAccessByVehicleId(vehicleId); var convertedResult = new List(); //convert useraccess to usercollaborator foreach(UserAccess userAccess in result) { var userCollaborator = new UserCollaborator { UserName = _userData.GetUserRecordById(userAccess.Id.UserId).UserName, UserVehicle = userAccess.Id }; convertedResult.Add(userCollaborator); } return convertedResult; } public OperationResponse AddCollaboratorToVehicle(int vehicleId, string username) { //try to find existing user. var existingUser = _userData.GetUserRecordByUserName(username); if (existingUser.Id != default) { //user exists. //check if user is already a collaborator var userAccess = _userAccess.GetUserAccessByVehicleAndUserId(existingUser.Id, vehicleId); if (userAccess != null) { return OperationResponse.Failed("User is already a collaborator"); } var result = AddUserAccessToVehicle(existingUser.Id, vehicleId); if (result) { return OperationResponse.Succeed("Collaborator Added"); } return OperationResponse.Failed(); } return OperationResponse.Failed($"Unable to find user {username} in the system"); } public OperationResponse DeleteCollaboratorFromVehicle(int vehicleId, string username) { //try to find existing user. var existingUser = _userData.GetUserRecordByUserName(username); if (existingUser.Id != default) { //user exists. //check if user is already a collaborator var userAccess = _userAccess.GetUserAccessByVehicleAndUserId(existingUser.Id, vehicleId); if (userAccess == null) { return OperationResponse.Failed("User doesn't have access to this vehicle"); } var result = _userAccess.DeleteUserAccess(existingUser.Id, vehicleId); if (result) { return OperationResponse.Succeed("Collaborator Removed"); } return OperationResponse.Failed(); } return OperationResponse.Failed($"Unable to find user {username} in the system"); } public bool DeleteCollaboratorFromVehicle(int userId, int vehicleId) { var result = _userAccess.DeleteUserAccess(userId, vehicleId); return result; } public bool AddUserAccessToVehicle(int userId, int vehicleId) { if (userId == -1) { return true; } var userVehicle = new UserVehicle { UserId = userId, VehicleId = vehicleId }; var userAccess = new UserAccess { Id = userVehicle }; var result = _userAccess.SaveUserAccess(userAccess); return result; } public List FilterUserVehicles(List results, int userId) { //user is root user. if (userId == -1) { return results; } List userIds = new List { userId }; List vehicleIds = new List(); var userHouseholds = _userHouseholdData.GetUserHouseholdByChildUserId(userId); if (userHouseholds.Any()) { //add parent's user ids userIds.AddRange(userHouseholds.Select(x => x.Id.ParentUserId)); } foreach(int userIdToCheck in userIds) { var accessibleVehicles = _userAccess.GetUserAccessByUserId(userIdToCheck); if (accessibleVehicles.Any()) { vehicleIds.AddRange(accessibleVehicles.Select(x => x.Id.VehicleId)); } } if (vehicleIds.Any()) { return results.Where(x => vehicleIds.Contains(x.Id)).ToList(); } else { return new List(); } } public bool UserCanEditVehicle(int userId, int vehicleId, HouseholdPermission permission) { //check if user is full collaborator or root user if (UserCanDirectlyEditVehicle(userId, vehicleId)) { return true; } //user is not a full collaborator, check households List userIds = new List(); var userHouseholds = _userHouseholdData.GetUserHouseholdByChildUserId(userId); foreach (UserHousehold userHousehold in userHouseholds) { //check if the direct parents have access to the vehicle var userAccess = _userAccess.GetUserAccessByVehicleAndUserId(userHousehold.Id.ParentUserId, vehicleId); if (userAccess != null && userAccess.Id.UserId == userHousehold.Id.ParentUserId && userAccess.Id.VehicleId == vehicleId) { //every member in a household has permission to view vehicles if (permission == HouseholdPermission.View || userHousehold.Permissions.Contains(permission)) { return true; } } } return false; } public bool UserCanDirectlyEditVehicle(int userId, int vehicleId) { if (userId == -1) { return true; } var userAccess = _userAccess.GetUserAccessByVehicleAndUserId(userId, vehicleId); if (userAccess != null && userAccess.Id.UserId == userId && userAccess.Id.VehicleId == vehicleId) { return true; } return false; } public bool DeleteAllAccessToVehicle(int vehicleId) { var result = _userAccess.DeleteAllAccessRecordsByVehicleId(vehicleId); return result; } public bool DeleteAllAccessToUser(int userId) { var result = _userAccess.DeleteAllAccessRecordsByUserId(userId); return result; } public List GetHouseholdForParentUserId(int parentUserId) { var result = _userHouseholdData.GetUserHouseholdByParentUserId(parentUserId); var convertedResult = new List(); //convert userhousehold to viewmodel foreach (UserHousehold userHouseholdAccess in result) { var userCollaborator = new UserHouseholdViewModel { UserName = _userData.GetUserRecordById(userHouseholdAccess.Id.ChildUserId).UserName, UserHousehold = userHouseholdAccess }; convertedResult.Add(userCollaborator); } return convertedResult; } public List GetHouseholdForChildUserId(int childUserId) { var result = _userHouseholdData.GetUserHouseholdByChildUserId(childUserId); var convertedResult = new List(); //convert userhousehold to viewmodel foreach (UserHousehold userHouseholdAccess in result) { var userCollaborator = new UserHouseholdViewModel { UserName = _userData.GetUserRecordById(userHouseholdAccess.Id.ParentUserId).UserName, UserHousehold = userHouseholdAccess }; convertedResult.Add(userCollaborator); } return convertedResult; } public OperationResponse AddUserToHousehold(int parentUserId, string childUsername) { //attempting to add to root user if (parentUserId == -1) { return OperationResponse.Failed("Root user household not allowed"); } //try to find existing user. var existingUser = _userData.GetUserRecordByUserName(childUsername); if (existingUser.Id != default) { //user exists. //check if user is trying to add themselves if (parentUserId == existingUser.Id) { return OperationResponse.Failed("Cannot add user to their own household"); } //check if user already belongs to the household var householdAccess = _userHouseholdData.GetUserHouseholdByParentAndChildUserId(parentUserId, existingUser.Id); if (householdAccess != null && householdAccess.Id.ChildUserId == existingUser.Id && householdAccess.Id.ParentUserId == parentUserId) { return OperationResponse.Failed("User already belongs to this household"); } //check if a circular dependency will exist var circularHouseholdAccess = _userHouseholdData.GetUserHouseholdByParentAndChildUserId(existingUser.Id, parentUserId); if (circularHouseholdAccess != null && circularHouseholdAccess.Id.ChildUserId == parentUserId && circularHouseholdAccess.Id.ParentUserId == existingUser.Id) { return OperationResponse.Failed("Circular dependency is not allowed"); } var result = _userHouseholdData.SaveUserHousehold(new UserHousehold { Id = new HouseholdAccess { ParentUserId = parentUserId, ChildUserId = existingUser.Id} }); if (result) { return OperationResponse.Succeed("User Added to Household"); } return OperationResponse.Failed(); } return OperationResponse.Failed($"Unable to find user {childUsername} in the system"); } public bool UpdateUserHousehold(int parentUserId, int childUserId, List permissions) { var existingHousehold = _userHouseholdData.GetUserHouseholdByParentAndChildUserId(parentUserId, childUserId); if (existingHousehold != null && existingHousehold.Id.ChildUserId == childUserId && existingHousehold.Id.ParentUserId == parentUserId) { existingHousehold.Permissions = permissions; var result = _userHouseholdData.SaveUserHousehold(existingHousehold); return result; } return false; } public bool DeleteUserFromHousehold(int parentUserId, int childUserId) { var result = _userHouseholdData.DeleteUserHousehold(parentUserId, childUserId); return result; } public bool DeleteAllHouseholdByParentUserId(int parentUserId) { var result = _userHouseholdData.DeleteAllHouseholdRecordsByParentUserId(parentUserId); return result; } public bool DeleteAllHouseholdByChildUserId(int childUserId) { var result = _userHouseholdData.DeleteAllHouseholdRecordsByChildUserId(childUserId); return result; } } }