saml-kit-cli 0.3.6 → 0.3.7

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,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saml
4
+ module Kit
5
+ module Cli
6
+ class SignatureReport
7
+ attr_reader :content, :format, :path
8
+
9
+ def initialize(path, format:)
10
+ @format = format
11
+ @path = path
12
+ if File.exist?(File.expand_path(path))
13
+ @content = IO.read(File.expand_path(path))
14
+ else
15
+ uri = URI.parse(path)
16
+ @content = Net::HTTP.get_response(uri).body.chomp
17
+ end
18
+ end
19
+
20
+ def print(shell)
21
+ shell.say to_xml
22
+ return shell.say_status :success, "#{path} is valid", :green if valid?
23
+ errors.each { |error| shell.say_status(:error, error, :red) }
24
+ return unless full?
25
+ invalid_signatures.each { |x| shell.say(x.to_xml(indent: 2), :red) }
26
+ end
27
+
28
+ private
29
+
30
+ def document
31
+ @document ||= ::Xml::Kit::Document.new(content)
32
+ end
33
+
34
+ def to_xml
35
+ document.to_xml(pretty: true)
36
+ end
37
+
38
+ def valid?
39
+ document.valid?
40
+ end
41
+
42
+ def full?
43
+ format == 'full'
44
+ end
45
+
46
+ def errors
47
+ document.errors.full_messages
48
+ end
49
+
50
+ def invalid_signatures
51
+ document.send(:invalid_signatures).map(&:signature)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Saml
2
4
  module Kit
3
5
  module Cli
4
- VERSION = "0.3.6"
6
+ VERSION = '0.3.7'.freeze
5
7
  end
6
8
  end
7
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Saml
2
4
  module Kit
3
5
  module Cli
@@ -32,16 +34,13 @@ module Saml
32
34
  private
33
35
 
34
36
  def with_transaction
35
- if @in_transaction
36
- yield @items
37
- else
38
- @items.transaction do
39
- begin
40
- @in_transaction = true
41
- yield @items
42
- ensure
43
- @in_transaction = false
44
- end
37
+ return yield @items if @in_transaction
38
+ @items.transaction do
39
+ begin
40
+ @in_transaction = true
41
+ yield @items
42
+ ensure
43
+ @in_transaction = false
45
44
  end
46
45
  end
47
46
  end
data/lib/saml/kit/cli.rb CHANGED
@@ -1,30 +1,47 @@
1
- require "saml/kit"
2
- require "thor"
3
- require "yaml/store"
4
-
5
- require "saml/kit/cli/certificate"
6
- require "saml/kit/cli/decode"
7
- require "saml/kit/cli/metadata"
8
- require "saml/kit/cli/report"
9
- require "saml/kit/cli/version"
10
- require "saml/kit/cli/xml_digital_signature"
11
- require "saml/kit/cli/yaml_registry"
1
+ # frozen_string_literal: true
2
+
3
+ require 'saml/kit'
4
+ require 'thor'
5
+ require 'yaml/store'
6
+ require 'uri'
7
+
8
+ require 'saml/kit/core_ext/assertion'
9
+ require 'saml/kit/core_ext/authentication_request'
10
+ require 'saml/kit/core_ext/document'
11
+ require 'saml/kit/core_ext/document'
12
+ require 'saml/kit/core_ext/logout_request'
13
+ require 'saml/kit/core_ext/metadata'
14
+ require 'saml/kit/core_ext/response'
15
+ require 'saml/kit/core_ext/signature'
16
+
17
+ require 'saml/kit/cli/certificate_report'
18
+ require 'saml/kit/cli/commands'
19
+ require 'saml/kit/cli/generate_key_pair'
20
+ require 'saml/kit/cli/report'
21
+ require 'saml/kit/cli/signature_report'
22
+ require 'saml/kit/cli/version'
23
+ require 'saml/kit/cli/yaml_registry'
12
24
 
13
25
  module Saml
14
26
  module Kit
15
27
  module Cli
16
28
  class Application < Thor
17
- desc "decode SUBCOMMAND ...ARGS", "decode SAMLRequest/SAMLResponse."
18
- subcommand "decode", Decode
29
+ desc 'decode SUBCOMMAND ...ARGS', 'decode SAMLRequest/SAMLResponse.'
30
+ subcommand 'decode', Commands::Decode
31
+
32
+ desc 'certificate SUBCOMMAND ...ARGS', 'Work with SAML Certificates.'
33
+ subcommand 'certificate', Commands::Certificate
19
34
 
20
- desc "certificate SUBCOMMAND ...ARGS", "Work with SAML Certificates."
21
- subcommand "certificate", Certificate
35
+ desc 'metadata SUBCOMMAND ...ARGS', 'Work with SAML Metadata.'
36
+ subcommand 'metadata', Commands::Metadata
22
37
 
23
- desc "metadata SUBCOMMAND ...ARGS", "Work with SAML Metadata."
24
- subcommand "metadata", Metadata
38
+ desc 'xmldsig SUBCOMMAND ...ARGS', 'Check XML digital signatures.'
39
+ subcommand 'xmldsig', Commands::XmlDigitalSignature
25
40
 
26
- desc "xmldsig SUBCOMMAND ...ARGS", "Check XML digital signatures."
27
- subcommand "xmldsig", XmlDigitalSignature
41
+ desc 'version', 'Display the current version'
42
+ def version
43
+ say Saml::Kit::Cli::VERSION
44
+ end
28
45
  end
29
46
  end
30
47
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saml
4
+ module Kit
5
+ class Assertion
6
+ TABLE = {
7
+ 'Assertion Present?' => ->(x) { x.present? },
8
+ 'Issuer' => ->(x) { x.issuer },
9
+ 'Name Id' => ->(x) { x.name_id },
10
+ 'Attributes' => ->(x) { x.attributes.inspect },
11
+ 'Not Before' => ->(x) { x.started_at },
12
+ 'Not After' => ->(x) { x.expired_at },
13
+ 'Audiences' => ->(x) { x.audiences.inspect },
14
+ 'Encrypted?' => ->(x) { x.encrypted? },
15
+ 'Decryptable' => ->(x) { x.decryptable? },
16
+ }.freeze
17
+
18
+ def build_table(table = [])
19
+ TABLE.each do |key, callable|
20
+ table.push([key, callable.call(self)])
21
+ end
22
+ signature.build_table(table)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saml
4
+ module Kit
5
+ class AuthenticationRequest
6
+ def build_table(table = [])
7
+ super(table)
8
+ table.push(['ACS', assertion_consumer_service_url])
9
+ table.push(['Name Id Format', name_id_format])
10
+ table
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saml
4
+ module Kit
5
+ class Document
6
+ TABLE = {
7
+ 'ID' => ->(x) { x.id },
8
+ 'Issuer' => ->(x) { x.issuer },
9
+ 'Version' => ->(x) { x.version },
10
+ 'Issue Instant' => ->(x) { x.issue_instant.iso8601 },
11
+ 'Type' => ->(x) { x.name },
12
+ 'Valid' => ->(x) { x.valid? },
13
+ 'Signed?' => ->(x) { x.signed? },
14
+ 'Trusted?' => ->(x) { x.trusted? },
15
+ }.freeze
16
+
17
+ def build_table(table = [])
18
+ TABLE.each do |key, callable|
19
+ table.push([key, callable.call(self)])
20
+ end
21
+ signature.build_table(table)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saml
4
+ module Kit
5
+ class LogoutRequest
6
+ def build_table(table = [])
7
+ super(table)
8
+ table.push(['Name Id', name_id])
9
+ table
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saml
4
+ module Kit
5
+ class Metadata
6
+ TABLE = {
7
+ 'Entity Id' => ->(x) { x.entity_id },
8
+ 'Type' => ->(x) { x.name },
9
+ 'Valid' => ->(x) { x.valid? },
10
+ 'Name Id Formats' => ->(x) { x.name_id_formats.inspect },
11
+ 'Organization' => ->(x) { x.organization_name },
12
+ 'Url' => ->(x) { x.organization_url },
13
+ 'Contact' => ->(x) { x.contact_person_company },
14
+ }.freeze
15
+
16
+ SERVICES = %w[
17
+ SingleSignOnService
18
+ SingleLogoutService
19
+ AssertionConsumerService
20
+ ].freeze
21
+
22
+ def build_table(table = [])
23
+ TABLE.each { |key, callable| table.push([key, callable.call(self)]) }
24
+ build_services_table(table)
25
+ certificates.each do |certificate|
26
+ table.push(['', certificate.x509.to_text])
27
+ end
28
+ signature.build_table(table)
29
+ end
30
+
31
+ def build_services_table(table)
32
+ SERVICES.each do |type|
33
+ services(type).each do |service|
34
+ table.push([type, [service.location, service.binding]])
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saml
4
+ module Kit
5
+ class Response
6
+ def build_table(table = [])
7
+ super(table)
8
+ assertion.build_table(table) if assertion.present?
9
+ table
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saml
4
+ module Kit
5
+ class Signature
6
+ TABLE = {
7
+ 'Digest Value' => ->(x) { x.digest_value },
8
+ 'Expected Digest Value' => ->(x) { x.expected_digest_value },
9
+ 'Digest Method' => ->(x) { x.digest_method },
10
+ 'Signature Value' => ->(x) { x.truncate(x.signature_value) },
11
+ 'Signature Method' => ->(x) { x.signature_method },
12
+ 'Canonicalization Method' => ->(x) { x.canonicalization_method },
13
+ }.freeze
14
+
15
+ def build_table(table = [])
16
+ return table unless present?
17
+ TABLE.each do |key, callable|
18
+ table.push([key, callable.call(self)])
19
+ end
20
+ table.push(['', certificate.x509.to_text])
21
+ end
22
+
23
+ def truncate(text, max: 50)
24
+ text.length >= max ? "#{text[0..max]}..." : text
25
+ end
26
+ end
27
+ end
28
+ end
data/saml-kit-cli.gemspec CHANGED
@@ -1,30 +1,35 @@
1
- lib = File.expand_path("../lib", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "saml/kit/cli/version"
5
+ require 'saml/kit/cli/version'
4
6
 
5
7
  Gem::Specification.new do |spec|
6
- spec.name = "saml-kit-cli"
8
+ spec.name = 'saml-kit-cli'
7
9
  spec.version = Saml::Kit::Cli::VERSION
8
- spec.authors = ["mo khan"]
9
- spec.email = ["mo@mokhan.ca"]
10
+ spec.authors = ['mo khan']
11
+ spec.email = ['mo@mokhan.ca']
10
12
 
11
- spec.summary = %q{A command line interface for saml-kit.}
12
- spec.description = %q{A command line interface for saml-kit.}
13
- spec.homepage = "http://www.mokhan.ca/"
14
- spec.license = "MIT"
13
+ spec.summary = 'A command line interface for saml-kit.'
14
+ spec.description = 'A command line interface for saml-kit.'
15
+ spec.homepage = 'https://www.mokhan.ca/'
16
+ spec.license = 'MIT'
15
17
 
16
18
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
19
  f.match(%r{^(test|spec|features)/})
18
20
  end
19
- spec.bindir = "exe"
21
+ spec.bindir = 'exe'
20
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
23
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
- spec.require_paths = ["lib"]
23
- spec.required_ruby_version = "~> 2.0"
24
+ spec.require_paths = ['lib']
25
+ spec.required_ruby_version = '~> 2.2'
24
26
 
25
- spec.add_dependency "saml-kit", "1.0.9"
26
- spec.add_dependency "thor", "~> 0.20"
27
- spec.add_development_dependency "bundler", "~> 1.16"
28
- spec.add_development_dependency "rake", "~> 10.0"
29
- spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_dependency 'saml-kit', '1.0.14'
28
+ spec.add_dependency 'thor', '~> 0.20'
29
+ spec.add_development_dependency 'bundler', '~> 1.16'
30
+ spec.add_development_dependency 'bundler-audit', '~> 0.6'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'rspec', '~> 3.0'
33
+ spec.add_development_dependency 'rubocop', '~> 0.52'
34
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.22'
30
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saml-kit-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - mo khan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-02-18 00:00:00.000000000 Z
11
+ date: 2018-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: saml-kit
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.9
19
+ version: 1.0.14
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 1.0.9
26
+ version: 1.0.14
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: thor
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.16'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler-audit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.6'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,34 @@ dependencies:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.52'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.52'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.22'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.22'
83
125
  description: A command line interface for saml-kit.
84
126
  email:
85
127
  - mo@mokhan.ca
@@ -89,25 +131,41 @@ extensions: []
89
131
  extra_rdoc_files: []
90
132
  files:
91
133
  - ".gitignore"
134
+ - ".gitlab-ci.yml"
92
135
  - ".rspec"
136
+ - ".rubocop.yml"
93
137
  - ".travis.yml"
94
138
  - Gemfile
95
139
  - LICENSE.txt
96
140
  - README.md
97
141
  - Rakefile
142
+ - bin/cibuild
98
143
  - bin/console
144
+ - bin/lint
99
145
  - bin/setup
146
+ - bin/test
100
147
  - exe/saml-kit
101
148
  - lib/saml/kit/cli.rb
102
- - lib/saml/kit/cli/certificate.rb
103
- - lib/saml/kit/cli/decode.rb
104
- - lib/saml/kit/cli/metadata.rb
149
+ - lib/saml/kit/cli/certificate_report.rb
150
+ - lib/saml/kit/cli/commands.rb
151
+ - lib/saml/kit/cli/commands/certificate.rb
152
+ - lib/saml/kit/cli/commands/decode.rb
153
+ - lib/saml/kit/cli/commands/metadata.rb
154
+ - lib/saml/kit/cli/commands/xml_digital_signature.rb
155
+ - lib/saml/kit/cli/generate_key_pair.rb
105
156
  - lib/saml/kit/cli/report.rb
157
+ - lib/saml/kit/cli/signature_report.rb
106
158
  - lib/saml/kit/cli/version.rb
107
- - lib/saml/kit/cli/xml_digital_signature.rb
108
159
  - lib/saml/kit/cli/yaml_registry.rb
160
+ - lib/saml/kit/core_ext/assertion.rb
161
+ - lib/saml/kit/core_ext/authentication_request.rb
162
+ - lib/saml/kit/core_ext/document.rb
163
+ - lib/saml/kit/core_ext/logout_request.rb
164
+ - lib/saml/kit/core_ext/metadata.rb
165
+ - lib/saml/kit/core_ext/response.rb
166
+ - lib/saml/kit/core_ext/signature.rb
109
167
  - saml-kit-cli.gemspec
110
- homepage: http://www.mokhan.ca/
168
+ homepage: https://www.mokhan.ca/
111
169
  licenses:
112
170
  - MIT
113
171
  metadata: {}
@@ -119,7 +177,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
177
  requirements:
120
178
  - - "~>"
121
179
  - !ruby/object:Gem::Version
122
- version: '2.0'
180
+ version: '2.2'
123
181
  required_rubygems_version: !ruby/object:Gem::Requirement
124
182
  requirements:
125
183
  - - ">="
@@ -127,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
185
  version: '0'
128
186
  requirements: []
129
187
  rubyforge_project:
130
- rubygems_version: 2.7.5
188
+ rubygems_version: 2.7.6
131
189
  signing_key:
132
190
  specification_version: 4
133
191
  summary: A command line interface for saml-kit.
@@ -1,45 +0,0 @@
1
- module Saml
2
- module Kit
3
- module Cli
4
- class Certificate < Thor
5
- desc "keypair", "Create a key pair using a self signed certificate."
6
- method_option :format, default: "pem", required: false, enum: ["pem", "env"]
7
- method_option :passphrase, default: nil, required: false
8
- def keypair
9
- passphrase = options[:passphrase]
10
- format = options[:format]
11
- generator = ::Xml::Kit::SelfSignedCertificate.new
12
- certificate, private_key = generator.create(passphrase: passphrase)
13
-
14
- if "pem" == format
15
- say "** BEGIN PEM Format **", :green
16
- print certificate
17
- say private_key
18
- say "***********************", :green
19
- else
20
- say "** BEGIN ENV Format **", :green
21
- say "X509_CERTIFICATE=" + certificate.inspect
22
- say
23
- say "PRIVATE_KEY=" + private_key.inspect
24
- say "***********************", :green
25
- end
26
-
27
- say
28
- say "Private Key Passphrase:", :green
29
- say passphrase.inspect
30
- end
31
-
32
- desc "dump", "Dump the details of a X509 Certificate."
33
- def dump(raw)
34
- certificate = ::Xml::Kit::Certificate.new(raw, use: :unknown)
35
- x509 = certificate.x509
36
- print_table [
37
- ["Subject", "Issuer", "Serial", "Not Before", "Not After", "Fingerprint"],
38
- [x509.subject, x509.issuer, x509.serial, x509.not_before, x509.not_after, certificate.fingerprint]
39
- ]
40
- say x509.to_text, :green
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,44 +0,0 @@
1
- module Saml
2
- module Kit
3
- module Cli
4
- class Decode < Thor
5
- desc "redirect uri", "Decodes the uri using the HTTP Redirect binding"
6
- def redirect(uri)
7
- print_report_for(redirect_binding.deserialize(uri))
8
- rescue StandardError => error
9
- say error.message, :red
10
- end
11
-
12
- desc "post saml", "Decodes the SAMLRequest/SAMLResponse using the HTTP Post binding"
13
- def post(saml_request)
14
- print_report_for(post_binding.deserialize('SAMLRequest' => saml_request))
15
- rescue StandardError => error
16
- say error.message, :red
17
- end
18
-
19
- desc "raw <file>", "Decode the contents of a decoded file"
20
- def raw(file)
21
- content = IO.read(File.expand_path(file))
22
- print_report_for(Document.to_saml_document(content))
23
- rescue StandardError => error
24
- say error.message, :red
25
- end
26
-
27
- private
28
-
29
- def print_report_for(document)
30
- 2.times { say "" }
31
- Report.new(document).print(self)
32
- end
33
-
34
- def post_binding(location = '')
35
- Saml::Kit::Bindings::HttpPost.new(location: location)
36
- end
37
-
38
- def redirect_binding(location = '')
39
- Saml::Kit::Bindings::HttpRedirect.new(location: location)
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,35 +0,0 @@
1
- module Saml
2
- module Kit
3
- module Cli
4
- class Metadata < Thor
5
- desc "register url", "Registers the Metadata from the remote url."
6
- def register(url)
7
- say registry.register_url(url).to_xml(pretty: true), :green
8
- end
9
-
10
- desc "list", "List each of the registered entityId's"
11
- def list
12
- registry.each do |x|
13
- say x.entity_id, :green
14
- end
15
- end
16
-
17
- desc "show entity_id", "show the metadata associated with an entityId"
18
- def show(entity_id)
19
- metadata = registry.metadata_for(entity_id)
20
- if metadata
21
- Report.new(metadata).print(self)
22
- else
23
- say "`#{entity_id}` is not registered", :red
24
- end
25
- end
26
-
27
- private
28
-
29
- def registry
30
- Saml::Kit.registry
31
- end
32
- end
33
- end
34
- end
35
- end