saml-kit-cli 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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