IntegrationPal

This engine is meant to contain the elements of big_sis that can be shared across sis integrations such as

  • access token
  • job starting
  • job monitoring
  • error capturing
  • Okta SAML2 authentication

Usage

1) Create an active job bin/rails generate job example_job

Installation

  1. Add integration_pal to your application's Gemfile:

    gem 'integration_pal'
    

    And install the bundle:

    $ bundle install
    

    Or install the Gem manually:

    $ gem install integration_pal
    
  2. Define Environment variables

    ENCRYPTION_KEY=... # must be 32 chars
    SALT_KEY=... # must be 32 chars
    
    OKTA_APP=okta_app_key
    OKTA_ID=xxxxxxxxxxx # Usually Base64
    SAML_DOMAIN=https://example-app-test.herokuapp.com/
    SAML_AUDIENCE=https://example-app.herokuapp.com/login # If using a single Okta app for all environments, this should be set to the prod instance + /login
    
  3. Generate template files for your project:

    $ bundle exec rails g integration_pal:install
    
  4. Set active job config.active_job.queue_adapter = :sidekiq # If you are using sidekiq

  5. Configure app. Include sp_metadata.xml[.erb] in config/saml:

    <?xml version="1.0"?>
    <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="<%= ENV['SAML_AUDIENCE'] || saml2_meta_url %>">
    <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <md:AssertionConsumerService Location="<%= saml2_login_url %>" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" index="0"/>
    </md:SPSSODescriptor>
    </md:EntityDescriptor>
    

    Also include idp_metadata.xml[.erb] in config/saml:

    <?xml version="1.0" encoding="UTF-8"?>
    <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://www.okta.com/<%= ENV['OKTA_ID'] %>">
        <md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
            <md:KeyDescriptor use="signing">
                <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                    <ds:X509Data>
                        <ds:X509Certificate>
    MIIDpjCCAo6gAwIBAgIGAV2m4sObMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYDVQQGEwJVUzETMBEG
    A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
    MBIGA1UECwwLU1NPUHJvdmlkZXIxFDASBgNVBAMMC2luc3RydWN0dXJlMRwwGgYJKoZIhvcNAQkB
    Fg1pbmZvQG9rdGEuY29tMB4XDTE3MDgwMzA2NTY0NVoXDTI3MDgwMzA2NTc0NVowgZMxCzAJBgNV
    BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYD
    VQQKDARPa3RhMRQwEgYDVQQLDAtTU09Qcm92aWRlcjEUMBIGA1UEAwwLaW5zdHJ1Y3R1cmUxHDAa
    BgkqhkiG9w0BCQEWDWluZm9Ab2t0YS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    AQCai7ii3JnhQo1059yLgPllaJMB/p5imSUD35JABBFBMRo/l7RZ9T0dVFwpa2W3JnGAR86WA+ct
    SY5kdXGaFHEmPz/rSeHQM6OSmoOFaMgUN1mSCpLUzJn84TdcSAZzDoAWQdgREmby2w+PxGaBkAfM
    9Fng+bD/DxvPMqpQDPtqZn6mih1x9lDNjpxcnkhddpNpuy2CVmTbFgi14KnZtTB8wmXXURminxp8
    DkCi0fDthjrdRthJ21knX7G7BqLTS0z8mhVuNp+0cW1QCJa0SZJe77c8/JyriiYOW+txXjlqEL5N
    aGwqp2VBvaPhy/zWGQgM8z/44N8MnjZq1kjEab7DAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAA6O
    Pmdr4XF4hTKDToURQmMMezwUx/iXVJyZrYOxxnfBsG9QfqzJBWxaj4nmrhJwcG2lTVyq0gK3VrIS
    suUyUUQGvTG8xcXkWugkQO3cxBSkW9gMQHe+RZ23CIV2JyKR9hlpVLgVL3vYwJL4a3X6RNV/xwbY
    qYztCcmEzyU9AmpdyIqCEAWiEKmolCYoxOjJ98HQF7IqfzuV+j1mSE2pkoBj7fHG4sKCdW7pb2LC
    Akzty10BVG3l+uzGqiLPlaSHH71zvSM6LbEuL3yVo+Y5m7Zue2lVFOcZZCEMT6kJSgUr98XsVX2p
    3yci0gapqFoET7zTmo0SPOcZ2SVfDdllTqk=
                        </ds:X509Certificate>
                    </ds:X509Data>
                </ds:KeyInfo>
            </md:KeyDescriptor>
            <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
            <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
            <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://instructure.okta.com/app/<%= ENV['OKTA_APP'] %>/<%= ENV['OKTA_ID'] %>/sso/saml"/>
            <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://instructure.okta.com/app/<%= ENV['OKTA_APP'] %>/<%= ENV['OKTA_ID'] %>/sso/saml"/>
        </md:IDPSSODescriptor>
    </md:EntityDescriptor>
    

    Metadata file names can be overriden from within an initializer:

    IntegrationPal. = 'idp_metadata.xml'
    IntegrationPal. = 'sp_metadata.xml'
    

    To validate or begin Okta authentication within a controller, use:

    session[:saml_username] ||= ENV['USER'] if Rails.env.in?(%w(development test))
    redirect_to  unless session[:saml_username]
    

Deploying to Heroku

The SAML2 Authentication library that this tool uses requires libxmlsec1-dev. In order to ensure that it is installed on the Heroku dyno, add https://github.com/ABASystems/heroku-buildpack-apt as the first buildpack in Heroku, followed by heroku/ruby. Also include an Aptfile in the root of your project:

libxmlsec1-dev

! - Double check this if Heroku fails to build Gem native extensions for nokogiri-xmlsec-instructure during deployment.

License

The gem is available as open source under the terms of the MIT License.

Example API Request

Note how we sign the request using ApiAuth

require "uri"
require "net/https"
require "time"
require "rubygems"
require "api_auth"
require 'active_record'

JOB_URL = "http://localhost:3000/api/v1/jobs"

access_key_id = "test"
secret_access_key = "test"

uri = URI.parse(JOB_URL)
http = Net::HTTP.new(uri.host, uri.port)

request = Net::HTTP::Post.new(uri.request_uri, 'Content-Type' => 'application/json')
request.body = {
  job: {
    worker_id: 1,
    job_params: {
      start_date: "2016-05-25T19:57:16Z",
      end_date: "2017-05-25T13:57:59-06:00"
    }
  }
}.to_json

ApiAuth.sign!(request, access_key_id, secret_access_key)

response = http.request(request)
puts response.body