diff --git a/lib/diaspora_federation/validators/rules/diaspora_id.rb b/lib/diaspora_federation/validators/rules/diaspora_id.rb index 944a9b0..42bcc0b 100644 --- a/lib/diaspora_federation/validators/rules/diaspora_id.rb +++ b/lib/diaspora_federation/validators/rules/diaspora_id.rb @@ -4,19 +4,19 @@ module Validation # # A simple rule to validate the base structure of diaspora* IDs. class DiasporaId + # Maximum length of a full diaspora* ID + DIASPORA_ID_MAX_LENGTH = 255 + # The Regex for a valid diaspora* ID DIASPORA_ID_REGEX = begin - letter = "a-zA-Z" - digit = "0-9" - hexadecimal = "[a-fA-F#{digit}]" - username = "[#{letter}#{digit}\\-\\_\\.]+" - hostname_part = "[#{letter}#{digit}\\-]" + username = "[[:lower:]\\d\\-\\.\\_]+" + hostname_part = "[[:lower:]\\d\\-]" hostname = "#{hostname_part}+(?:[.]#{hostname_part}*)*" - ipv4 = "(?:[#{digit}]{1,3}\\.){3}[#{digit}]{1,3}" - ipv6 = "\\[(?:#{hexadecimal}{0,4}:){0,7}#{hexadecimal}{1,4}\\]" + ipv4 = "(?:[\\d]{1,3}\\.){3}[\\d]{1,3}" + ipv6 = "\\[(?:[[:xdigit:]]{0,4}:){0,7}[[:xdigit:]]{1,4}\\]" ip_addr = "(?:#{ipv4}|#{ipv6})" domain = "(?:#{hostname}|#{ip_addr})" - port = "(?::[#{digit}]+)?" + port = "(?::[\\d]+)?" "#{username}\\@#{domain}#{port}" end @@ -32,7 +32,10 @@ module Validation # Determines if value is a valid diaspora* ID def valid_value?(value) - value.is_a?(String) && value =~ DIASPORA_ID + return false unless value.is_a?(String) + return false if value.length > DIASPORA_ID_MAX_LENGTH + + value =~ DIASPORA_ID end # This rule has no params. diff --git a/spec/lib/diaspora_federation/validators/rules/diaspora_id_spec.rb b/spec/lib/diaspora_federation/validators/rules/diaspora_id_spec.rb index 178b190..a796530 100644 --- a/spec/lib/diaspora_federation/validators/rules/diaspora_id_spec.rb +++ b/spec/lib/diaspora_federation/validators/rules/diaspora_id_spec.rb @@ -83,6 +83,30 @@ describe Validation::Rule::DiasporaId do expect(validator.errors).to include(:diaspora_id) end + it "fails if the diaspora* ID contains uppercase characters in the username" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "SOME_USER@example.com")) + validator.rule(:diaspora_id, :diaspora_id) + + expect(validator).not_to be_valid + expect(validator.errors).to include(:diaspora_id) + end + + it "fails if the diaspora* ID contains uppercase characters in the domain-name" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "some_user@EXAMPLE.com")) + validator.rule(:diaspora_id, :diaspora_id) + + expect(validator).not_to be_valid + expect(validator.errors).to include(:diaspora_id) + end + + it "fails if the diaspora* ID is longer than 255 characters" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "#{'a' * 244}@example.com")) + validator.rule(:diaspora_id, :diaspora_id) + + expect(validator).not_to be_valid + expect(validator.errors).to include(:diaspora_id) + end + it "fails for nil and empty" do [nil, ""].each do |val| validator = Validation::Validator.new(OpenStruct.new(diaspora_id: val))