From ac8832ee4abd978159c0084925a844c11c97fe77 Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Tue, 21 Jul 2015 02:00:36 +0200 Subject: [PATCH] add diaspora handle validator and test --- lib/diaspora_federation/validators.rb | 3 +- .../validators/person_validator.rb | 2 +- .../validators/profile_validator.rb | 2 +- .../validators/rules/diaspora_id.rb | 43 +++++++++++ spec/factories.rb | 4 +- .../validators/rules/diaspora_id_spec.rb | 74 +++++++++++++++++++ 6 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 lib/diaspora_federation/validators/rules/diaspora_id.rb create mode 100644 spec/lib/diaspora_federation/validators/rules/diaspora_id_spec.rb diff --git a/lib/diaspora_federation/validators.rb b/lib/diaspora_federation/validators.rb index a5f0e86..79d6f40 100644 --- a/lib/diaspora_federation/validators.rb +++ b/lib/diaspora_federation/validators.rb @@ -1,6 +1,4 @@ require "validation" -require "validation/rule/not_empty" -require "validation/rule/email" require "validation/rule/regular_expression" require "validation/rule/uri" @@ -17,6 +15,7 @@ end require "diaspora_federation/validators/rules/birthday" require "diaspora_federation/validators/rules/boolean" +require "diaspora_federation/validators/rules/diaspora_id" require "diaspora_federation/validators/rules/guid" require "diaspora_federation/validators/rules/not_nil" require "diaspora_federation/validators/rules/public_key" diff --git a/lib/diaspora_federation/validators/person_validator.rb b/lib/diaspora_federation/validators/person_validator.rb index 1e58117..525a00c 100644 --- a/lib/diaspora_federation/validators/person_validator.rb +++ b/lib/diaspora_federation/validators/person_validator.rb @@ -5,7 +5,7 @@ module DiasporaFederation rule :guid, :guid - rule :diaspora_handle, %i(not_empty email) + rule :diaspora_handle, :diaspora_id rule :url, :u_r_i # WTF? :uri -> Uri -> "uninitialized constant Uri", :u_r_i -> URI -> \o/ diff --git a/lib/diaspora_federation/validators/profile_validator.rb b/lib/diaspora_federation/validators/profile_validator.rb index 1e6cfa8..ab672ff 100644 --- a/lib/diaspora_federation/validators/profile_validator.rb +++ b/lib/diaspora_federation/validators/profile_validator.rb @@ -3,7 +3,7 @@ module DiasporaFederation class ProfileValidator < Validation::Validator include Validation - rule :diaspora_handle, %i(not_empty email) + rule :diaspora_handle, :diaspora_id # the name must not contain a semicolon because of mentions # @{ ; } diff --git a/lib/diaspora_federation/validators/rules/diaspora_id.rb b/lib/diaspora_federation/validators/rules/diaspora_id.rb new file mode 100644 index 0000000..817e84d --- /dev/null +++ b/lib/diaspora_federation/validators/rules/diaspora_id.rb @@ -0,0 +1,43 @@ +module Validation + module Rule + # Diaspora ID validation rule + # + # This rule is based on https://github.com/zombor/Validator/blob/master/lib/validation/rule/email.rb + # which was adapted from https://github.com/emmanuel/aequitas/blob/master/lib/aequitas/rule/format/email_address.rb + class DiasporaId + DIASPORA_HANDLE = begin + letter = "a-zA-Z" + digit = "0-9" + username = "[#{letter}#{digit}\-\_\.]+" + atext = "[#{letter}#{digit}+\=\-\_]" + dot_atom = "#{atext}+([.]#{atext}*)*" + no_ws_ctl = '\x01-\x08\x11\x12\x14-\x1f\x7f' + text = '[\x01-\x09\x11\x12\x14-\x7f]' + quoted_pair = "(\\x5c#{text})" + dtext = "[#{no_ws_ctl}\\x21-\\x5a\\x5e-\\x7e]" + dcontent = "(?:#{dtext}|#{quoted_pair})" + domain_literal = "\\[#{dcontent}+\\]" + domain = "(?:#{dot_atom}|#{domain_literal})" + port = "(:[#{digit}]+)?" + addr_spec = "#{username}\@#{domain}#{port}" + + /\A#{addr_spec}\z/u + end + + # The error key for this rule + def error_key + :diaspora_id + end + + # Determines if value is a valid email + def valid_value?(value) + !DIASPORA_HANDLE.match(value).nil? + end + + # This rule has no params + def params + {} + end + end + end +end diff --git a/spec/factories.rb b/spec/factories.rb index 79f2b69..553a4fd 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -19,7 +19,7 @@ FactoryGirl.define do factory :person_entity, class: DiasporaFederation::Entities::Person do guid UUID.generate :compact - diaspora_handle "testing@example.com" + diaspora_handle url "http://localhost:3000/" exported_key { generate(:public_key) } profile { @@ -29,7 +29,7 @@ FactoryGirl.define do end factory :profile_entity, class: DiasporaFederation::Entities::Profile do - diaspora_handle "testing@example.com" + diaspora_handle first_name "my_name" last_name nil tag_string "#i #love #tags" diff --git a/spec/lib/diaspora_federation/validators/rules/diaspora_id_spec.rb b/spec/lib/diaspora_federation/validators/rules/diaspora_id_spec.rb new file mode 100644 index 0000000..f1f7a0e --- /dev/null +++ b/spec/lib/diaspora_federation/validators/rules/diaspora_id_spec.rb @@ -0,0 +1,74 @@ +describe Validation::Rule::DiasporaId do + it "will not accept parameters" do + validator = Validation::Validator.new({}) + expect { + validator.rule(:diaspora_id, diaspora_id: {param: true}) + }.to raise_error ArgumentError + end + + context "validation" do + it "validates a normal diaspora id" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "some_user@example.com")) + validator.rule(:diaspora_id, :diaspora_id) + + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + + it "validates a diaspora id with localhost" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "some_user@localhost")) + validator.rule(:diaspora_id, :diaspora_id) + + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + + it "validates a diaspora id with port" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "some_user@example.com:3000")) + validator.rule(:diaspora_id, :diaspora_id) + + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + + it "validates a diaspora id with IPv4 address" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "some_user@123.45.67.89")) + validator.rule(:diaspora_id, :diaspora_id) + + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + + it "validates a diaspora id with IPv6 address" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "some_user@[2001:1234:5678:90ab:cdef::1]")) + validator.rule(:diaspora_id, :diaspora_id) + + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + + it "validates a diaspora id with . and -" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "some-fancy.user@example.com")) + validator.rule(:diaspora_id, :diaspora_id) + + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + + it "fails if the diaspora id contains a / in the domain-name" do + validator = Validation::Validator.new(OpenStruct.new(diaspora_id: "some_user@example.com/friendica")) + 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 a special-chars 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 + end +end