aboutsummaryrefslogtreecommitdiff
path: root/app/validators
diff options
context:
space:
mode:
Diffstat (limited to 'app/validators')
-rw-r--r--app/validators/email_validator.rb33
-rw-r--r--app/validators/url_validator.rb33
2 files changed, 66 insertions, 0 deletions
diff --git a/app/validators/email_validator.rb b/app/validators/email_validator.rb
new file mode 100644
index 0000000..4191907
--- /dev/null
+++ b/app/validators/email_validator.rb
@@ -0,0 +1,33 @@
+# SPDX-FileCopyrightText: 2020 IN COMMON Collective <collective@incommon.cc>
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# frozen_string_literal: true
+
+# = Email Validator =
+#
+# In order to be considered valid, value must be:
+#
+# - a valid Email URI
+# - parsable as an URI
+# - have a hostname
+# - have a valid public TLD
+#
+class EmailValidator < ActiveModel::EachValidator
+ def validate_each(record, attribute, value)
+ unless valid_email_address?(value)
+ record.errors[attribute] << (options[:message] || 'is an invalid email address')
+ end
+ end
+
+ private
+
+ def valid_email_address?(value)
+ uri = URI.parse("mailto:#{value}")
+ uri.is_a?(URI::MailTo) &&
+ uri.to == value &&
+ IANA::TLD.valid?(value.split('@', 2).last.split('.').compact.last)
+ rescue URI::InvalidURIError, URI::InvalidComponentError
+ false
+ end
+end
diff --git a/app/validators/url_validator.rb b/app/validators/url_validator.rb
new file mode 100644
index 0000000..5f790b3
--- /dev/null
+++ b/app/validators/url_validator.rb
@@ -0,0 +1,33 @@
+# SPDX-FileCopyrightText: 2020 IN COMMON Collective <collective@incommon.cc>
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# frozen_string_literal: true
+
+# = URL Validator =
+#
+# In order to be considered valid, value must be:
+#
+# - parsable as an URI
+# - use the http or https scheme
+# - have a hostname
+# - have a valid public TLD
+#
+class UrlValidator < ActiveModel::EachValidator
+ def validate_each(record, attribute, value)
+ unless valid_web_address?(value)
+ record.errors[attribute] << (options[:message] || 'is an invalid Web URL')
+ end
+ end
+
+ private
+
+ def valid_web_address?(value)
+ uri = URI.parse(value)
+ uri.is_a?(URI::HTTP) &&
+ uri.host.present? &&
+ IANA::TLD.valid?(uri.host.split('.').compact.last)
+ rescue URI::InvalidURIError
+ false
+ end
+end