From c80ffc6fbfabbeb654dfb3e3cea92d52bea73500 Mon Sep 17 00:00:00 2001 From: Onur Cinar Date: Sat, 17 Jun 2023 03:24:54 +0000 Subject: [PATCH 1/4] IPv4 checker is added. Fixes #23 --- README.md | 1 + checker.go | 1 + doc/checkers/ipv4.md | 28 ++++++++++++++++++++++ ipv4.go | 40 +++++++++++++++++++++++++++++++ ipv4_test.go | 57 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+) create mode 100644 doc/checkers/ipv4.md create mode 100644 ipv4.go create mode 100644 ipv4_test.go diff --git a/README.md b/README.md index 52a9f1d..8e68070 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ This package currently provides the following checkers: - [alphanumeric](doc/checkers/alphanumeric.md) checks if the given string consists of only alphanumeric characters. - [ascii](doc/checkers/ascii.md) checks if the given string consists of only ASCII characters. - [digits](doc/checkers/digits.md) checks if the given string consists of only digit characters. +- [ipv4](doc/checkers/ipv4.md) checks if the given value is an IPv4 address. - [max](doc/checkers/max.md) checks if the given value is less than the given maximum. - [max-length](doc/checkers/maxlength.md) checks if the length of the given value is less than the given maximum length. - [min](doc/checkers/min.md) checks if the given value is greather than the given minimum. diff --git a/checker.go b/checker.go index e2e23f3..9e94c22 100644 --- a/checker.go +++ b/checker.go @@ -34,6 +34,7 @@ var makers = map[string]MakeFunc{ CheckerAlphanumeric: makeAlphanumeric, CheckerAscii: makeAscii, CheckerDigits: makeDigits, + CheckerIpV4: makeIpV4, CheckerMax: makeMax, CheckerMaxLength: makeMaxLength, CheckerMin: makeMin, diff --git a/doc/checkers/ipv4.md b/doc/checkers/ipv4.md new file mode 100644 index 0000000..daee03f --- /dev/null +++ b/doc/checkers/ipv4.md @@ -0,0 +1,28 @@ +# IpV4 Checker + +The ```ipv4``` checker checks if the value is an IPv4 address. If the value is not an IPv4 address, the checker will return the ```NOT_IP_V4``` result. Here is an example: + +```golang +type Request struct { + RemoteIp string `checkers:"ipv4"` +} + +request := &Request{ + RemoteIp: "192.168.1.1", +} + +_, valid := Check(request) +if !valid { + // Send the mistakes back to the user +} +``` + +In your custom checkers, you can call the ```ipV4``` checker function ```IsIpV4``` to validate the user input. Here is an example: + +```golang +result := IsIpV4("192.168.1.1") + +if result != ResultValid { + // Send the mistakes back to the user +} +``` diff --git a/ipv4.go b/ipv4.go new file mode 100644 index 0000000..782c5c7 --- /dev/null +++ b/ipv4.go @@ -0,0 +1,40 @@ +package checker + +import ( + "net" + "reflect" +) + +// CheckerIpV4 is the name of the checker. +const CheckerIpV4 = "ipv4" + +// ResultNotIpV4 indicates that the given value is not an IPv4 address. +const ResultNotIpV4 = "NOT_IP_V4" + +// IsIpV4 checks if the given value is an IPv4 address. +func IsIpV4(value string) Result { + ip := net.ParseIP(value) + if ip == nil { + return ResultNotIpV4 + } + + if ip.To4() == nil { + return ResultNotIpV4 + } + + return ResultValid +} + +// makeIpV4 makes a checker function for the ipV4 checker. +func makeIpV4(_ string) CheckFunc { + return checkIpV4 +} + +// checkIpV4 checks if the given value is an IPv4 address. +func checkIpV4(value, _ reflect.Value) Result { + if value.Kind() != reflect.String { + panic("string expected") + } + + return IsIpV4(value.String()) +} diff --git a/ipv4_test.go b/ipv4_test.go new file mode 100644 index 0000000..a958ee5 --- /dev/null +++ b/ipv4_test.go @@ -0,0 +1,57 @@ +package checker + +import "testing" + +func TestIsIpV4Invalid(t *testing.T) { + if IsIpV4("900.800.200.100") == ResultValid { + t.Fail() + } +} + +func TestIsIpV4Valid(t *testing.T) { + if IsIpV4("192.168.1.1") != ResultValid { + t.Fail() + } +} + +func TestCheckIpV4NonString(t *testing.T) { + defer FailIfNoPanic(t) + + type Request struct { + RemoteIp int `checkers:"ipv4"` + } + + request := &Request{} + + Check(request) +} + +func TestCheckIpV4Invalid(t *testing.T) { + type Request struct { + RemoteIp string `checkers:"ipv4"` + } + + request := &Request{ + RemoteIp: "900.800.200.100", + } + + _, valid := Check(request) + if valid { + t.Fail() + } +} + +func TestCheckIpV4Valid(t *testing.T) { + type Request struct { + RemoteIp string `checkers:"ipv4"` + } + + request := &Request{ + RemoteIp: "192.168.1.1", + } + + _, valid := Check(request) + if !valid { + t.Fail() + } +} From 965cb72a83c0d5b9896eb54c9d176881a349bf43 Mon Sep 17 00:00:00 2001 From: Onur Cinar Date: Sat, 17 Jun 2023 03:31:47 +0000 Subject: [PATCH 2/4] IPv6 checker is added. Fixes #24 --- README.md | 1 + checker.go | 1 + doc/checkers/ipv4.md | 2 +- doc/checkers/ipv6.md | 28 ++++++++++++++++++++++ ipv6.go | 40 +++++++++++++++++++++++++++++++ ipv6_test.go | 57 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 doc/checkers/ipv6.md create mode 100644 ipv6.go create mode 100644 ipv6_test.go diff --git a/README.md b/README.md index 8e68070..5182561 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ This package currently provides the following checkers: - [ascii](doc/checkers/ascii.md) checks if the given string consists of only ASCII characters. - [digits](doc/checkers/digits.md) checks if the given string consists of only digit characters. - [ipv4](doc/checkers/ipv4.md) checks if the given value is an IPv4 address. +- [ipv6](doc/checkers/ipv6.md) checks if the given value is an IPv6 address. - [max](doc/checkers/max.md) checks if the given value is less than the given maximum. - [max-length](doc/checkers/maxlength.md) checks if the length of the given value is less than the given maximum length. - [min](doc/checkers/min.md) checks if the given value is greather than the given minimum. diff --git a/checker.go b/checker.go index 9e94c22..d450830 100644 --- a/checker.go +++ b/checker.go @@ -35,6 +35,7 @@ var makers = map[string]MakeFunc{ CheckerAscii: makeAscii, CheckerDigits: makeDigits, CheckerIpV4: makeIpV4, + CheckerIpV6: makeIpV6, CheckerMax: makeMax, CheckerMaxLength: makeMaxLength, CheckerMin: makeMin, diff --git a/doc/checkers/ipv4.md b/doc/checkers/ipv4.md index daee03f..e7149e7 100644 --- a/doc/checkers/ipv4.md +++ b/doc/checkers/ipv4.md @@ -17,7 +17,7 @@ if !valid { } ``` -In your custom checkers, you can call the ```ipV4``` checker function ```IsIpV4``` to validate the user input. Here is an example: +In your custom checkers, you can call the ```ipv4``` checker function ```IsIpV4``` to validate the user input. Here is an example: ```golang result := IsIpV4("192.168.1.1") diff --git a/doc/checkers/ipv6.md b/doc/checkers/ipv6.md new file mode 100644 index 0000000..e5e7ed5 --- /dev/null +++ b/doc/checkers/ipv6.md @@ -0,0 +1,28 @@ +# IpV4 Checker + +The ```ipv6``` checker checks if the value is an IPv6 address. If the value is not an IPv6 address, the checker will return the ```NOT_IP_V6``` result. Here is an example: + +```golang +type Request struct { + RemoteIp string `checkers:"ipv6"` +} + +request := &Request{ + RemoteIp: "2001:db8::68", +} + +_, valid := Check(request) +if !valid { + // Send the mistakes back to the user +} +``` + +In your custom checkers, you can call the ```ipv6``` checker function ```IsIpV6``` to validate the user input. Here is an example: + +```golang +result := IsIpV6("2001:db8::68") + +if result != ResultValid { + // Send the mistakes back to the user +} +``` diff --git a/ipv6.go b/ipv6.go new file mode 100644 index 0000000..b6a33b8 --- /dev/null +++ b/ipv6.go @@ -0,0 +1,40 @@ +package checker + +import ( + "net" + "reflect" +) + +// CheckerIpV6 is the name of the checker. +const CheckerIpV6 = "ipv6" + +// ResultNotIpV6 indicates that the given value is not an IPv6 address. +const ResultNotIpV6 = "NOT_IP_V6" + +// IsIpV6 checks if the given value is an IPv6 address. +func IsIpV6(value string) Result { + ip := net.ParseIP(value) + if ip == nil { + return ResultNotIpV6 + } + + if ip.To16() == nil { + return ResultNotIpV6 + } + + return ResultValid +} + +// makeIpV6 makes a checker function for the ipV6 checker. +func makeIpV6(_ string) CheckFunc { + return checkIpV6 +} + +// checkIpV6 checks if the given value is an IPv6 address. +func checkIpV6(value, _ reflect.Value) Result { + if value.Kind() != reflect.String { + panic("string expected") + } + + return IsIpV6(value.String()) +} diff --git a/ipv6_test.go b/ipv6_test.go new file mode 100644 index 0000000..fdf3690 --- /dev/null +++ b/ipv6_test.go @@ -0,0 +1,57 @@ +package checker + +import "testing" + +func TestIsIpV6Invalid(t *testing.T) { + if IsIpV6("900.800.200.100") == ResultValid { + t.Fail() + } +} + +func TestIsIpV6Valid(t *testing.T) { + if IsIpV6("2001:db8::68") != ResultValid { + t.Fail() + } +} + +func TestCheckIpV6NonString(t *testing.T) { + defer FailIfNoPanic(t) + + type Request struct { + RemoteIp int `checkers:"ipv6"` + } + + request := &Request{} + + Check(request) +} + +func TestCheckIpV6Invalid(t *testing.T) { + type Request struct { + RemoteIp string `checkers:"ipv6"` + } + + request := &Request{ + RemoteIp: "900.800.200.100", + } + + _, valid := Check(request) + if valid { + t.Fail() + } +} + +func TestCheckIpV6Valid(t *testing.T) { + type Request struct { + RemoteIp string `checkers:"ipv6"` + } + + request := &Request{ + RemoteIp: "2001:db8::68", + } + + _, valid := Check(request) + if !valid { + t.Fail() + } +} From f71fb35e62428d5c88e931e0d0572e49aa7b3f9d Mon Sep 17 00:00:00 2001 From: Onur Cinar Date: Sat, 17 Jun 2023 03:39:07 +0000 Subject: [PATCH 3/4] IP checker is added. Fixes #22 --- README.md | 1 + checker.go | 1 + doc/checkers/ip.md | 28 ++++++++++++++++++++++ doc/checkers/ipv4.md | 2 +- doc/checkers/ipv6.md | 2 +- ip.go | 36 ++++++++++++++++++++++++++++ ip_test.go | 57 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 doc/checkers/ip.md create mode 100644 ip.go create mode 100644 ip_test.go diff --git a/README.md b/README.md index 5182561..be985a9 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ This package currently provides the following checkers: - [alphanumeric](doc/checkers/alphanumeric.md) checks if the given string consists of only alphanumeric characters. - [ascii](doc/checkers/ascii.md) checks if the given string consists of only ASCII characters. - [digits](doc/checkers/digits.md) checks if the given string consists of only digit characters. +- [ip](doc/checkers/ip.md) checks if the given value is an IP address. - [ipv4](doc/checkers/ipv4.md) checks if the given value is an IPv4 address. - [ipv6](doc/checkers/ipv6.md) checks if the given value is an IPv6 address. - [max](doc/checkers/max.md) checks if the given value is less than the given maximum. diff --git a/checker.go b/checker.go index d450830..ca4bcd9 100644 --- a/checker.go +++ b/checker.go @@ -34,6 +34,7 @@ var makers = map[string]MakeFunc{ CheckerAlphanumeric: makeAlphanumeric, CheckerAscii: makeAscii, CheckerDigits: makeDigits, + CheckerIp: makeIp, CheckerIpV4: makeIpV4, CheckerIpV6: makeIpV6, CheckerMax: makeMax, diff --git a/doc/checkers/ip.md b/doc/checkers/ip.md new file mode 100644 index 0000000..58d4af2 --- /dev/null +++ b/doc/checkers/ip.md @@ -0,0 +1,28 @@ +# IP Checker + +The ```ip``` checker checks if the value is an IP address. If the value is not an IP address, the checker will return the ```NOT_IP``` result. Here is an example: + +```golang +type Request struct { + RemoteIp string `checkers:"ip"` +} + +request := &Request{ + RemoteIp: "192.168.1.1", +} + +_, valid := Check(request) +if !valid { + // Send the mistakes back to the user +} +``` + +In your custom checkers, you can call the ```ip``` checker function ```IsIp``` to validate the user input. Here is an example: + +```golang +result := IsIp("2001:db8::68") + +if result != ResultValid { + // Send the mistakes back to the user +} +``` diff --git a/doc/checkers/ipv4.md b/doc/checkers/ipv4.md index e7149e7..ee7ac0e 100644 --- a/doc/checkers/ipv4.md +++ b/doc/checkers/ipv4.md @@ -1,4 +1,4 @@ -# IpV4 Checker +# IPv4 Checker The ```ipv4``` checker checks if the value is an IPv4 address. If the value is not an IPv4 address, the checker will return the ```NOT_IP_V4``` result. Here is an example: diff --git a/doc/checkers/ipv6.md b/doc/checkers/ipv6.md index e5e7ed5..e2801ae 100644 --- a/doc/checkers/ipv6.md +++ b/doc/checkers/ipv6.md @@ -1,4 +1,4 @@ -# IpV4 Checker +# IPv6 Checker The ```ipv6``` checker checks if the value is an IPv6 address. If the value is not an IPv6 address, the checker will return the ```NOT_IP_V6``` result. Here is an example: diff --git a/ip.go b/ip.go new file mode 100644 index 0000000..c9bd10e --- /dev/null +++ b/ip.go @@ -0,0 +1,36 @@ +package checker + +import ( + "net" + "reflect" +) + +// CheckerIp is the name of the checker. +const CheckerIp = "ip" + +// ResultNotIp indicates that the given value is not an IP address. +const ResultNotIp = "NOT_IP" + +// IsIp checks if the given value is an IP address. +func IsIp(value string) Result { + ip := net.ParseIP(value) + if ip == nil { + return ResultNotIp + } + + return ResultValid +} + +// makeIp makes a checker function for the ip checker. +func makeIp(_ string) CheckFunc { + return checkIp +} + +// checkIp checks if the given value is an IP address. +func checkIp(value, _ reflect.Value) Result { + if value.Kind() != reflect.String { + panic("string expected") + } + + return IsIp(value.String()) +} diff --git a/ip_test.go b/ip_test.go new file mode 100644 index 0000000..1fd607b --- /dev/null +++ b/ip_test.go @@ -0,0 +1,57 @@ +package checker + +import "testing" + +func TestIsIpInvalid(t *testing.T) { + if IsIp("900.800.200.100") == ResultValid { + t.Fail() + } +} + +func TestIsIpValid(t *testing.T) { + if IsIp("2001:db8::68") != ResultValid { + t.Fail() + } +} + +func TestCheckIpNonString(t *testing.T) { + defer FailIfNoPanic(t) + + type Request struct { + RemoteIp int `checkers:"ip"` + } + + request := &Request{} + + Check(request) +} + +func TestCheckIpInvalid(t *testing.T) { + type Request struct { + RemoteIp string `checkers:"ip"` + } + + request := &Request{ + RemoteIp: "900.800.200.100", + } + + _, valid := Check(request) + if valid { + t.Fail() + } +} + +func TestCheckIpValid(t *testing.T) { + type Request struct { + RemoteIp string `checkers:"ip"` + } + + request := &Request{ + RemoteIp: "192.168.1.1", + } + + _, valid := Check(request) + if !valid { + t.Fail() + } +} From eac2b0c08778431b17e111647a8b72d183f2e3e4 Mon Sep 17 00:00:00 2001 From: Onur Cinar Date: Sat, 17 Jun 2023 03:43:57 +0000 Subject: [PATCH 4/4] IPv4 and IPv6 tests. --- ipv4_test.go | 6 ++++++ ipv6.go | 2 +- ipv6_test.go | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ipv4_test.go b/ipv4_test.go index a958ee5..5e853a7 100644 --- a/ipv4_test.go +++ b/ipv4_test.go @@ -8,6 +8,12 @@ func TestIsIpV4Invalid(t *testing.T) { } } +func TestIsIpV4InvalidV6(t *testing.T) { + if IsIpV4("2001:db8::68") == ResultValid { + t.Fail() + } +} + func TestIsIpV4Valid(t *testing.T) { if IsIpV4("192.168.1.1") != ResultValid { t.Fail() diff --git a/ipv6.go b/ipv6.go index b6a33b8..eb56fe9 100644 --- a/ipv6.go +++ b/ipv6.go @@ -18,7 +18,7 @@ func IsIpV6(value string) Result { return ResultNotIpV6 } - if ip.To16() == nil { + if ip.To4() != nil { return ResultNotIpV6 } diff --git a/ipv6_test.go b/ipv6_test.go index fdf3690..bc8489d 100644 --- a/ipv6_test.go +++ b/ipv6_test.go @@ -8,6 +8,12 @@ func TestIsIpV6Invalid(t *testing.T) { } } +func TestIsIpV6InvalidV4(t *testing.T) { + if IsIpV6("192.168.1.1") == ResultValid { + t.Fail() + } +} + func TestIsIpV6Valid(t *testing.T) { if IsIpV6("2001:db8::68") != ResultValid { t.Fail()