dnc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 470a323d926d5b35cf824c6984227b59413b1293
4
+ data.tar.gz: cd95e84a643c70999b4114a8a9080a8c36aa4268
5
+ SHA512:
6
+ metadata.gz: e41dda0c97dc5cd0166137cba422eb498db1a2102e8e00fe2f83a20b1d477de4742f6682bb2eb7ced9c36a55e159a21ff6b977d7885d2b517471b730b38be6ad
7
+ data.tar.gz: a11f87306b43ecb1784ffab751962ee71857e87eeb9a53d43b0993ac9ca46a5dfcaba7b0dbfa1f62954abac2a6e4d03e1b351211acb320dc2f47b61b612c414f
@@ -0,0 +1 @@
1
+ �dw8��Il?��"k����D�>ʪ��C���fT�nf_������d���t��aH��b�}��S��+O*Ʒ���\yüAy�`8�j�EW�L]M+G*����
@@ -0,0 +1 @@
1
+ �t�{P-�� L��"��^q���T�2�+��4[ �l
@@ -0,0 +1,2 @@
1
+ service_name: travis-ci
2
+ repo_token:
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
@@ -0,0 +1,8 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'dnc.gemspec'
4
+ - 'lib/dnc/version.rb'
5
+ - 'spec/**/*'
6
+ - 'vendor/cache/**/*'
7
+ - 'vendor/bundle/**/*'
8
+ - '**/gems/**/*'
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ cache: bundler
3
+
4
+ rvm:
5
+ - ruby-head
6
+ - jruby-head
7
+ - 2.1.2
8
+ - 2.1.1
9
+ - 2.0.0
10
+ - 1.9.3
11
+
12
+ script: 'bundle exec rake'
@@ -0,0 +1 @@
1
+ --markup markdown
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dnc.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Steven Haddox
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,39 @@
1
+ # Distinguished Name (DN) Converter
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'dnc'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install dnc
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'dnc'
25
+ dn_string = 'CN=Some Valid, O=DN, OU=string'
26
+ dn = DN.new(dn_string: dn_string)
27
+ # Or:
28
+ dn_string.to_dn
29
+ # And:
30
+ dn_string.to_dn.to_s
31
+ ```
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it ( https://github.com/[my-github-username]/dnc/fork )
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create a new Pull Request
@@ -0,0 +1,20 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+ require 'coveralls/rake/task'
5
+ Coveralls::RakeTask.new
6
+
7
+ task default: [:spec, :rubocop, 'coveralls:push']
8
+
9
+ desc 'Run specs'
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ desc 'Run rubocop'
13
+ task :rubocop do
14
+ RuboCop::RakeTask.new
15
+ end
16
+
17
+ desc 'Display TODOs, FIXMEs, and OPTIMIZEs'
18
+ task :notes do
19
+ system("grep -r 'OPTIMIZE:\\|FIXME:\\|TODO:' #{Dir.pwd}")
20
+ end
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dnc/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dnc"
8
+ spec.version = Dnc::VERSION
9
+ spec.authors = ["Steven Haddox"]
10
+ spec.email = ["steven@haddox.us"]
11
+ spec.summary = %q{Distinguished Name Converter}
12
+ spec.description = %q{Convert multiple X509 DN strings into a consistent(ish) format.}
13
+ spec.homepage = "https://github.com/stevenhaddox/dnc"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.required_ruby_version = '>= 1.9.3'
22
+ spec.add_dependency 'logging', '~> 1.8'
23
+
24
+ spec.add_development_dependency 'awesome_print', '~> 1.2'
25
+ spec.add_development_dependency 'bundler', '~> 1.6'
26
+ spec.add_development_dependency 'coveralls', '~> 0.7'
27
+ spec.add_development_dependency 'rack', '~> 1.5'
28
+ spec.add_development_dependency 'rack-test', '~> 0.6'
29
+ spec.add_development_dependency 'rake', '~> 10.0'
30
+ spec.add_development_dependency 'rubocop', '~> 0.27'
31
+ spec.add_development_dependency 'rspec', '~> 3.1'
32
+ spec.add_development_dependency 'simplecov', '~> 0.9'
33
+ spec.add_development_dependency 'yard', '~> 0.8'
34
+
35
+ spec.cert_chain = ['certs/stevenhaddox.pem']
36
+ spec.signing_key = File.expand_path("~/.gem/certs/gem-private_key.pem") if $0 =~ /gem\z/
37
+ end
@@ -0,0 +1,4 @@
1
+ require 'dnc/version'
2
+ require 'dnc/dn'
3
+ require 'dnc/string'
4
+ require 'dnc/array'
@@ -0,0 +1,16 @@
1
+ #
2
+ # Extend the core Array class to include `.wrap`
3
+ #
4
+ class Array
5
+
6
+ # Duplication of Ruby on Rails Array#wrap method
7
+ def self.wrap(object)
8
+ if object.nil?
9
+ []
10
+ elsif object.respond_to?(:to_ary)
11
+ object.to_ary || [object]
12
+ else
13
+ [object]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,209 @@
1
+ require 'logging'
2
+
3
+ # Custom exception for strings that can't be parsed as per RFC1779
4
+ class DnDelimiterUnparsableError < TypeError; end
5
+ # Custom exception for strings that can't be parsed as per RFC1779
6
+ class DnStringUnparsableError < TypeError; end
7
+
8
+ # Accepts various DN strings and returns a DN object
9
+ class DN
10
+ attr_accessor :original_dn, :dn_string, :delimiter,
11
+ :cn, :l, :st, :o, :ou, :c, :street, :dc
12
+
13
+ # Initialize the instance
14
+ #
15
+ # @param opts [Hash] Options hash for new DN instance attribute values
16
+ # @param opts[:dn_string] [String] The DN string you want to parse into a DN
17
+ # @param opts[:logger] User provided logger vs Rails / Logging default logger
18
+ def initialize(opts={})
19
+ @dn_string = opts[:dn_string]
20
+ @original_dn = dn_string
21
+ fail "dnc: dn_string parameter is **required**" if dn_string.nil?
22
+ @logger = opts[:logger].nil? ? logger : opts[:logger]
23
+ @delimiter = opts[:delimiter].nil? ? identify_delimiter : opts[:delimiter]
24
+ format_dn
25
+ end
26
+
27
+ # logger method to return Rails logger if defined, else logging logger
28
+ def logger
29
+ return @logger if @logger
30
+ logger = Logging.logger[self]
31
+ @logger ||= Kernel.const_defined?('Rails') ? Rails.logger : logger
32
+ end
33
+
34
+ # Split passed DN by identified delimiter
35
+ def split_by_delimiter
36
+ dn_string.split(delimiter).reject(&:empty?)
37
+ end
38
+
39
+ # Convert DN object into a string
40
+ def to_s
41
+ return_string = ""
42
+ %w(cn dc l st ou o c street).each do |string_name|
43
+ unless self.send(string_name.to_sym).nil? || self.send(string_name.to_sym).empty?
44
+ return_string += "," unless return_string.empty?
45
+ return_string += self.send("#{string_name}_string".to_sym)
46
+ end
47
+ end
48
+
49
+ return_string
50
+ end
51
+
52
+ private
53
+
54
+ # Orchestrates reformatting DN to expected element order for LDAP auth.
55
+ def format_dn
56
+ dn_string.upcase! # Upcase all DNs for consistency
57
+ format_dn_element_order unless dn_begins_properly?(dn_string)
58
+ parse_rdns_to_attrs
59
+ self
60
+ end
61
+
62
+ # Parse @dn_string RDNs and assign them to DN attributes
63
+ def parse_rdns_to_attrs
64
+ split_by_delimiter.each do |rdn|
65
+ unless rdn.include?('+')
66
+ parse_top_level_rdn(rdn)
67
+ else
68
+ parse_nested_rdn(rdn)
69
+ end
70
+ end
71
+
72
+ self
73
+ end
74
+
75
+ def parse_top_level_rdn(rdn)
76
+ rdn_array = rdn.split('=')
77
+ method = rdn_array[0].downcase.to_sym
78
+ value = rdn_array[1]
79
+ unless send(method).nil? || send(method).empty?
80
+ send("#{method}=", Array.wrap(send(method)))
81
+ send("#{method}").insert(0, value)
82
+ else
83
+ send("#{method}=", value)
84
+ end
85
+ end
86
+
87
+ def parse_nested_rdn(rdn)
88
+ rdn_keypairs = {}
89
+ rdn_array = rdn.split('+')
90
+ rdn_array.each do |string|
91
+ keypair = string.split('=')
92
+ rdn_keypairs[keypair[0].to_sym] = keypair[1]
93
+ end
94
+
95
+ send("#{rdn_keypairs.keys.first.downcase}=", rdn_keypairs)
96
+ end
97
+
98
+ # Ensure order of DN elements is proper for CAS server with ',' delimiter
99
+ def format_dn_element_order
100
+ formatted_dn = split_by_delimiter.reverse.join(delimiter)
101
+ if dn_begins_properly?(formatted_dn)
102
+ dn_string = formatted_dn
103
+
104
+ else
105
+ fail("DN invalid format for LDAP authentication, DN:\r\n#{original_dn}")
106
+ end
107
+ end
108
+
109
+ # Verify DN starts with 'CN='
110
+ def dn_begins_properly?(dn_str)
111
+ dn_str.nil? ? false : (dn_str.start_with?("CN=") || dn_str.start_with?("#{delimiter}CN="))
112
+ end
113
+
114
+ # Regex to match the DN delimiter by getting the 2nd key non-word predecessor
115
+ def delimiter_regexp
116
+ /\A.*=.*((([^\w\s\+\)\(])|([_]))\s?)\w+=.*\z/
117
+ end
118
+
119
+ # Identify and set the DN delimiter
120
+ def identify_delimiter
121
+ begin
122
+ logger.debug("DN.identify_delimeter: #{dn_string}")
123
+ delimiter_regexp.match(dn_string)[1]
124
+ rescue
125
+ fail DnDelimiterUnparsableError, "DN delimiter could not be identified
126
+ \r\nPlease ensure your string complies with RFC1779 formatting."
127
+ end
128
+ end
129
+
130
+ def cn_string
131
+ dynamic_strings('cn', cn.class)
132
+ end
133
+
134
+ def l_string
135
+ dynamic_strings('l', l.class)
136
+ end
137
+
138
+ def st_string
139
+ dynamic_strings('st', st.class)
140
+ end
141
+
142
+ def o_string
143
+ dynamic_strings('o', o.class)
144
+ end
145
+
146
+ def ou_string
147
+ dynamic_strings('ou', ou.class)
148
+ end
149
+
150
+ def c_string
151
+ dynamic_strings('c', c.class)
152
+ end
153
+
154
+ def street_string
155
+ dynamic_strings('street', street.class)
156
+ end
157
+
158
+ def dc_string
159
+ dynamic_strings('dc', dc.class)
160
+ end
161
+
162
+ # Identify which RDN string formatteer to call by value's class
163
+ def dynamic_strings(getter_method, value_class)
164
+ case value_class.to_s
165
+ when Array.to_s
166
+ dn_array_to_string(getter_method)
167
+ when Hash.to_s
168
+ dn_hash_to_string(getter_method)
169
+ when String.to_s
170
+ dn_string_to_string(getter_method)
171
+ else
172
+ logger.error "Invalid string accessor method class: #{value_class}"
173
+ fail "Invalid string accessor method class: #{value_class}"
174
+ end
175
+ end
176
+
177
+ # NOTE:
178
+ # The following methods are a code smell, they handle formatting the values
179
+ # in DN attrs and converting them into a string format based upon their class
180
+
181
+ # Dynamically define a method to return DN array values as string format
182
+ def dn_array_to_string(getter_method)
183
+ return_string = ""
184
+ value = self.send(getter_method.to_sym)
185
+ value.each do |element|
186
+ return_string += "," unless return_string.empty?
187
+ return_string += "#{getter_method.to_s.upcase}=#{element}"
188
+ end
189
+
190
+ return_string
191
+ end
192
+
193
+ # Dynamically define a method to return DN hash values as string format
194
+ def dn_hash_to_string(getter_method)
195
+ return_string = ""
196
+ value = self.send(getter_method.to_sym)
197
+ value.each do |key, string|
198
+ return_string += "+" unless return_string.empty?
199
+ return_string += "#{key}=#{string}"
200
+ end
201
+
202
+ return_string
203
+ end
204
+
205
+ # Dynamically define a method to return DN string values as string format
206
+ def dn_string_to_string(getter_method)
207
+ "#{getter_method.to_s.upcase}=#{self.send(getter_method.to_sym)}"
208
+ end
209
+ end
@@ -0,0 +1,33 @@
1
+ require 'dnc'
2
+
3
+ #
4
+ # Extend the core String class to include `.to_dn` && `.to_dn!`
5
+ #
6
+ class String
7
+
8
+ # Parses the string to return a DN object
9
+ # Returns nil if a DN instance cannot be created
10
+ def to_dn
11
+ begin
12
+ new_dn = DN.new(dn_string: self.to_s)
13
+ rescue StandardError
14
+ new_dn = nil
15
+ end
16
+
17
+ new_dn
18
+ end
19
+
20
+ # Similar to {#to_dn}, but raises an error unless the string can be
21
+ # explicitly parsed to a DN instance
22
+ def to_dn!
23
+ begin
24
+ new_dn = DN.new(dn_string: self.to_s)
25
+ rescue StandardError
26
+ raise DnStringUnparsableError,
27
+ "Could not force conversion to DN:\n#{inspect}"
28
+ end
29
+
30
+ new_dn
31
+ end
32
+ end
33
+
@@ -0,0 +1,3 @@
1
+ module Dnc
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,12 @@
1
+ /C=US/O=RB/OU=DEV/OU=RAILS/OU=People/CN=Last First (initial)%CN=LAST FIRST (INITIAL),OU=PEOPLE,OU=RAILS,OU=DEV,O=RB,C=US
2
+ /CN=Smith John+initials=cpt/OU=People/OU=RAILS/OU=DEV/O=RB/C=GB%CN=SMITH JOHN+INITIALS=CPT,OU=DEV,OU=RAILS,OU=PEOPLE,O=RB,C=GB
3
+ CN=John Smith+email=jsmith@mayflower.org,O=ISODE Consortium,C=GB,O=ISODE Consortium%CN=JOHN SMITH+EMAIL=JSMITH@MAYFLOWER.ORG,O=ISODE CONSORTIUM,C=GB,O=ISODE CONSORTIUM
4
+ /C=GB/O=RB/OU=DEV/OU=RAILS/OU=People/CN=Smith John+initials=cpt%CN=SMITH JOHN+INITIALS=CPT,OU=PEOPLE,OU=RAILS,OU=DEV,O=RB,C=GB
5
+ /C=US/O=RB/OU=DEV/OU=JS/OU=People/CN=Last First M (initial)%CN=LAST FIRST M (INITIAL),OU=PEOPLE,OU=JS,OU=DEV,O=RB,C=US
6
+ CN=Marshall T. Rose, O=Dover Beach Consulting, L=Santa Clara, ST=California, C=US%CN=MARSHALL T. ROSE,O=DOVER BEACH CONSULTING,L=SANTA CLARA,ST=CALIFORNIA,C=US
7
+ CN=FTAM Service, CN=Bells, OU=Computer Science, O=University College London, C=GB%CN=FTAM SERVICE,CN=BELLS,OU=COMPUTER SCIENCE,O=UNIVERSITY COLLEGE LONDON,C=GB
8
+ CN=Markus Kuhn, O=University of Erlangen, C=DE%CN=MARKUS KUHN,O=UNIVERSITY OF ERLANGEN,C=DE
9
+ CN=Steve Kille, O=ISODE Consortium, C=DE%CN=STEVE KILLE,O=ISODE CONSORTIUM,C=DE
10
+ CN=Steve Kille,O=ISODE Consortium,C=GB%CN=STEVE KILLE,O=ISODE CONSORTIUM,C=GB
11
+ CN=C E B\sid=ceb\foo=bar, C=GB, O=foo%CN=C E B\sid=ceb\foo=bar,C=GB,O=FOO
12
+ C=UK, ST=England, L=London, O=LShift Ltd., OU=Development, CN=Lee Coomber/UID=123456%CN=LEE COOMBER/UID=123456,OU=DEVELOPMENT,O=LSHIFT LTD.,L=LONDON,ST=ENGLAND,C=UK
@@ -0,0 +1,73 @@
1
+ require "spec_helper"
2
+
3
+ describe DN do
4
+ let!(:raw_dn) { '/C=US/O=RB/OU=DEV/OU=JS/OU=People/CN=Last First M (initial)' }
5
+ let!(:dn_to_s) { 'CN=LAST FIRST M (INITIAL),OU=PEOPLE,OU=JS,OU=DEV,O=RB,C=US' }
6
+ let(:valid_subject) { DN.new(dn_string: raw_dn) }
7
+ let(:dn_elements) { ["C=US", "O=RB", "OU=DEV", "OU=JS", "OU=PEOPLE", "CN=LAST FIRST M (INITIAL)"] }
8
+
9
+ #
10
+ # Unit specs
11
+ #
12
+ describe "#new" do
13
+ it "should create a new DN object when valid" do
14
+ expect(valid_subject.class.to_s).to eq(DN.to_s)
15
+ end
16
+
17
+ it "should identify the most likely delimiter" do
18
+ expect(valid_subject.delimiter).to eq('/')
19
+ %w(, ; - _ : \\ % ^ ! & * @ # $).each do |delim|
20
+ custom_delim_subject = DN.new(dn_string: raw_dn.gsub('/',delim))
21
+ expect(custom_delim_subject.delimiter).to eq(delim)
22
+ end
23
+ end
24
+
25
+ it "should split on identified delimiter" do
26
+ expect(valid_subject.split_by_delimiter).to eq(dn_elements)
27
+ end
28
+
29
+ it "should parse each key value pair and assign an attribute" do
30
+ expect(valid_subject.c).to eq('US')
31
+ expect(valid_subject.o).to eq('RB')
32
+ end
33
+
34
+ it "should return appropriate attrs as arrays" do
35
+ [:ou, :dc].each do |array_wrapped_el|
36
+ dn = DN.new(dn_string: '/C=US/O=RB/OU=DEV/OU=JS/OU=People/DC=example/DC=org/CN=Last First M (initial)')
37
+ expect(dn.dc).to eq(['ORG', 'EXAMPLE'])
38
+ expect(dn.ou).to eq(['PEOPLE', 'JS', 'DEV'])
39
+ end
40
+ end
41
+
42
+ it "should handle multiple RDN key value pairs in the CN and return an array of elements" do
43
+ dn = DN.new(dn_string: '/C=US/O=RB/OU=DEV/OU=JS/OU=People/DC=example/DC=org/CN=Last First M (initial)+email=initial@example.org+office=home')
44
+ expect(dn.cn).to eq({CN: 'LAST FIRST M (INITIAL)', EMAIL: 'INITIAL@EXAMPLE.ORG', OFFICE: 'HOME'})
45
+ end
46
+ end
47
+
48
+ describe "validations" do
49
+ it "should require a parsable DN string" do
50
+ expect{ DN.new(dn_string: "") }.to raise_error(DnDelimiterUnparsableError)
51
+ expect{ DN.new(dn_string: "nope") }.to raise_error(DnDelimiterUnparsableError)
52
+ end
53
+ end
54
+
55
+ describe ".to_s" do
56
+ it "should return a properly formatted string for CAS & RFC1779 use" do
57
+ dn = DN.new(dn_string: '/C=US/O=RB/OU=DEV/OU=JS/OU=People/DC=example/DC=org/CN=Last First M (initial)+email=initial@example.org+office=home')
58
+ dn_string = 'CN=LAST FIRST M (INITIAL)+EMAIL=INITIAL@EXAMPLE.ORG+OFFICE=HOME,DC=ORG,DC=EXAMPLE,OU=PEOPLE,OU=JS,OU=DEV,O=RB,C=US'
59
+ expect(dn.to_s).to eq(dn_string)
60
+ end
61
+
62
+ it "should parse common DN formats into DN objects" do
63
+ pending "Finish this"
64
+ File.readlines('spec/fixtures/common_dns.txt').each do |line|
65
+ dn_in = line.rstrip.split('%')[0]
66
+ dn_out = line.rstrip.split('%')[1]
67
+ #ap dn_in
68
+ #ap dn_out
69
+ expect(DN.new(dn_string: dn_in).to_s).to eq(dn_out)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+ let!(:raw_dn) { '/DC=org/DC=ruby-lang/CN=Ruby certificate rbcert' }
5
+ let(:dn) {
6
+ DN.new({
7
+ dn_string: raw_dn,
8
+ })
9
+ }
10
+ let(:dn_to_s) { 'CN=RUBY CERTIFICATE RBCERT,DC=RUBY-LANG,DC=ORG' }
11
+
12
+ after :all do
13
+ #expect(@log_output.readline).to eq("DEBUG String: DNC raw_dn:\n")
14
+ end
15
+
16
+ describe ".to_dn" do
17
+ it "should return a DN instance if the string can be parsed" do
18
+ expect(raw_dn.to_dn.class.to_s).to eq('DN')
19
+ expect(raw_dn.to_dn.to_yaml).to eq(dn.to_yaml)
20
+ end
21
+
22
+ it "should return nil otherwise" do
23
+ expect("".to_dn).to eql(nil)
24
+ expect("nope".to_dn).to eql(nil)
25
+ end
26
+ end
27
+
28
+ describe ".to_dn!" do
29
+ it "should return a DN instance if the string can be parsed" do
30
+ expect(raw_dn.to_dn!.class.to_s).to eq('DN')
31
+ expect(raw_dn.to_dn!.to_yaml).to eq(dn.to_yaml)
32
+ end
33
+
34
+ it "should raise a DnStringUnparsableError otherwise" do
35
+ expect{ "".to_dn! }.to raise_error(DnStringUnparsableError)
36
+ expect{ "nope".to_dn! }.to raise_error(DnStringUnparsableError)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
4
+ SimpleCov.start do
5
+ add_filter '/spec/'
6
+ end
7
+ # SimpleCov always comes before **anything** else
8
+
9
+ require_relative '../lib/dnc'
10
+ require 'awesome_print'
11
+ #require 'rspec/logging_helper'
12
+
13
+ RSpec.configure do |config|
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+ config.filter_run_excluding :skip
17
+ config.order = 'random'
18
+
19
+ # Configure RSpec to capture log messages for each test. The output from the
20
+ # logs will be stored in the @log_output variable. It is a StringIO instance.
21
+ # include RSpec::LoggingHelper
22
+ # config.capture_log_messages
23
+ end
metadata ADDED
@@ -0,0 +1,244 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dnc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Steven Haddox
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDhTCCAm2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMRYwFAYDVQQDDA1zdGV2
14
+ ZW4uaGFkZG94MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
15
+ FgNjb20wHhcNMTQxMTE4MDIxMzIwWhcNMTUxMTE4MDIxMzIwWjBEMRYwFAYDVQQD
16
+ DA1zdGV2ZW4uaGFkZG94MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJ
17
+ k/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDanmKr
18
+ vJDcVGMeDbDouLfKvU5ugOcHTXP04QDYSshaMTeuWSm4OXakxk2rxnR7Laq86R+8
19
+ h1NbHMdiZdwlHcpZm9/YD6qjbQhnLNGsezMrNpfZwfy9VnUQY4e0OCAca9vQXKTL
20
+ qC4fiuRD6sQQpyXkiIno0KlJOA4sKtH8vFucPGmhO0FUdlQY5FarDvCvZrtteO6L
21
+ 6/GQFjupFBd9X6zt1XBs28IC+YUw33SN0UJ5JHB45ig0BmeWMXdd4SKWe4ve/2UY
22
+ asgs2miI3HP0wCPs0EF64/8LbuEUyMjHDr3a7+7KIRxYn2H/yUH5Ndqz6yL5G0sf
23
+ jUsC32JuE7VlJwFNAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAd
24
+ BgNVHQ4EFgQUC8HywyOMPJFCsH7uGW+CeKcZ8+8wIgYDVR0RBBswGYEXc3RldmVu
25
+ LmhhZGRveEBnbWFpbC5jb20wIgYDVR0SBBswGYEXc3RldmVuLmhhZGRveEBnbWFp
26
+ bC5jb20wDQYJKoZIhvcNAQEFBQADggEBAFoac9ZKc20ZXw2R2mWUz7FaJJdUvb7o
27
+ 4rKVzFQkJwvAX+NEdP32yCDViGoEqlA13el5fllllmG3E7Qrw+0JA5B3wrZbVfQA
28
+ v4eX0ZohhW3CXLSz65pd3zfrwPAw0pXs1QKP+IioTuLQoBsGUiIqCPulZvzn/xN2
29
+ KG7SexyfUEXyJRMMigA/mE8h6bYfgKKUmLQVs1uRaXmOI7dKUF6HZJpda51zJH3v
30
+ 42qdwEXvvkODZAD6KAIXPdmbMfBgPbcd+B/4eUA0PyKo+4dgL1NuqX4MPWToevIZ
31
+ O8EKLF2X7NmC6FY1bOsSj/J8r1SOkx0rxgF+geRvY1P+hfNjDfxTsjU=
32
+ -----END CERTIFICATE-----
33
+ date: 2015-01-13 00:00:00.000000000 Z
34
+ dependencies:
35
+ - !ruby/object:Gem::Dependency
36
+ name: logging
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.8'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.8'
49
+ - !ruby/object:Gem::Dependency
50
+ name: awesome_print
51
+ requirement: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.2'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '1.2'
63
+ - !ruby/object:Gem::Dependency
64
+ name: bundler
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.6'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.6'
77
+ - !ruby/object:Gem::Dependency
78
+ name: coveralls
79
+ requirement: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.7'
84
+ type: :development
85
+ prerelease: false
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0.7'
91
+ - !ruby/object:Gem::Dependency
92
+ name: rack
93
+ requirement: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.5'
98
+ type: :development
99
+ prerelease: false
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '1.5'
105
+ - !ruby/object:Gem::Dependency
106
+ name: rack-test
107
+ requirement: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '0.6'
112
+ type: :development
113
+ prerelease: false
114
+ version_requirements: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '0.6'
119
+ - !ruby/object:Gem::Dependency
120
+ name: rake
121
+ requirement: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '10.0'
126
+ type: :development
127
+ prerelease: false
128
+ version_requirements: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '10.0'
133
+ - !ruby/object:Gem::Dependency
134
+ name: rubocop
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.27'
140
+ type: :development
141
+ prerelease: false
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '0.27'
147
+ - !ruby/object:Gem::Dependency
148
+ name: rspec
149
+ requirement: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '3.1'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - "~>"
159
+ - !ruby/object:Gem::Version
160
+ version: '3.1'
161
+ - !ruby/object:Gem::Dependency
162
+ name: simplecov
163
+ requirement: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - "~>"
166
+ - !ruby/object:Gem::Version
167
+ version: '0.9'
168
+ type: :development
169
+ prerelease: false
170
+ version_requirements: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - "~>"
173
+ - !ruby/object:Gem::Version
174
+ version: '0.9'
175
+ - !ruby/object:Gem::Dependency
176
+ name: yard
177
+ requirement: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - "~>"
180
+ - !ruby/object:Gem::Version
181
+ version: '0.8'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - "~>"
187
+ - !ruby/object:Gem::Version
188
+ version: '0.8'
189
+ description: Convert multiple X509 DN strings into a consistent(ish) format.
190
+ email:
191
+ - steven@haddox.us
192
+ executables: []
193
+ extensions: []
194
+ extra_rdoc_files: []
195
+ files:
196
+ - ".coveralls.yml"
197
+ - ".gitignore"
198
+ - ".rubocop.yml"
199
+ - ".travis.yml"
200
+ - ".yardopts"
201
+ - Gemfile
202
+ - LICENSE.txt
203
+ - README.md
204
+ - Rakefile
205
+ - dnc.gemspec
206
+ - lib/dnc.rb
207
+ - lib/dnc/array.rb
208
+ - lib/dnc/dn.rb
209
+ - lib/dnc/string.rb
210
+ - lib/dnc/version.rb
211
+ - spec/fixtures/common_dns.txt
212
+ - spec/lib/dn_spec.rb
213
+ - spec/lib/string_spec.rb
214
+ - spec/spec_helper.rb
215
+ homepage: https://github.com/stevenhaddox/dnc
216
+ licenses:
217
+ - MIT
218
+ metadata: {}
219
+ post_install_message:
220
+ rdoc_options: []
221
+ require_paths:
222
+ - lib
223
+ required_ruby_version: !ruby/object:Gem::Requirement
224
+ requirements:
225
+ - - ">="
226
+ - !ruby/object:Gem::Version
227
+ version: 1.9.3
228
+ required_rubygems_version: !ruby/object:Gem::Requirement
229
+ requirements:
230
+ - - ">="
231
+ - !ruby/object:Gem::Version
232
+ version: '0'
233
+ requirements: []
234
+ rubyforge_project:
235
+ rubygems_version: 2.4.4
236
+ signing_key:
237
+ specification_version: 4
238
+ summary: Distinguished Name Converter
239
+ test_files:
240
+ - spec/fixtures/common_dns.txt
241
+ - spec/lib/dn_spec.rb
242
+ - spec/lib/string_spec.rb
243
+ - spec/spec_helper.rb
244
+ has_rdoc:
Binary file