From: Tomasz Wrobel Date: Tue, 17 Nov 2020 07:59:43 +0000 (+0100) Subject: [OOM CERT-SERVICE-CLIENT] Add URI validator (RFC 3986) X-Git-Tag: 2.3.0~8^2 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=41993ca46abed06ba642c63680355b5e83327115;p=oom%2Fplatform%2Fcert-service.git [OOM CERT-SERVICE-CLIENT] Add URI validator (RFC 3986) Issue-ID: OOM-2632 Signed-off-by: Tomasz Wrobel Change-Id: Ia71d413a56f65b0a51ff5c2e7522035f41e06faf --- diff --git a/certServiceClient/src/main/java/org/onap/oom/certservice/client/configuration/validation/UriValidator.java b/certServiceClient/src/main/java/org/onap/oom/certservice/client/configuration/validation/UriValidator.java new file mode 100644 index 00000000..6971d8ea --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/oom/certservice/client/configuration/validation/UriValidator.java @@ -0,0 +1,50 @@ +/* + * ============LICENSE_START======================================================= + * oom-certservice-client + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.certservice.client.configuration.validation; + +/** + * Compliant with the RFC3986 + */ +public final class UriValidator { + + private UriValidator() { + } + + private static final String RFC3986_URI_MATCH_PATTERN = "([A-Za-z][A-Za-z0-9+\\-.]*):(?:(//)(?:((?:[A-Za-z0-9\\-" + + "._~!$&'()*+,;=:]|%[0-9A-Fa-f]{2})*)@)?((?:\\[(?:(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|::(?:[0-9A-Fa-f]{1,4}:){5}|" + + "(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::" + + "(?:[0-9A-Fa-f]{1,4}:){3}|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|(?:" + + "(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|(?:(?:[0-9A-Fa-f]{1,4}:){0," + + "4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\" + + ".){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})" + + "?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)|[Vv][0-9A-Fa-f]+\\.[A-Za-z0-9\\-" + + "._~!$&'()*+,;=:]+)\\]|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}" + + "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[A-Za-z0-9\\-._~!$&'()*+,;=]|%[0-9A-Fa-f]{2})*))(?::([0-9]*))?" + + "((?:/(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)|/((?:(?:[A-Za-z0-9\\-._~!$&'()*+,;" + + "=:@]|%[0-9A-Fa-f]{2})+(?:/(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)?)|((?:[A-Za-z0-9\\-" + + "._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:/(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)|)(?:\\?(" + + "(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*))?(?:\\#((?:[A-Za-z0-9\\-._~!$&'()*+,;" + + "=:@/?]|%[0-9A-Fa-f]{2})*))?"; + + public static boolean isValidUri(String uri) { + return uri.matches(RFC3986_URI_MATCH_PATTERN); + } +} diff --git a/certServiceClient/src/main/java/org/onap/oom/certservice/client/configuration/validation/ValidatorsFactory.java b/certServiceClient/src/main/java/org/onap/oom/certservice/client/configuration/validation/ValidatorsFactory.java index 771ce3f2..8eeac74a 100644 --- a/certServiceClient/src/main/java/org/onap/oom/certservice/client/configuration/validation/ValidatorsFactory.java +++ b/certServiceClient/src/main/java/org/onap/oom/certservice/client/configuration/validation/ValidatorsFactory.java @@ -45,4 +45,7 @@ public class ValidatorsFactory { .anyMatch(name -> name.equals(outputType)); } + public Predicate uriValidator() { + return UriValidator::isValidUri; + } } diff --git a/certServiceClient/src/test/java/org/onap/oom/certservice/client/configuration/validation/UriValidatorTest.java b/certServiceClient/src/test/java/org/onap/oom/certservice/client/configuration/validation/UriValidatorTest.java new file mode 100644 index 00000000..ed358b6f --- /dev/null +++ b/certServiceClient/src/test/java/org/onap/oom/certservice/client/configuration/validation/UriValidatorTest.java @@ -0,0 +1,162 @@ +/* + * ============LICENSE_START======================================================= + * oom-certservice-client + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.certservice.client.configuration.validation; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class UriValidatorTest { + + /** + * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + */ + + @ParameterizedTest + @ValueSource(strings = {"http:/", "http:", "http://"}) + void shouldTrueForValidScheme(String uri) { + assertThat(UriValidator.isValidUri(uri)).isTrue(); + } + + @ParameterizedTest + @ValueSource(strings = {"example.com", "www.example.com", "0.0.0.0", "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"}) + void shouldFalseForUriWithoutScheme(String uri) { + assertThat(UriValidator.isValidUri(uri)).isFalse(); + } + + @ParameterizedTest + @ValueSource(strings = {"*http://", "_http://", "?http://"}) + void shouldFalseForUriWithInvalidScheme(String uri) { + assertThat(UriValidator.isValidUri(uri)).isFalse(); + } + + /** + * authority = [ userinfo "@" ] host [ ":" port ] + *

+ * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) + *

+ * host = IP-literal / IPv4address / reg-name + */ + + @ParameterizedTest + @ValueSource(strings = { + "http://user:password@example.com", + "http://user@example.com", + "http://user:password:test@example.com", + "http://user-info:password@example.com"}) + void shouldTrueForValidUserInAuthority(String uri) { + assertThat(UriValidator.isValidUri(uri)).isTrue(); + } + + @ParameterizedTest + @ValueSource(strings = { + "http://user:password", + "http://user:password:test:"}) + void shouldFalseForMissingHostInAuthority(String uri) { + assertThat(UriValidator.isValidUri(uri)).isFalse(); + } + + @ParameterizedTest + @ValueSource(strings = { + "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]/test", + "https://[2001:db8:85a3:8d3:1319:8a2e:370:7348]/", + "http://8.8.8.8/", + "http://8.8.8.8/test"}) + void shouldTrueForUriContainsIP(String uri) { + assertThat(UriValidator.isValidUri(uri)).isTrue(); + } + + @ParameterizedTest + @ValueSource(strings = { + "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:443/test", + "https://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443/", + "http://8.8.8.8:8080/test", + "https://8.8.8.8:443/"}) + void shouldTrueForUriContainsIPAndPort(String uri) { + assertThat(UriValidator.isValidUri(uri)).isTrue(); + } + + @ParameterizedTest + @ValueSource(strings = { + "http:/path.to.file", + "http:/file", + "http:/ptah/to/file"}) + void shouldTrueForMissingAuthority(String uri) { + assertThat(UriValidator.isValidUri(uri)).isTrue(); + } + + /** + * PATH QUERY FRAGMENT + */ + + @ParameterizedTest + @ValueSource(strings = { + "http://example.com/path/to/file", + "http://example.com/path", + "http://example.com/",}) + void shouldTrueForPathWithAuthority(String uri) { + assertThat(UriValidator.isValidUri(uri)).isTrue(); + } + + @ParameterizedTest + @ValueSource(strings = { + "http:/path/to/file", + "http:/path", + "http:/",}) + void shouldTrueForPathWithoutAuthority(String uri) { + assertThat(UriValidator.isValidUri(uri)).isTrue(); + } + + + @ParameterizedTest + @ValueSource(strings = { + "http://example.com/test.txt?test=test1&test2=test3#onap", + "http://example.com?", + "http://example.com?test=tes1&#", + "http://example.com#onap"}) + void shouldTrueForUriWithQueryAndFragmentInPath(String uri) { + assertThat(UriValidator.isValidUri(uri)).isTrue(); + } + + @ParameterizedTest + @ValueSource(strings = { + "http://example.com/test.txt?#onap#?", + "http://example.com?##", + "http://www.example.com/file%GF.html"}) + void shouldFalseForUriWithWrongQueryOrWrongFragmentInPath(String uri) { + assertThat(UriValidator.isValidUri(uri)).isFalse(); + } + + @ParameterizedTest + @ValueSource(strings = { + "ftp://ftp.is.co.za/rfc/rfc1808.txt", + "http://www.ietf.org/rfc/rfc2396.txt", + "ldap://[2001:db8::7]/c=GB?objectClass?one", + "mailto:John.Doe@example.com", + "news:comp.infosystems.www.servers.unix", + "tel:+1-816-555-1212", + "telnet://192.0.2.16:80/", + "urn:oasis:names:specification:docbook:dtd:xml:4.1.2"}) + void shouldTrueForRFC3986Examples(String uri) { + assertThat(UriValidator.isValidUri(uri)).isTrue(); + } +}