verify_vsp_client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ee1f8e908abcdd3e2d6d0a74dce049b8ea3b8fa19671206263d6126a4220f356
4
+ data.tar.gz: 18ae2f8fa7f0ab41914cc8f3dcdc0d8a2c31b61fd3f29cf44657d5b1b4eeffaf
5
+ SHA512:
6
+ metadata.gz: d9387be5bd43a1513b69b6f38b6d78c40704eaa8c8077ad3c2aaff5ed7afef3818e6666a2324fac5f18890316959eb31c24f43f0dcd23061b5693aff24811f11
7
+ data.tar.gz: 6987744fe5f673d47d54deb1a5239fafd1c50d7597835aa7bb1e9975bbadcb02caf3682c6e76062f544e6fb8c07fe049b2046d5788e51de33bc3f73e35778cea
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ mkdir ~/.gem
5
+ echo -e "---\r\n:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials
6
+ chmod 0600 ~/.gem/credentials
@@ -0,0 +1,22 @@
1
+ name: Build
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - uses: actions/checkout@v1
12
+ - name: Set up Ruby 2.6
13
+ uses: actions/setup-ruby@v1
14
+ with:
15
+ ruby-version: 2.6.x
16
+ - name: Build and test with Rake
17
+ run: |
18
+ sudo apt-get update
19
+ sudo apt-get install sqlite3 libsqlite3-dev
20
+ gem install bundler
21
+ bundle install --jobs 4 --retry 3
22
+ bundle exec rake
@@ -0,0 +1,25 @@
1
+ name: Publish to rubygems
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "*"
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v1
13
+ - name: Set up Ruby 2.6
14
+ uses: actions/setup-ruby@v1
15
+ with:
16
+ ruby-version: 2.6.x
17
+ - name: Setup Rubygems
18
+ env:
19
+ RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
20
+ run: |
21
+ bash .github/setup-rubygems.sh
22
+ - name: Publish to Rubygems
23
+ run: |
24
+ gem build verify_vsp_client.gemspec
25
+ gem push "verify_vsp_client-$(git describe --tags).gem"
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
4
+ --order rand
@@ -0,0 +1 @@
1
+ 2.6.4
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog]
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2019-09-20
10
+
11
+ - Initial release
12
+
13
+ [unreleased]:
14
+ https://github.com/dxw/verify_vsp_client/compare/0.1.0...HEAD
15
+ [0.1.0]: https://github.com/dxw/verify_vsp_client/compare/c01154a06c06b74a0eadebca7d316155cb1fd98f...0.1.0
16
+ [keep a changelog]: https://keepachangelog.com/en/1.0.0/
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at robbie.paul@dxw.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in verify_vsp_client.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Robbie Paul
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,121 @@
1
+ [![Build status](https://github.com/dxw/verify_vsp_client/workflows/Build/badge.svg)](https://github.com/dxw/verify_vsp_client/actions)
2
+ [![License](http://img.shields.io/:license-mit-blue.svg)](https://mit-license.org/)
3
+
4
+ # Verify VSP Client
5
+
6
+ Ruby client for sending and receiving requests to a [Verify Service Provider] allowing you to
7
+ connect to [GOV.UK Verify]
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'verify_vsp_client'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Create a new `verify_vsp_client.rb` initialiser in `config/initializers`:
22
+
23
+ ```ruby
24
+ VerifyVspClient.configure do |config|
25
+ config.vsp_host = YOUR_VSP_HOST
26
+ end
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ For a more detailed explanation of how to send and receive requests to the VSP, read the [GOV.UK Verify docs](https://www.docs.verify.service.gov.uk/get-started/set-up-successful-verification-journey/)
32
+
33
+ ### Generate an authentication request
34
+
35
+ An authentication request with contain a `samlRequest`, `requestId` and `ssoLocation`.
36
+ You will need to store the `requestId` and access it later as part of translating the response:
37
+
38
+ ```ruby
39
+ def new
40
+ @verify_authentication_request = VerifyVspClient::AuthenticationRequest.generate
41
+ session[:verify_request_id] = @verify_authentication_request.request_id
42
+ end
43
+ ```
44
+
45
+ ### Send the authentication request to the VSP
46
+
47
+ Create a form that makes a POST to `ssoLocation` containing a `SAMLRequest` hidden field.
48
+ The form should look something like this:
49
+
50
+ ```erbruby
51
+ <%= form_tag @verify_authentication_request.sso_location, authenticity_token: false do %>
52
+ <h1>Continue to next step</h1>
53
+ <%= hidden_field_tag "relayState" %>
54
+ <%= hidden_field_tag "SAMLRequest", @verify_authentication_request.saml_request %>
55
+ <p>If your browser does not redirect in a few seconds, please press the "Continue" button.</p>
56
+ <%= submit_tag "Continue" %>
57
+ <% end %>
58
+
59
+ <!-- JavaScript to automatically submit the form and POST to `ssoLocation` -->
60
+ <script>
61
+ var form = document.forms[0];
62
+ form.setAttribute('style', 'display: none;');
63
+ window.setTimeout(function () { form.removeAttribute('style') }, 5000);
64
+ form.submit()
65
+ </script>
66
+ ```
67
+
68
+ ### Request to translate the SAML response
69
+
70
+ Your application will receive a POST containing a SAMLResponse. Because the POST is being sent
71
+ from an external source we'll need to skip verifying CSRF token for this action:
72
+
73
+ ```ruby
74
+ skip_before_action :verify_authenticity_token, only: [:create]
75
+
76
+ def create
77
+ @response = VerifyVspClient::Response.translate(
78
+ saml_response: params["SAMLResponse"],
79
+ request_id: session[:verify_request_id],
80
+ level_of_assurance: "LEVEL_2"
81
+ )
82
+ if @response.verified?
83
+ # The user has successfully verified their identity, you can access
84
+ # the information about the user's identity using:
85
+ @response.parameters
86
+ else
87
+ # It's important for your app to also handle the failure scenarios:
88
+ # @response.scenario == VerifyVspClient::AUTHENTICATION_FAILED_SCENARIO
89
+ # @response.scenario == VerifyVspClient::NO_AUTHENTICATION_SCENARIO
90
+ end
91
+ end
92
+ ```
93
+
94
+ ## Development
95
+
96
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
97
+ the tests. You can also run `bin/console` for an interactive prompt that will allow you to
98
+ experiment.
99
+
100
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new
101
+ version, update the version number in `version.rb`, and then run `bundle exec rake release`, which
102
+ will create a git tag for the version, push git commits and tags, and push the `.gem` file
103
+ to [rubygems.org](https://rubygems.org).
104
+
105
+ ## Contributing
106
+
107
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dxw/verify_vsp_client.
108
+ This project is intended to be a safe, welcoming space for collaboration, and contributors are
109
+ expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
110
+
111
+ ## License
112
+
113
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
114
+
115
+ ## Code of Conduct
116
+
117
+ Everyone interacting in the VerifyVspClient project’s codebases, issue trackers, chat rooms and
118
+ mailing lists is expected to follow the [code of conduct](https://github.com/dxw/verify_vsp_client/blob/master/CODE_OF_CONDUCT.md).
119
+
120
+ [Verify Service Provider]: https://github.com/alphagov/verify-service-provider
121
+ [GOV.UK Verify]: https://www.verify.service.gov.uk/
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "standard/rake"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task default: [:spec, :standard]
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "verify_vsp_client"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,28 @@
1
+ require "active_support"
2
+ require "active_support/core_ext"
3
+
4
+ require_relative "verify_vsp_client/version"
5
+ require_relative "verify_vsp_client/service_provider"
6
+ require_relative "verify_vsp_client/authentication_request"
7
+ require_relative "verify_vsp_client/redacted_response"
8
+ require_relative "verify_vsp_client/response"
9
+ require_relative "verify_vsp_client/response_error"
10
+
11
+ module VerifyVspClient
12
+ IDENTITY_VERIFIED_SCENARIO = "IDENTITY_VERIFIED".freeze
13
+ AUTHENTICATION_FAILED_SCENARIO = "AUTHENTICATION_FAILED".freeze
14
+ NO_AUTHENTICATION_SCENARIO = "NO_AUTHENTICATION".freeze
15
+
16
+ class << self
17
+ attr_accessor :configuration
18
+ end
19
+
20
+ def self.configure
21
+ self.configuration ||= Configuration.new
22
+ yield(configuration)
23
+ end
24
+
25
+ class Configuration
26
+ attr_accessor :vsp_host
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ module VerifyVspClient
2
+ # SAML Authentication Request used to start the verification user journey.
3
+ #
4
+ # Use by calling AuthenticationRequest.generate to generate a new
5
+ # authentication request via the Verify Service Provider
6
+ class AuthenticationRequest
7
+ attr_reader :saml_request, :request_id, :sso_location
8
+
9
+ def initialize(saml_request:, request_id:, sso_location:)
10
+ @saml_request = saml_request
11
+ @request_id = request_id
12
+ @sso_location = sso_location
13
+ end
14
+
15
+ def self.generate
16
+ request = VerifyVspClient::ServiceProvider.new.generate_request
17
+
18
+ new(
19
+ saml_request: request["samlRequest"],
20
+ request_id: request["requestId"],
21
+ sso_location: request["ssoLocation"]
22
+ )
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ module VerifyVspClient
2
+ # A Rack application that can be used in the test suite to simulate the GOV.UK
3
+ # Verify SSO process.
4
+ #
5
+ # The Rack app responds with a form that when submitted will POST back to
6
+ # `callback_path` with a `SAMLResponse` parameter set to
7
+ # `FakeSso::IDENTITY_VERIFIED_SAML_RESPONSE`.
8
+ class FakeSso
9
+ IDENTITY_VERIFIED_SAML_RESPONSE = "IDENTITY_VERIFIED_SAML"
10
+
11
+ def initialize(callback_path)
12
+ @callback_path = callback_path
13
+ end
14
+
15
+ def call(env)
16
+ [200, {"Content-Type" => "text/html"}, [identity_verified_form]]
17
+ end
18
+
19
+ private
20
+
21
+ def identity_verified_form
22
+ <<~HEREDOC
23
+ <html><body>
24
+ <form action="#{@callback_path}" method="POST" id="verify_auth_request">
25
+ <input type="hidden" name="SAMLResponse" value="#{IDENTITY_VERIFIED_SAML_RESPONSE}">
26
+ <input type="submit" value="Perform identity check">
27
+ </form>
28
+ </body></html>
29
+ HEREDOC
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,42 @@
1
+ module VerifyVspClient
2
+ # Used to report a response from Verify without revealing any Personally
3
+ # Identifiable Information by replacing any string "values" with the "X"
4
+ # character. For example:
5
+ #
6
+ # VerifyVspClient::RedactedResponse.new({"value" => "Secret"}).parameters
7
+ # => {"value" => "XXXXXX"}
8
+ #
9
+ class RedactedResponse
10
+ KEYS_TO_REDACT = %w[value postCode from].freeze
11
+
12
+ attr_reader :parameters
13
+
14
+ def initialize(parameters)
15
+ @parameters = redact_values(parameters.deep_dup)
16
+ end
17
+
18
+ private
19
+
20
+ def redact_values(input)
21
+ if input.is_a?(String)
22
+ redact_string(input)
23
+ else
24
+ input.tap do |hash_to_redact|
25
+ hash_to_redact.each do |key, value|
26
+ if value.is_a?(Hash)
27
+ hash_to_redact[key] = redact_values(value)
28
+ elsif value.is_a?(Array)
29
+ hash_to_redact[key].each_with_index { |nested_value, nested_key| hash_to_redact[key][nested_key] = redact_values(nested_value) }
30
+ elsif value.is_a?(String) && KEYS_TO_REDACT.include?(key)
31
+ hash_to_redact[key] = redact_string(value)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def redact_string(string)
39
+ "X" * string.length
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ module VerifyVspClient
2
+ # Represents a Response from a Verify authentication attempt.
3
+ #
4
+ # Use by calling VerifyVspClient::Response.translate to translate a SAML response using
5
+ # the Verify Service Provider, for example:
6
+ #
7
+ # VerifyVspClient::Response.translate(saml_response: "SOME SAML", request_id: "REQUEST_ID", level_of_assurance: "LEVEL_2")
8
+ #
9
+ class Response
10
+ class MissingResponseAttribute < StandardError; end
11
+ attr_reader :parameters
12
+
13
+ def initialize(parameters)
14
+ @parameters = parameters
15
+ end
16
+
17
+ def self.translate(saml_response:, request_id:, level_of_assurance:)
18
+ parameters = VerifyVspClient::ServiceProvider.new.translate_response(saml_response, request_id, level_of_assurance)
19
+ new(parameters)
20
+ end
21
+
22
+ def verified?
23
+ scenario == VerifyVspClient::IDENTITY_VERIFIED_SCENARIO
24
+ end
25
+
26
+ def scenario
27
+ @scenario ||= parameters["scenario"]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,10 @@
1
+ module VerifyVspClient
2
+ class ResponseError < StandardError
3
+ attr_reader :code
4
+
5
+ def initialize(message, code)
6
+ @code = code
7
+ super(message)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,84 @@
1
+ require "net/http"
2
+
3
+ module VerifyVspClient
4
+ # Interface for interacting with an instance of a Verify Service Provider.
5
+ #
6
+ # Make sure the VSP host is configured, for example:
7
+ #
8
+ # VerifyVspClient.configuration.vsp_host= "https://vsp.host:50300"
9
+ class ServiceProvider
10
+ def self.generate_request_url
11
+ "#{VerifyVspClient.configuration.vsp_host}/generate-request"
12
+ end
13
+
14
+ def self.translate_response_url
15
+ "#{VerifyVspClient.configuration.vsp_host}/translate-response"
16
+ end
17
+
18
+ # Makes a request to the Verify Service Provider to generate an
19
+ # authentication request, as described here:
20
+ #
21
+ # https://www.docs.verify.service.gov.uk/get-started/set-up-successful-verification-journey/#generate-an-authentication-request
22
+ #
23
+ # The authentication request is used to start the identity assurance process
24
+ # with Verify.
25
+ #
26
+ # Returns the authentication request as a Hash, for example:
27
+ #
28
+ # {
29
+ # "samlRequest" => "PD94bWwgdmVyc2lvbj0iMS4wIiBlb...",
30
+ # "requestId" => "_f43aa274-9395-45dd-aaef-25f56fe",
31
+ # "ssoLocation" => "https://compliance-tool-reference.ida.digital.cabinet-office.gov.uk/SAML2/SSO"
32
+ # }
33
+ #
34
+ # Raises VerifyVspClient::ResponseError if the VSP responds with an error response.
35
+ def generate_request
36
+ uri = URI(self.class.generate_request_url)
37
+ request = Net::HTTP::Post.new(uri, {})
38
+ request.content_type = "application/json"
39
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri_uses_ssl?(uri)) { |http| http.request(request) }
40
+
41
+ handle_response response.body
42
+ end
43
+
44
+ # Makes a request to the Verify Service Provider to translate a SAML
45
+ # response returned by Verify, as described here:
46
+ #
47
+ # https://www.docs.verify.service.gov.uk/get-started/set-up-successful-verification-journey/#request-to-translate-the-saml-response
48
+ #
49
+ # The SAML response is the payload representing the result of the Verify
50
+ # identity assurance attempt by the user.
51
+ #
52
+ # Returns the translated response as a Hash, for example:
53
+ #
54
+ # {
55
+ # "scenario" => "IDENTITY_VERIFIED",
56
+ # "pid" => "etikgj3ewowe",
57
+ # "levelOfAssurance" => "LEVEL_2",
58
+ # "attributes" => {...}
59
+ # }
60
+ #
61
+ # Raises VerifyVspClient::ResponseError if the VSP responds with an error response.
62
+ def translate_response(saml_response, request_id, level_of_assurance)
63
+ uri = URI(self.class.translate_response_url)
64
+ request = Net::HTTP::Post.new(uri)
65
+ request.body = {"samlResponse" => saml_response, "requestId" => request_id, "levelOfAssurance" => level_of_assurance}.to_json
66
+ request.content_type = "application/json"
67
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri_uses_ssl?(uri)) { |http| http.request(request) }
68
+
69
+ handle_response response.body
70
+ end
71
+
72
+ private
73
+
74
+ def handle_response(json_response)
75
+ JSON.parse(json_response).tap do |parameters|
76
+ raise ResponseError.new(parameters["message"], parameters["code"]) if parameters.key?("code")
77
+ end
78
+ end
79
+
80
+ def uri_uses_ssl?(uri)
81
+ uri.default_port == 443
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,3 @@
1
+ module VerifyVspClient
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,47 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "verify_vsp_client/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "verify_vsp_client"
7
+ spec.version = VerifyVspClient::VERSION
8
+ spec.authors = ["Robbie Paul"]
9
+ spec.email = ["robbie.paul@dxw.com"]
10
+
11
+ spec.summary = "Write a short summary, because RubyGems requires one."
12
+ spec.description = "Write a longer description or delete this line."
13
+ spec.homepage = "https://github.com/dxw"
14
+ spec.license = "MIT"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ # if spec.respond_to?(:metadata)
19
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
20
+ #
21
+ # spec.metadata["homepage_uri"] = spec.homepage
22
+ # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
23
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
24
+ # else
25
+ # raise "RubyGems 2.0 or newer is required to protect against " \
26
+ # "public gem pushes."
27
+ # end
28
+
29
+ # Specify which files should be added to the gem when it is released.
30
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
31
+ spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
32
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
+ end
34
+ spec.bindir = "exe"
35
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ["lib"]
37
+
38
+ spec.add_dependency "activesupport", ">= 5.0", "< 6.1"
39
+ spec.add_dependency "json", "~> 2.2"
40
+
41
+ spec.add_development_dependency "bundler", "~> 2.0"
42
+ spec.add_development_dependency "rake", "~> 10.0"
43
+ spec.add_development_dependency "rspec", "~> 3.0"
44
+ spec.add_development_dependency "rack-test", "~> 1.1"
45
+ spec.add_development_dependency "webmock", "~> 3.7"
46
+ spec.add_development_dependency "standard", "~> 0.1"
47
+ end
metadata ADDED
@@ -0,0 +1,184 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: verify_vsp_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Robbie Paul
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-09-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '6.1'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '5.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '6.1'
33
+ - !ruby/object:Gem::Dependency
34
+ name: json
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.2'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '2.2'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '10.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '10.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rack-test
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.1'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.1'
103
+ - !ruby/object:Gem::Dependency
104
+ name: webmock
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '3.7'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '3.7'
117
+ - !ruby/object:Gem::Dependency
118
+ name: standard
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.1'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.1'
131
+ description: Write a longer description or delete this line.
132
+ email:
133
+ - robbie.paul@dxw.com
134
+ executables: []
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - ".github/setup-rubygems.sh"
139
+ - ".github/workflows/build.yml"
140
+ - ".github/workflows/publish.yml"
141
+ - ".gitignore"
142
+ - ".rspec"
143
+ - ".ruby-version"
144
+ - CHANGELOG.md
145
+ - CODE_OF_CONDUCT.md
146
+ - Gemfile
147
+ - LICENSE.txt
148
+ - README.md
149
+ - Rakefile
150
+ - bin/console
151
+ - bin/setup
152
+ - lib/verify_vsp_client.rb
153
+ - lib/verify_vsp_client/authentication_request.rb
154
+ - lib/verify_vsp_client/fake_sso.rb
155
+ - lib/verify_vsp_client/redacted_response.rb
156
+ - lib/verify_vsp_client/response.rb
157
+ - lib/verify_vsp_client/response_error.rb
158
+ - lib/verify_vsp_client/service_provider.rb
159
+ - lib/verify_vsp_client/version.rb
160
+ - verify_vsp_client.gemspec
161
+ homepage: https://github.com/dxw
162
+ licenses:
163
+ - MIT
164
+ metadata: {}
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubygems_version: 3.0.3
181
+ signing_key:
182
+ specification_version: 4
183
+ summary: Write a short summary, because RubyGems requires one.
184
+ test_files: []