Skip to content

Commit

Permalink
Add an 'ipinfo' database configuration provider
Browse files Browse the repository at this point in the history
  • Loading branch information
joegallo committed Oct 11, 2024
1 parent dc009db commit 21790e4
Showing 1 changed file with 62 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -78,8 +79,19 @@ public record DatabaseConfiguration(String id, String name, Provider provider) i
// "GeoLite2-Country"
);

public static final Set<String> IPINFO_NAMES = Set.of(
// these file names are from https://ipinfo.io/developers/database-filename-reference
"asn", // "Free IP to ASN"
"country", // "Free IP to Country"
// "country_asn" // "Free IP to Country + IP to ASN", not supported at present
"standard_asn", // commercial "ASN"
"standard_location", // commercial "IP Geolocation"
"standard_privacy" // commercial "Privacy Detection" (sometimes "Anonymous IP")
);

private static final ParseField NAME = new ParseField("name");
private static final ParseField MAXMIND = new ParseField(Maxmind.NAME);
private static final ParseField IPINFO = new ParseField(Ipinfo.NAME);
private static final ParseField WEB = new ParseField(Web.NAME);
private static final ParseField LOCAL = new ParseField(Local.NAME);

Expand All @@ -99,9 +111,11 @@ public record DatabaseConfiguration(String id, String name, Provider provider) i
if (a[1] != null) {
provider = (Maxmind) a[1];
} else if (a[2] != null) {
provider = (Web) a[2];
provider = (Ipinfo) a[2];
} else if (a[3] != null) {
provider = (Web) a[3];
} else {
provider = (Local) a[3];
provider = (Local) a[4];
}
return new DatabaseConfiguration(id, name, provider);
}
Expand All @@ -114,6 +128,7 @@ public record DatabaseConfiguration(String id, String name, Provider provider) i
(parser, id) -> Maxmind.PARSER.apply(parser, null),
MAXMIND
);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (parser, id) -> Ipinfo.PARSER.apply(parser, null), IPINFO);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (parser, id) -> Web.PARSER.apply(parser, null), WEB);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (parser, id) -> Local.PARSER.apply(parser, null), LOCAL);
}
Expand Down Expand Up @@ -201,8 +216,16 @@ public ActionRequestValidationException validate() {
err.addValidationError("invalid name [" + name + "]: cannot be empty");
}

if (MAXMIND_NAMES.contains(name) == false) {
err.addValidationError("invalid name [" + name + "]: must be a supported name ([" + MAXMIND_NAMES + "])");
// provider-specific name validation
if (provider instanceof Maxmind) {
if (MAXMIND_NAMES.contains(name) == false) {
err.addValidationError("invalid name [" + name + "]: must be a supported name ([" + MAXMIND_NAMES + "])");
}
}
if (provider instanceof Ipinfo) {
if (IPINFO_NAMES.contains(name) == false) {
err.addValidationError("invalid name [" + name + "]: must be a supported name ([" + IPINFO_NAMES + "])");
}
}

// important: the name must be unique across all configurations of this same type,
Expand Down Expand Up @@ -277,6 +300,41 @@ public boolean isReadOnly() {
}
}

public record Ipinfo() implements Provider {
public static final String NAME = "ipinfo";

// this'll become a ConstructingObjectParser once we accept the token (securely) in the json definition
private static final ObjectParser<Ipinfo, Void> PARSER = new ObjectParser<>("ipinfo", Ipinfo::new);

public Ipinfo(StreamInput in) throws IOException {
this();
}

public static Ipinfo parse(XContentParser parser) {
return PARSER.apply(parser, null);
}

@Override
public void writeTo(StreamOutput out) throws IOException {}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.endObject();
return builder;
}

@Override
public String getWriteableName() {
return NAME;
}

@Override
public boolean isReadOnly() {
return false;
}
}

public record Local(String type) implements Provider {
public static final String NAME = "local";

Expand Down

0 comments on commit 21790e4

Please sign in to comment.