From 1d1ad7e0b68039100029f20a84fd867fe92cbb32 Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Thu, 5 Oct 2017 03:27:07 -0700 Subject: [PATCH] Refactor DN error classes --- .../normalize_ldap_extern_uids_range.rb | 29 +++--- lib/gitlab/ldap/dn.rb | 27 +++--- lib/gitlab/ldap/person.rb | 2 +- spec/lib/gitlab/ldap/dn_spec.rb | 96 +++++++++---------- 4 files changed, 78 insertions(+), 76 deletions(-) diff --git a/lib/gitlab/background_migration/normalize_ldap_extern_uids_range.rb b/lib/gitlab/background_migration/normalize_ldap_extern_uids_range.rb index 7a18feb8a4f..cf7eafcff3b 100644 --- a/lib/gitlab/background_migration/normalize_ldap_extern_uids_range.rb +++ b/lib/gitlab/background_migration/normalize_ldap_extern_uids_range.rb @@ -10,10 +10,11 @@ module Gitlab # accompanied by another migration. module Gitlab module LDAP - MalformedDnError = Class.new(StandardError) - UnsupportedDnFormatError = Class.new(StandardError) - class DN + FormatError = Class.new(StandardError) + MalformedError = Class.new(FormatError) + UnsupportedError = Class.new(FormatError) + def self.normalize_value(given_value) dummy_dn = "placeholder=#{given_value}" normalized_dn = new(*dummy_dn).to_normalized_s @@ -79,19 +80,19 @@ module Gitlab state = :key_oid key << char when ' ' then state = :key - else raise(MalformedDnError, "Unrecognized first character of an RDN attribute type name \"#{char}\"") + else raise(MalformedError, "Unrecognized first character of an RDN attribute type name \"#{char}\"") end when :key_normal then case char when '=' then state = :value when 'a'..'z', 'A'..'Z', '0'..'9', '-', ' ' then key << char - else raise(MalformedDnError, "Unrecognized RDN attribute type name character \"#{char}\"") + else raise(MalformedError, "Unrecognized RDN attribute type name character \"#{char}\"") end when :key_oid then case char when '=' then state = :value when '0'..'9', '.', ' ' then key << char - else raise(MalformedDnError, "Unrecognized RDN OID attribute type name character \"#{char}\"") + else raise(MalformedError, "Unrecognized RDN OID attribute type name character \"#{char}\"") end when :value then case char @@ -118,7 +119,7 @@ module Gitlab yield key.string.strip, rstrip_except_escaped(value.string, dn_index) key = StringIO.new value = StringIO.new - when '+' then raise(UnsupportedDnFormatError, "Multivalued RDNs are not supported") + when '+' then raise(UnsupportedError, "Multivalued RDNs are not supported") else value << char end when :value_normal_escape then @@ -135,7 +136,7 @@ module Gitlab when '0'..'9', 'a'..'f', 'A'..'F' then state = :value_normal value << "#{hex_buffer}#{char}".to_i(16).chr - else raise(MalformedDnError, "Invalid escaped hex code \"\\#{hex_buffer}#{char}\"") + else raise(MalformedError, "Invalid escaped hex code \"\\#{hex_buffer}#{char}\"") end when :value_quoted then case char @@ -157,7 +158,7 @@ module Gitlab when '0'..'9', 'a'..'f', 'A'..'F' then state = :value_quoted value << "#{hex_buffer}#{char}".to_i(16).chr - else raise(MalformedDnError, "Expected the second character of a hex pair inside a double quoted value, but got \"#{char}\"") + else raise(MalformedError, "Expected the second character of a hex pair inside a double quoted value, but got \"#{char}\"") end when :value_hexstring then case char @@ -170,14 +171,14 @@ module Gitlab yield key.string.strip, rstrip_except_escaped(value.string, dn_index) key = StringIO.new value = StringIO.new - else raise(MalformedDnError, "Expected the first character of a hex pair, but got \"#{char}\"") + else raise(MalformedError, "Expected the first character of a hex pair, but got \"#{char}\"") end when :value_hexstring_hex then case char when '0'..'9', 'a'..'f', 'A'..'F' then state = :value_hexstring value << char - else raise(MalformedDnError, "Expected the second character of a hex pair, but got \"#{char}\"") + else raise(MalformedError, "Expected the second character of a hex pair, but got \"#{char}\"") end when :value_end then case char @@ -187,14 +188,14 @@ module Gitlab yield key.string.strip, rstrip_except_escaped(value.string, dn_index) key = StringIO.new value = StringIO.new - else raise(MalformedDnError, "Expected the end of an attribute value, but got \"#{char}\"") + else raise(MalformedError, "Expected the end of an attribute value, but got \"#{char}\"") end else raise "Fell out of state machine" end end # Last pair - raise(MalformedDnError, 'DN string ended unexpectedly') unless + raise(MalformedError, 'DN string ended unexpectedly') unless [:value, :value_normal, :value_hexstring, :value_end].include? state yield key.string.strip, rstrip_except_escaped(value.string, @dn.length) @@ -290,7 +291,7 @@ module Gitlab unless identity.save Rails.logger.info "Unable to normalize \"#{identity.extern_uid}\". Skipping." end - rescue Gitlab::LDAP::MalformedDnError, Gitlab::LDAP::UnsupportedDnFormatError => e + rescue Gitlab::LDAP::DN::FormatError => e Rails.logger.info "Unable to normalize \"#{identity.extern_uid}\" due to \"#{e.message}\". Skipping." end end diff --git a/lib/gitlab/ldap/dn.rb b/lib/gitlab/ldap/dn.rb index 87a7f1c6bc0..c469420f1f9 100644 --- a/lib/gitlab/ldap/dn.rb +++ b/lib/gitlab/ldap/dn.rb @@ -21,10 +21,11 @@ # class also helps take care of that. module Gitlab module LDAP - MalformedDnError = Class.new(StandardError) - UnsupportedDnFormatError = Class.new(StandardError) - class DN + FormatError = Class.new(StandardError) + MalformedError = Class.new(FormatError) + UnsupportedError = Class.new(FormatError) + def self.normalize_value(given_value) dummy_dn = "placeholder=#{given_value}" normalized_dn = new(*dummy_dn).to_normalized_s @@ -90,19 +91,19 @@ module Gitlab state = :key_oid key << char when ' ' then state = :key - else raise(MalformedDnError, "Unrecognized first character of an RDN attribute type name \"#{char}\"") + else raise(MalformedError, "Unrecognized first character of an RDN attribute type name \"#{char}\"") end when :key_normal then case char when '=' then state = :value when 'a'..'z', 'A'..'Z', '0'..'9', '-', ' ' then key << char - else raise(MalformedDnError, "Unrecognized RDN attribute type name character \"#{char}\"") + else raise(MalformedError, "Unrecognized RDN attribute type name character \"#{char}\"") end when :key_oid then case char when '=' then state = :value when '0'..'9', '.', ' ' then key << char - else raise(MalformedDnError, "Unrecognized RDN OID attribute type name character \"#{char}\"") + else raise(MalformedError, "Unrecognized RDN OID attribute type name character \"#{char}\"") end when :value then case char @@ -129,7 +130,7 @@ module Gitlab yield key.string.strip, rstrip_except_escaped(value.string, dn_index) key = StringIO.new value = StringIO.new - when '+' then raise(UnsupportedDnFormatError, "Multivalued RDNs are not supported") + when '+' then raise(UnsupportedError, "Multivalued RDNs are not supported") else value << char end when :value_normal_escape then @@ -146,7 +147,7 @@ module Gitlab when '0'..'9', 'a'..'f', 'A'..'F' then state = :value_normal value << "#{hex_buffer}#{char}".to_i(16).chr - else raise(MalformedDnError, "Invalid escaped hex code \"\\#{hex_buffer}#{char}\"") + else raise(MalformedError, "Invalid escaped hex code \"\\#{hex_buffer}#{char}\"") end when :value_quoted then case char @@ -168,7 +169,7 @@ module Gitlab when '0'..'9', 'a'..'f', 'A'..'F' then state = :value_quoted value << "#{hex_buffer}#{char}".to_i(16).chr - else raise(MalformedDnError, "Expected the second character of a hex pair inside a double quoted value, but got \"#{char}\"") + else raise(MalformedError, "Expected the second character of a hex pair inside a double quoted value, but got \"#{char}\"") end when :value_hexstring then case char @@ -181,14 +182,14 @@ module Gitlab yield key.string.strip, rstrip_except_escaped(value.string, dn_index) key = StringIO.new value = StringIO.new - else raise(MalformedDnError, "Expected the first character of a hex pair, but got \"#{char}\"") + else raise(MalformedError, "Expected the first character of a hex pair, but got \"#{char}\"") end when :value_hexstring_hex then case char when '0'..'9', 'a'..'f', 'A'..'F' then state = :value_hexstring value << char - else raise(MalformedDnError, "Expected the second character of a hex pair, but got \"#{char}\"") + else raise(MalformedError, "Expected the second character of a hex pair, but got \"#{char}\"") end when :value_end then case char @@ -198,14 +199,14 @@ module Gitlab yield key.string.strip, rstrip_except_escaped(value.string, dn_index) key = StringIO.new value = StringIO.new - else raise(MalformedDnError, "Expected the end of an attribute value, but got \"#{char}\"") + else raise(MalformedError, "Expected the end of an attribute value, but got \"#{char}\"") end else raise "Fell out of state machine" end end # Last pair - raise(MalformedDnError, 'DN string ended unexpectedly') unless + raise(MalformedError, 'DN string ended unexpectedly') unless [:value, :value_normal, :value_hexstring, :value_end].include? state yield key.string.strip, rstrip_except_escaped(value.string, @dn.length) diff --git a/lib/gitlab/ldap/person.rb b/lib/gitlab/ldap/person.rb index e91e3a176e6..81aa352e656 100644 --- a/lib/gitlab/ldap/person.rb +++ b/lib/gitlab/ldap/person.rb @@ -42,7 +42,7 @@ module Gitlab # 2. The string is downcased (for case-insensitivity) def self.normalize_uid(uid) ::Gitlab::LDAP::DN.normalize_value(uid) - rescue ::Gitlab::LDAP::MalformedDnError, ::Gitlab::LDAP::UnsupportedDnFormatError => e + rescue ::Gitlab::LDAP::DN::FormatError => e Rails.logger.info("Returning original UID \"#{uid}\" due to error during normalization attempt: #{e.message}") Rails.logger.info(e.backtrace.join("\n")) diff --git a/spec/lib/gitlab/ldap/dn_spec.rb b/spec/lib/gitlab/ldap/dn_spec.rb index 709eadd7e38..c300f7160fe 100644 --- a/spec/lib/gitlab/ldap/dn_spec.rb +++ b/spec/lib/gitlab/ldap/dn_spec.rb @@ -12,64 +12,64 @@ describe Gitlab::LDAP::DN do context 'when ending with a comma' do let(:given) { 'John Smith,' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'DN string ended unexpectedly') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'DN string ended unexpectedly') end end context 'when given a BER encoded attribute value with a space in it' do let(:given) { '#aa aa' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, "Expected the end of an attribute value, but got \"a\"") + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, "Expected the end of an attribute value, but got \"a\"") end end context 'when given a BER encoded attribute value with a non-hex character in it' do let(:given) { '#aaXaaa' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, "Expected the first character of a hex pair, but got \"X\"") + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, "Expected the first character of a hex pair, but got \"X\"") end end context 'when given a BER encoded attribute value with a non-hex character in it' do let(:given) { '#aaaYaa' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, "Expected the second character of a hex pair, but got \"Y\"") + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, "Expected the second character of a hex pair, but got \"Y\"") end end context 'when given a hex pair with a non-hex character in it, inside double quotes' do let(:given) { '"Sebasti\\cX\\a1n"' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, "Expected the second character of a hex pair inside a double quoted value, but got \"X\"") + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, "Expected the second character of a hex pair inside a double quoted value, but got \"X\"") end end context 'with an open (as opposed to closed) double quote' do let(:given) { '"James' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'DN string ended unexpectedly') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'DN string ended unexpectedly') end end context 'with an invalid escaped hex code' do let(:given) { 'J\ames' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'Invalid escaped hex code "\am"') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'Invalid escaped hex code "\am"') end end context 'with a value ending with the escape character' do let(:given) { 'foo\\' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'DN string ended unexpectedly') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'DN string ended unexpectedly') end end end @@ -119,8 +119,8 @@ describe Gitlab::LDAP::DN do context 'without extraneous whitespace' do let(:given) { 'uid=john smith+telephonenumber=+1 555-555-5555,ou=people,dc=example,dc=com' } - it 'raises UnsupportedDnFormatError' do - expect { subject }.to raise_error(Gitlab::LDAP::UnsupportedDnFormatError) + it 'raises UnsupportedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::UnsupportedError) end end @@ -128,16 +128,16 @@ describe Gitlab::LDAP::DN do context 'around the phone number plus sign' do let(:given) { 'uid = John Smith + telephoneNumber = + 1 555-555-5555 , ou = People,dc=example,dc=com' } - it 'raises UnsupportedDnFormatError' do - expect { subject }.to raise_error(Gitlab::LDAP::UnsupportedDnFormatError) + it 'raises UnsupportedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::UnsupportedError) end end context 'not around the phone number plus sign' do let(:given) { 'uid = John Smith + telephoneNumber = +1 555-555-5555 , ou = People,dc=example,dc=com' } - it 'raises UnsupportedDnFormatError' do - expect { subject }.to raise_error(Gitlab::LDAP::UnsupportedDnFormatError) + it 'raises UnsupportedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::UnsupportedError) end end end @@ -148,104 +148,104 @@ describe Gitlab::LDAP::DN do context 'when ending with a comma' do let(:given) { 'uid=John Smith,' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'DN string ended unexpectedly') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'DN string ended unexpectedly') end end context 'when given a BER encoded attribute value with a space in it' do let(:given) { '0.9.2342.19200300.100.1.25=#aa aa' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, "Expected the end of an attribute value, but got \"a\"") + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, "Expected the end of an attribute value, but got \"a\"") end end context 'when given a BER encoded attribute value with a non-hex character in it' do let(:given) { '0.9.2342.19200300.100.1.25=#aaXaaa' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, "Expected the first character of a hex pair, but got \"X\"") + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, "Expected the first character of a hex pair, but got \"X\"") end end context 'when given a BER encoded attribute value with a non-hex character in it' do let(:given) { '0.9.2342.19200300.100.1.25=#aaaYaa' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, "Expected the second character of a hex pair, but got \"Y\"") + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, "Expected the second character of a hex pair, but got \"Y\"") end end context 'when given a hex pair with a non-hex character in it, inside double quotes' do let(:given) { 'uid="Sebasti\\cX\\a1n"' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, "Expected the second character of a hex pair inside a double quoted value, but got \"X\"") + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, "Expected the second character of a hex pair inside a double quoted value, but got \"X\"") end end context 'without a name value pair' do let(:given) { 'John' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'DN string ended unexpectedly') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'DN string ended unexpectedly') end end context 'with an open (as opposed to closed) double quote' do let(:given) { 'cn="James' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'DN string ended unexpectedly') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'DN string ended unexpectedly') end end context 'with an invalid escaped hex code' do let(:given) { 'cn=J\ames' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'Invalid escaped hex code "\am"') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'Invalid escaped hex code "\am"') end end context 'with a value ending with the escape character' do let(:given) { 'cn=\\' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'DN string ended unexpectedly') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'DN string ended unexpectedly') end end context 'with an invalid OID attribute type name' do let(:given) { '1.2.d=Value' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'Unrecognized RDN OID attribute type name character "d"') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'Unrecognized RDN OID attribute type name character "d"') end end context 'with a period in a non-OID attribute type name' do let(:given) { 'd1.2=Value' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'Unrecognized RDN attribute type name character "."') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'Unrecognized RDN attribute type name character "."') end end context 'when starting with non-space, non-alphanumeric character' do let(:given) { ' -uid=John Smith' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'Unrecognized first character of an RDN attribute type name "-"') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'Unrecognized first character of an RDN attribute type name "-"') end end context 'when given a UID with an escaped equal sign' do let(:given) { 'uid\\=john' } - it 'raises MalformedDnError' do - expect { subject }.to raise_error(Gitlab::LDAP::MalformedDnError, 'Unrecognized RDN attribute type name character "\\"') + it 'raises MalformedError' do + expect { subject }.to raise_error(Gitlab::LDAP::DN::MalformedError, 'Unrecognized RDN attribute type name character "\\"') end end end