Commit 6073c81
Changed files (10)
lib
spec
saml
kit
lib/saml/kit/cli/certificate.rb
@@ -3,41 +3,21 @@ module Saml
module Cli
class Certificate < Thor
desc 'keypair', 'Create a key pair using a self signed certificate.'
- method_option :format, default: 'pem', required: false, enum: %w[pem env]
+ method_option(
+ :format,
+ default: 'pem',
+ required: false,
+ enum: %w[pem env]
+ )
method_option :passphrase, default: nil, required: false
def keypair
- passphrase = options[:passphrase]
- format = options[:format]
- generator = ::Xml::Kit::SelfSignedCertificate.new
- certificate, private_key = generator.create(passphrase: passphrase)
-
- if format == 'pem'
- say '** BEGIN PEM Format **', :green
- print certificate
- say private_key
- say '***********************', :green
- else
- say '** BEGIN ENV Format **', :green
- say 'X509_CERTIFICATE=' + certificate.inspect
- say
- say 'PRIVATE_KEY=' + private_key.inspect
- say '***********************', :green
- end
-
- say
- say 'Private Key Passphrase:', :green
- say passphrase.inspect
+ command = GenerateKeyPair.new(passphrase: passphrase, format: format)
+ command.run(self)
end
desc 'dump', 'Dump the details of a X509 Certificate.'
def dump(raw)
- certificate = ::Xml::Kit::Certificate.new(raw, use: :unknown)
- x509 = certificate.x509
- print_table [
- ['Subject', 'Issuer', 'Serial', 'Not Before', 'Not After', 'Fingerprint'],
- [x509.subject, x509.issuer, x509.serial, x509.not_before, x509.not_after, certificate.fingerprint]
- ]
- say x509.to_text, :green
+ CertificateReport.new(raw).print(self)
end
end
end
lib/saml/kit/cli/certificate_report.rb
@@ -0,0 +1,36 @@
+module Saml
+ module Kit
+ module Cli
+ class CertificateReport
+ HEADER = [
+ 'Subject', 'Issuer', 'Serial',
+ 'Not Before', 'Not After', 'Fingerprint'
+ ].freeze
+ attr_reader :certificate, :x509
+
+ def initialize(raw)
+ @certificate = ::Xml::Kit::Certificate.new(raw, use: :unknown)
+ @x509 = @certificate.x509
+ end
+
+ def print(shell)
+ shell.print_table([HEADER, body])
+ shell.say(x509.to_text, :green)
+ end
+
+ private
+
+ def fingerprint
+ certificate.fingerprint
+ end
+
+ def body
+ [
+ x509.subject, x509.issuer, x509.serial,
+ x509.not_before, x509.not_after, fingerprint
+ ]
+ end
+ end
+ end
+ end
+end
lib/saml/kit/cli/decode.rb
@@ -10,10 +10,13 @@ module Saml
say error.message, :red
end
- desc 'post saml', 'Decodes the SAMLRequest/SAMLResponse using the HTTP Post binding'
+ desc(
+ 'post saml',
+ 'Decodes the SAMLRequest/SAMLResponse using the HTTP Post binding'
+ )
method_option :export, default: nil, required: false
- def post(saml_request)
- print_report_for(post_binding.deserialize('SAMLRequest' => saml_request))
+ def post(saml)
+ print_report_for(post_binding.deserialize('SAMLRequest' => saml))
rescue StandardError => error
say error.message, :red
end
lib/saml/kit/cli/generate_key_pair.rb
@@ -0,0 +1,38 @@
+module Saml
+ module Kit
+ module Cli
+ class GenerateKeyPair
+ attr_reader :passphrase, :format
+
+ def initialize(passphrase:, format:)
+ @passphrase = passphrase
+ @format = format
+ end
+
+ def run(shell)
+ certificate, private_key = generate
+ if pem?
+ shell.say certificate
+ shell.say private_key
+ else
+ shell.say 'X509_CERTIFICATE=' + certificate.inspect
+ shell.say 'PRIVATE_KEY=' + private_key.inspect
+ end
+ shell.say 'Private Key Passphrase:', :green
+ shell.say passphrase.inspect
+ end
+
+ private
+
+ def generate
+ generator = ::Xml::Kit::SelfSignedCertificate.new
+ generator.create(passphrase: passphrase)
+ end
+
+ def pem?
+ format == 'pem'
+ end
+ end
+ end
+ end
+end
lib/saml/kit/cli/signature_report.rb
@@ -0,0 +1,55 @@
+require 'uri'
+
+module Saml
+ module Kit
+ module Cli
+ class SignatureReport
+ attr_reader :content, :format
+
+ def initialize(file, format:)
+ @format = format
+ if File.exist?(File.expand_path(file))
+ @content = IO.read(File.expand_path(file))
+ else
+ uri = URI.parse(file)
+ @content = Net::HTTP.get_response(uri).body.chomp
+ end
+ end
+
+ def print(shell)
+ shell.say to_xml(pretty: true)
+ return shell.say_status :success, "#{file} is valid", :green if valid?
+ errors.each { |error| shell.say_status(:error, error, :red) }
+ return unless full?
+ invalid_signatures.each { |x| shell.say(x.to_xml(indent: 2), :red) }
+ end
+
+ private
+
+ def document
+ @document ||= ::Xml::Kit::Document.new(content)
+ end
+
+ def to_xml
+ document.to_xml(pretty: true)
+ end
+
+ def valid?
+ document.valid?
+ end
+
+ def full?
+ format == 'full'
+ end
+
+ def errors
+ document.errors.full_messages
+ end
+
+ def invalid_signatures
+ document.send(:invalid_signatures).map(&:signature)
+ end
+ end
+ end
+ end
+end
lib/saml/kit/cli/xml_digital_signature.rb
@@ -4,41 +4,19 @@ module Saml
module Kit
module Cli
class XmlDigitalSignature < Thor
- desc 'verify file', 'Verify if the contents of a file has a valid signature.'
- method_option :format, default: 'short', required: false, enum: %w[short full]
+ desc(
+ 'verify file',
+ 'Verify if the contents of a file has a valid signature.'
+ )
+ method_option(
+ :format,
+ default: 'short',
+ required: false,
+ enum: %w[short full]
+ )
def verify(file)
- format = options[:format]
- path = File.expand_path(file)
-
- if File.exist?(path)
- path = File.expand_path(file)
- say_status :status, "Attempting to read #{path}...", :yellow
- content = IO.read(path)
- else
- uri = begin
- URI.parse(file)
- rescue StandardError
- nil
- end
- say_status :status, "Downloading from #{uri}...", :yellow
- content = Net::HTTP.get_response(uri).body.chomp
- end
- document = ::Xml::Kit::Document.new(content)
- say document.to_xml(pretty: true)
- if document.valid?
- say_status :success, "#{file} is valid", :green
- else
- document.errors.full_messages.each do |error|
- say_status :error, error, :red
- end
-
- if format == 'full'
- document.send(:invalid_signatures).each_with_index do |invalid_signature, index|
- say "Signature: #{index}"
- say invalid_signature.signature.to_xml(indent: 2), :red
- end
- end
- end
+ report = SignatureReport.new(file, format: options[:format])
+ report.print(self)
end
end
end
lib/saml/kit/cli/yaml_registry.rb
@@ -32,16 +32,13 @@ module Saml
private
def with_transaction
- if @in_transaction
- yield @items
- else
- @items.transaction do
- begin
- @in_transaction = true
- yield @items
- ensure
- @in_transaction = false
- end
+ return yield @items if @in_transaction
+ @items.transaction do
+ begin
+ @in_transaction = true
+ yield @items
+ ensure
+ @in_transaction = false
end
end
end
lib/saml/kit/cli.rb
@@ -3,9 +3,11 @@ require 'thor'
require 'yaml/store'
require 'saml/kit/cli/certificate'
+require 'saml/kit/cli/certificate_report'
require 'saml/kit/cli/decode'
require 'saml/kit/cli/metadata'
require 'saml/kit/cli/report'
+require 'saml/kit/cli/signature_report'
require 'saml/kit/cli/version'
require 'saml/kit/cli/xml_digital_signature'
require 'saml/kit/cli/yaml_registry'
spec/saml/kit/cli_spec.rb
@@ -1,9 +1,5 @@
RSpec.describe Saml::Kit::Cli do
it 'has a version number' do
- expect(Saml::Kit::Cli::VERSION).not_to be nil
- end
-
- it 'does something useful' do
- expect(false).to eq(false)
+ expect(Saml::Kit::Cli::VERSION).not_to be_nil
end
end
saml-kit-cli.gemspec
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']
- spec.required_ruby_version = '~> 2.0'
+ spec.required_ruby_version = '~> 2.2'
spec.add_dependency 'saml-kit', '1.0.12'
spec.add_dependency 'thor', '~> 0.20'