Reputation: 986
I have a customers database, containing a list of the customers ip address ranges, to give them access to a system.
public class Customer
{
[BsonId]
public ObjectId Id { get; set; }
public string Name { get; set; }
public List<IPRange> IPRanges { get; set; }
}
public class IPRange
{
public int Lower { get; set; }
public int Upper { get; set; }
}
The ip's are converted in to integers, so it is easier (or at least i think it is) to compare them with an incoming ip address.
So the document in MongoDB looks something like this
{
"_id": ObjectID("55f9ab5ac95fb323d8b724a8"),
"Name": "Customername",
"IPRanges": [
{
"Lower": 134743044,
"Upper": 134744072
},
{
"Lower": 3494108380,
"Upper": 3494108894
}
],
}
So the question is, how to compare an incoming IP with a customer, based on the array of ipranges? If that is not possible, how to do this in a better way?
I have tried a lot of combinations, non of them which work. I have managed to get it work, if the upper and the lower ip's are identical.
This is the closes I got to a solution
private async static Task<bool> check(string ip = "")
{
db = Connect();
var intIp = IPCalculator.IPToInt(ip); //converts the ip from string form e.g. "8.8.8.8" to integer
var lowerFilter = Builders<IPRange>.Filter.Gte("Lower", intIp);
var upperFilter = Builders<IPRange>.Filter.Lte("Upper", intIp);
List<FilterDefinition<IPRange>> filters = new List<FilterDefinition<IPRange>>();
filters.Add(lowerFilter);
filters.Add(upperFilter);
var customerFilter = Builders<Customer>.Filter.ElemMatch<IPRange>(ca => ca.IPRanges, Builders<IPRange>.Filter.And(filters));
var customerCollection = db.GetCollection<Customer>("Customer").Find(customerFilter);
var customerList = await customerCollection.ToListAsync();
if (customerList.Count > 0)
{
return true;
}
return false;
}
Upvotes: 2
Views: 45
Reputation: 101493
It seems you just messed up a little here:
var lowerFilter = Builders<IPRange>.Filter.Gte("Lower", intIp);
var upperFilter = Builders<IPRange>.Filter.Lte("Upper", intIp);
because that would mean Lower >= ip and Upper <= ip. You need:
var lowerFilter = Builders<IPRange>.Filter.Lte("Lower", intIp);
var upperFilter = Builders<IPRange>.Filter.Gte("Upper", intIp);
Upvotes: 1